PageSourceSearch

https://shinhoglobal.com/js/custom/lyt-cn-about.js?nIQvuCSYww

js shinhoglobal.com collected 2026-10-03 21:10:57 UTC 1,024,925 bytes, 27,970 lines download raw bytes

1/******/ (function(modules) { // webpackBootstrap
2/******/ 	// The module cache
3/******/ 	var installedModules = {};
4/******/
5/******/ 	// The require function
6/******/ 	function __webpack_require__(moduleId) {
7/******/
8/******/ 		// Check if module is in cache
9/******/ 		if(installedModules[moduleId]) {
10/******/ 			return installedModules[moduleId].exports;
11/******/ 		}
12/******/ 		// Create a new module (and put it into the cache)
13/******/ 		var module = installedModules[moduleId] = {
14/******/ 			i: moduleId,
15/******/ 			l: false,
16/******/ 			exports: {}
17/******/ 		};
18/******/
19/******/ 		// Execute the module function
20/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
21/******/
22/******/ 		// Flag the module as loaded
23/******/ 		module.l = true;
24/******/
25/******/ 		// Return the exports of the module
26/******/ 		return module.exports;
27/******/ 	}
28/******/
29/******/
30/******/ 	// expose the modules object (__webpack_modules__)
31/******/ 	__webpack_require__.m = modules;
32/******/
33/******/ 	// expose the module cache
34/******/ 	__webpack_require__.c = installedModules;
35/******/
36/******/ 	// define getter function for harmony exports
37/******/ 	__webpack_require__.d = function(exports, name, getter) {
38/******/ 		if(!__webpack_require__.o(exports, name)) {
39/******/ 			Object.defineProperty(exports, name, {
40/******/ 				configurable: false,
41/******/ 				enumerable: true,
42/******/ 				get: getter
43/******/ 			});
44/******/ 		}
45/******/ 	};
46/******/
47/******/ 	// getDefaultExport function for compatibility with non-harmony modules
48/******/ 	__webpack_require__.n = function(module) {
49/******/ 		var getter = module && module.__esModule ?
50/******/ 			function getDefault() { return module['default']; } :
51/******/ 			function getModuleExports() { return module; };
52/******/ 		__webpack_require__.d(getter, 'a', getter);
53/******/ 		return getter;
54/******/ 	};
55/******/
56/******/ 	// Object.prototype.hasOwnProperty.call
57/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
58/******/
59/******/ 	// __webpack_public_path__
60/******/ 	__webpack_require__.p = "";
61/******/
62/******/ 	// Load entry module and return exports
63/******/ 	return __webpack_require__(__webpack_require__.s = 42);
64/******/ })
65/************************************************************************/
66/******/ ([
67/* 0 */
68/***/ (function(module, exports, __webpack_require__) {
69
70var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
71 * jQuery JavaScript Library v1.12.4
72 * http://jquery.com/
73 *
74 * Includes Sizzle.js
75 * http://sizzlejs.com/
76 *
77 * Copyright jQuery Foundation and other contributors
78 * Released under the MIT license
79 * http://jquery.org/license
80 *
81 * Date: 2016-05-20T17:17Z
82 */
83
84(function (global, factory) {
85
86	if (typeof module === "object" && typeof module.exports === "object") {
87		// For CommonJS and CommonJS-like environments where a proper `window`
88		// is present, execute the factory and get jQuery.
89		// For environments that do not have a `window` with a `document`
90		// (such as Node.js), expose a factory as module.exports.
91		// This accentuates the need for the creation of a real `window`.
92		// e.g. var jQuery = require("jquery")(window);
93		// See ticket #14549 for more info.
94		module.exports = global.document ? factory(global, true) : function (w) {
95			if (!w.document) {
96				throw new Error("jQuery requires a window with a document");
97			}
98			return factory(w);
99		};
100	} else {
101		factory(global);
102	}
103
104	// Pass this if window is not defined yet
105})(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
106
107	// Support: Firefox 18+
108	// Can't be in strict mode, several libs including ASP.NET trace
109	// the stack via arguments.caller.callee and Firefox dies if
vendor: 4,159 bytes, lines 110-294
110	// you try to trace through "use strict" call chains. (#13335)
111	//"use strict";
112	var deletedIds = [];
113
114	var document = window.document;
115
116	var slice = deletedIds.slice;
117
118	var concat = deletedIds.concat;
119
120	var push = deletedIds.push;
121
122	var indexOf = deletedIds.indexOf;
123
124	var class2type = {};
125
126	var toString = class2type.toString;
127
128	var hasOwn = class2type.hasOwnProperty;
129
130	var support = {};
131
132	var version = "1.12.4",
133
134
135	// Define a local copy of jQuery
136	jQuery = function (selector, context) {
137
138		// The jQuery object is actually just the init constructor 'enhanced'
139		// Need init if jQuery is called (just allow error to be thrown if not included)
140		return new jQuery.fn.init(selector, context);
141	},
142
143
144	// Support: Android<4.1, IE<9
145	// Make sure we trim BOM and NBSP
146	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
147
148
149	// Matches dashed string for camelizing
150	rmsPrefix = /^-ms-/,
151	    rdashAlpha = /-([\da-z])/gi,
152
153
154	// Used by jQuery.camelCase as callback to replace()
155	fcamelCase = function (all, letter) {
156		return letter.toUpperCase();
157	};
158
159	jQuery.fn = jQuery.prototype = {
160
161		// The current version of jQuery being used
162		jquery: version,
163
164		constructor: jQuery,
165
166		// Start with an empty selector
167		selector: "",
168
169		// The default length of a jQuery object is 0
170		length: 0,
171
172		toArray: function () {
173			return slice.call(this);
174		},
175
176		// Get the Nth element in the matched element set OR
177		// Get the whole matched element set as a clean array
178		get: function (num) {
179			return num != null ?
180
181			// Return just the one element from the set
182			num < 0 ? this[num + this.length] : this[num] :
183
184			// Return all the elements in a clean array
185			slice.call(this);
186		},
187
188		// Take an array of elements and push it onto the stack
189		// (returning the new matched element set)
190		pushStack: function (elems) {
191
192			// Build a new jQuery matched element set
193			var ret = jQuery.merge(this.constructor(), elems);
194
195			// Add the old object onto the stack (as a reference)
196			ret.prevObject = this;
197			ret.context = this.context;
198
199			// Return the newly-formed element set
200			return ret;
201		},
202
203		// Execute a callback for every element in the matched set.
204		each: function (callback) {
205			return jQuery.each(this, callback);
206		},
207
208		map: function (callback) {
209			return this.pushStack(jQuery.map(this, function (elem, i) {
210				return callback.call(elem, i, elem);
211			}));
212		},
213
214		slice: function () {
215			return this.pushStack(slice.apply(this, arguments));
216		},
217
218		first: function () {
219			return this.eq(0);
220		},
221
222		last: function () {
223			return this.eq(-1);
224		},
225
226		eq: function (i) {
227			var len = this.length,
228			    j = +i + (i < 0 ? len : 0);
229			return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
230		},
231
232		end: function () {
233			return this.prevObject || this.constructor();
234		},
235
236		// For internal use only.
237		// Behaves like an Array's method, not like a jQuery method.
238		push: push,
239		sort: deletedIds.sort,
240		splice: deletedIds.splice
241	};
242
243	jQuery.extend = jQuery.fn.extend = function () {
244		var src,
245		    copyIsArray,
246		    copy,
247		    name,
248		    options,
249		    clone,
250		    target = arguments[0] || {},
251		    i = 1,
252		    length = arguments.length,
253		    deep = false;
254
255		// Handle a deep copy situation
256		if (typeof target === "boolean") {
257			deep = target;
258
259			// skip the boolean and the target
260			target = arguments[i] || {};
261			i++;
262		}
263
264		// Handle case when target is a string or something (possible in deep copy)
265		if (typeof target !== "object" && !jQuery.isFunction(target)) {
266			target = {};
267		}
268
269		// extend jQuery itself if only one argument is passed
270		if (i === length) {
271			target = this;
272			i--;
273		}
274
275		for (; i < length; i++) {
276
277			// Only deal with non-null/undefined values
278			if ((options = arguments[i]) != null) {
279
280				// Extend the base object
281				for (name in options) {
282					src = target[name];
283					copy = options[name];
284
285					// Prevent never-ending loop
286					if (target === copy) {
287						continue;
288					}
289
290					// Recurse if we're merging plain objects or arrays
291					if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
292
293						if (copyIsArray) {
294							copyIsArray = false;
vendor: 8,553 bytes, lines 295-636
295							clone = src && jQuery.isArray(src) ? src : [];
296						} else {
297							clone = src && jQuery.isPlainObject(src) ? src : {};
298						}
299
300						// Never move original objects, clone them
301						target[name] = jQuery.extend(deep, clone, copy);
302
303						// Don't bring in undefined values
304					} else if (copy !== undefined) {
305						target[name] = copy;
306					}
307				}
308			}
309		}
310
311		// Return the modified object
312		return target;
313	};
314
315	jQuery.extend({
316
317		// Unique for each copy of jQuery on the page
318		expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
319
320		// Assume jQuery is ready without the ready module
321		isReady: true,
322
323		error: function (msg) {
324			throw new Error(msg);
325		},
326
327		noop: function () {},
328
329		// See test/unit/core.js for details concerning isFunction.
330		// Since version 1.3, DOM methods and functions like alert
331		// aren't supported. They return false on IE (#2968).
332		isFunction: function (obj) {
333			return jQuery.type(obj) === "function";
334		},
335
336		isArray: Array.isArray || function (obj) {
337			return jQuery.type(obj) === "array";
338		},
339
340		isWindow: function (obj) {
341			/* jshint eqeqeq: false */
342			return obj != null && obj == obj.window;
343		},
344
345		isNumeric: function (obj) {
346
347			// parseFloat NaNs numeric-cast false positives (null|true|false|"")
348			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
349			// subtraction forces infinities to NaN
350			// adding 1 corrects loss of precision from parseFloat (#15100)
351			var realStringObj = obj && obj.toString();
352			return !jQuery.isArray(obj) && realStringObj - parseFloat(realStringObj) + 1 >= 0;
353		},
354
355		isEmptyObject: function (obj) {
356			var name;
357			for (name in obj) {
358				return false;
359			}
360			return true;
361		},
362
363		isPlainObject: function (obj) {
364			var key;
365
366			// Must be an Object.
367			// Because of IE, we also have to check the presence of the constructor property.
368			// Make sure that DOM nodes and window objects don't pass through, as well
369			if (!obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow(obj)) {
370				return false;
371			}
372
373			try {
374
375				// Not own constructor property must be Object
376				if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
377					return false;
378				}
379			} catch (e) {
380
381				// IE8,9 Will throw exceptions on certain host objects #9897
382				return false;
383			}
384
385			// Support: IE<9
386			// Handle iteration over inherited properties before own properties.
387			if (!support.ownFirst) {
388				for (key in obj) {
389					return hasOwn.call(obj, key);
390				}
391			}
392
393			// Own properties are enumerated firstly, so to speed up,
394			// if last one is own, then all properties are own.
395			for (key in obj) {}
396
397			return key === undefined || hasOwn.call(obj, key);
398		},
399
400		type: function (obj) {
401			if (obj == null) {
402				return obj + "";
403			}
404			return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj;
405		},
406
407		// Workarounds based on findings by Jim Driscoll
408		// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
409		globalEval: function (data) {
410			if (data && jQuery.trim(data)) {
411
412				// We use execScript on Internet Explorer
413				// We use an anonymous function so that context is window
414				// rather than jQuery in Firefox
415				(window.execScript || function (data) {
416					window["eval"].call(window, data); // jscs:ignore requireDotNotation
417				})(data);
418			}
419		},
420
421		// Convert dashed to camelCase; used by the css and data modules
422		// Microsoft forgot to hump their vendor prefix (#9572)
423		camelCase: function (string) {
424			return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
425		},
426
427		nodeName: function (elem, name) {
428			return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
429		},
430
431		each: function (obj, callback) {
432			var length,
433			    i = 0;
434
435			if (isArrayLike(obj)) {
436				length = obj.length;
437				for (; i < length; i++) {
438					if (callback.call(obj[i], i, obj[i]) === false) {
439						break;
440					}
441				}
442			} else {
443				for (i in obj) {
444					if (callback.call(obj[i], i, obj[i]) === false) {
445						break;
446					}
447				}
448			}
449
450			return obj;
451		},
452
453		// Support: Android<4.1, IE<9
454		trim: function (text) {
455			return text == null ? "" : (text + "").replace(rtrim, "");
456		},
457
458		// results is for internal usage only
459		makeArray: function (arr, results) {
460			var ret = results || [];
461
462			if (arr != null) {
463				if (isArrayLike(Object(arr))) {
464					jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);
465				} else {
466					push.call(ret, arr);
467				}
468			}
469
470			return ret;
471		},
472
473		inArray: function (elem, arr, i) {
474			var len;
475
476			if (arr) {
477				if (indexOf) {
478					return indexOf.call(arr, elem, i);
479				}
480
481				len = arr.length;
482				i = i ? i < 0 ? Math.max(0, len + i) : i : 0;
483
484				for (; i < len; i++) {
485
486					// Skip accessing in sparse arrays
487					if (i in arr && arr[i] === elem) {
488						return i;
489					}
490				}
491			}
492
493			return -1;
494		},
495
496		merge: function (first, second) {
497			var len = +second.length,
498			    j = 0,
499			    i = first.length;
500
501			while (j < len) {
502				first[i++] = second[j++];
503			}
504
505			// Support: IE<9
506			// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
507			if (len !== len) {
508				while (second[j] !== undefined) {
509					first[i++] = second[j++];
510				}
511			}
512
513			first.length = i;
514
515			return first;
516		},
517
518		grep: function (elems, callback, invert) {
519			var callbackInverse,
520			    matches = [],
521			    i = 0,
522			    length = elems.length,
523			    callbackExpect = !invert;
524
525			// Go through the array, only saving the items
526			// that pass the validator function
527			for (; i < length; i++) {
528				callbackInverse = !callback(elems[i], i);
529				if (callbackInverse !== callbackExpect) {
530					matches.push(elems[i]);
531				}
532			}
533
534			return matches;
535		},
536
537		// arg is for internal usage only
538		map: function (elems, callback, arg) {
539			var length,
540			    value,
541			    i = 0,
542			    ret = [];
543
544			// Go through the array, translating each of the items to their new values
545			if (isArrayLike(elems)) {
546				length = elems.length;
547				for (; i < length; i++) {
548					value = callback(elems[i], i, arg);
549
550					if (value != null) {
551						ret.push(value);
552					}
553				}
554
555				// Go through every key on the object,
556			} else {
557				for (i in elems) {
558					value = callback(elems[i], i, arg);
559
560					if (value != null) {
561						ret.push(value);
562					}
563				}
564			}
565
566			// Flatten any nested arrays
567			return concat.apply([], ret);
568		},
569
570		// A global GUID counter for objects
571		guid: 1,
572
573		// Bind a function to a context, optionally partially applying any
574		// arguments.
575		proxy: function (fn, context) {
576			var args, proxy, tmp;
577
578			if (typeof context === "string") {
579				tmp = fn[context];
580				context = fn;
581				fn = tmp;
582			}
583
584			// Quick check to determine if target is callable, in the spec
585			// this throws a TypeError, but we will just return undefined.
586			if (!jQuery.isFunction(fn)) {
587				return undefined;
588			}
589
590			// Simulated bind
591			args = slice.call(arguments, 2);
592			proxy = function () {
593				return fn.apply(context || this, args.concat(slice.call(arguments)));
594			};
595
596			// Set the guid of unique handler to the same of original handler, so it can be removed
597			proxy.guid = fn.guid = fn.guid || jQuery.guid++;
598
599			return proxy;
600		},
601
602		now: function () {
603			return +new Date();
604		},
605
606		// jQuery.support is not used in Core but other projects attach their
607		// properties to it so it needs to exist.
608		support: support
609	});
610
611	// JSHint would error on this code due to the Symbol not being defined in ES5.
612	// Defining this global in .jshintrc would create a danger of using the global
613	// unguarded in another place, it seems safer to just disable JSHint for these
614	// three lines.
615	/* jshint ignore: start */
616	if (typeof Symbol === "function") {
617		jQuery.fn[Symbol.iterator] = deletedIds[Symbol.iterator];
618	}
619	/* jshint ignore: end */
620
621	// Populate the class2type map
622	jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) {
623		class2type["[object " + name + "]"] = name.toLowerCase();
624	});
625
626	function isArrayLike(obj) {
627
628		// Support: iOS 8.2 (not reproducible in simulator)
629		// `in` check used to prevent JIT error (gh-2145)
630		// hasOwn isn't used here due to false negatives
631		// regarding Nodelist length in IE
632		var length = !!obj && "length" in obj && obj.length,
633		    type = jQuery.type(obj);
634
635		if (type === "function" || jQuery.isWindow(obj)) {
636			return false;
vendor: 4,770 bytes, lines 637-782
637		}
638
639		return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
640	}
641	var Sizzle =
642	/*!
643  * Sizzle CSS Selector Engine v2.2.1
644  * http://sizzlejs.com/
645  *
646  * Copyright jQuery Foundation and other contributors
647  * Released under the MIT license
648  * http://jquery.org/license
649  *
650  * Date: 2015-10-17
651  */
652	function (window) {
653
654		var i,
655		    support,
656		    Expr,
657		    getText,
658		    isXML,
659		    tokenize,
660		    compile,
661		    select,
662		    outermostContext,
663		    sortInput,
664		    hasDuplicate,
665
666
667		// Local document vars
668		setDocument,
669		    document,
670		    docElem,
671		    documentIsHTML,
672		    rbuggyQSA,
673		    rbuggyMatches,
674		    matches,
675		    contains,
676
677
678		// Instance-specific data
679		expando = "sizzle" + 1 * new Date(),
680		    preferredDoc = window.document,
681		    dirruns = 0,
682		    done = 0,
683		    classCache = createCache(),
684		    tokenCache = createCache(),
685		    compilerCache = createCache(),
686		    sortOrder = function (a, b) {
687			if (a === b) {
688				hasDuplicate = true;
689			}
690			return 0;
691		},
692
693
694		// General-purpose constants
695		MAX_NEGATIVE = 1 << 31,
696
697
698		// Instance methods
699		hasOwn = {}.hasOwnProperty,
700		    arr = [],
701		    pop = arr.pop,
702		    push_native = arr.push,
703		    push = arr.push,
704		    slice = arr.slice,
705
706		// Use a stripped-down indexOf as it's faster than native
707		// http://jsperf.com/thor-indexof-vs-for/5
708		indexOf = function (list, elem) {
709			var i = 0,
710			    len = list.length;
711			for (; i < len; i++) {
712				if (list[i] === elem) {
713					return i;
714				}
715			}
716			return -1;
717		},
718		    booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
719
720
721		// Regular expressions
722
723		// http://www.w3.org/TR/css3-selectors/#whitespace
724		whitespace = "[\\x20\\t\\r\\n\\f]",
725
726
727		// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
728		identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
729
730
731		// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
732		attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
733		// Operator (capture 2)
734		"*([*^$|!~]?=)" + whitespace +
735		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
736		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]",
737		    pseudos = ":(" + identifier + ")(?:\\((" +
738		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
739		// 1. quoted (capture 3; capture 4 or capture 5)
740		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
741		// 2. simple (capture 6)
742		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
743		// 3. anything else (capture 2)
744		".*" + ")\\)|)",
745
746
747		// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
748		rwhitespace = new RegExp(whitespace + "+", "g"),
749		    rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
750		    rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
751		    rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
752		    rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"),
753		    rpseudo = new RegExp(pseudos),
754		    ridentifier = new RegExp("^" + identifier + "$"),
755		    matchExpr = {
756			"ID": new RegExp("^#(" + identifier + ")"),
757			"CLASS": new RegExp("^\\.(" + identifier + ")"),
758			"TAG": new RegExp("^(" + identifier + "|[*])"),
759			"ATTR": new RegExp("^" + attributes),
760			"PSEUDO": new RegExp("^" + pseudos),
761			"CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
762			"bool": new RegExp("^(?:" + booleans + ")$", "i"),
763			// For use in libraries implementing .is()
764			// We use this for POS matching in `select`
765			"needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
766		},
767		    rinputs = /^(?:input|select|textarea|button)$/i,
768		    rheader = /^h\d$/i,
769		    rnative = /^[^{]+\{\s*\[native \w/,
770
771
772		// Easily-parseable/retrievable ID or TAG or CLASS selectors
773		rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
774		    rsibling = /[+~]/,
775		    rescape = /'|\\/g,
776
777
778		// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
779		runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
780		    funescape = function (_, escaped, escapedWhitespace) {
781			var high = "0x" + escaped - 0x10000;
782			// NaN means non-codepoint
783			// Support: Firefox<24
784			// Workaround erroneous numeric interpretation of +"0x"
785			return high !== high || escapedWhitespace ? escaped : high < 0 ?
786			// BMP codepoint
787			String.fromCharCode(high + 0x10000) :
788			// Supplemental Plane codepoint (surrogate pair)
789			String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
790		},
791
792
793		// Used for iframes
794		// See setDocument()
795		// Removing the function wrapper causes a "Permission Denied"
796		// error in IE
797		unloadHandler = function () {
798			setDocument();
799		};
800
801		// Optimize for push.apply( _, NodeList )
802		try {
803			push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);
804			// Support: Android<4.0
805			// Detect silently failing push.apply
806			arr[preferredDoc.childNodes.length].nodeType;
807		} catch (e) {
808			push = { apply: arr.length ?
809
810				// Leverage slice if possible
811				function (target, els) {
812					push_native.apply(target, slice.call(els));
813				} :
814
815				// Support: IE<9
816				// Otherwise append directly
817				function (target, els) {
818					var j = target.length,
819					    i = 0;
820					// Can't trust NodeList.length
821					while (target[j++] = els[i++]) {}
822					target.length = j - 1;
823				}
824			};
825		}
826
827		function Sizzle(selector, context, results, seed) {
828			var m,
829			    i,
830			    elem,
831			    nid,
832			    nidselect,
833			    match,
834			    groups,
835			    newSelector,
836			    newContext = context && context.ownerDocument,
837
838
839			// nodeType defaults to 9, since context defaults to document
840			nodeType = context ? context.nodeType : 9;
841
842			results = results || [];
843
844			// Return early from calls with invalid selector or context
845			if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
846
847				return results;
848			}
849
850			// Try to shortcut find operations (as opposed to filters) in HTML documents
851			if (!seed) {
852
853				if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
854					setDocument(context);
855				}
856				context = context || document;
857
858				if (documentIsHTML) {
859
860					// If the selector is sufficiently simple, try using a "get*By*" DOM method
861					// (excepting DocumentFragment context, where the methods don't exist)
862					if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
863
864						// ID selector
865						if (m = match[1]) {
866
867							// Document context
868							if (nodeType === 9) {
869								if (elem = context.getElementById(m)) {
870
871									// Support: IE, Opera, Webkit
872									// TODO: identify versions
873									// getElementById can match elements by name instead of ID
874									if (elem.id === m) {
875										results.push(elem);
876										return results;
877									}
878								} else {
879									return results;
880								}
881
882								// Element context
883							} else {
884
885								// Support: IE, Opera, Webkit
886								// TODO: identify versions
887								// getElementById can match elements by name instead of ID
888								if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) {
889
890									results.push(elem);
891									return results;
892								}
893							}
894
895							// Type selector
896						} else if (match[2]) {
897							push.apply(results, context.getElementsByTagName(selector));
898							return results;
899
900							// Class selector
901						} else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {
902
903							push.apply(results, context.getElementsByClassName(m));
904							return results;
905						}
906					}
907
908					// Take advantage of querySelectorAll
909					if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
910
911						if (nodeType !== 1) {
912							newContext = context;
913							newSelector = selector;
914
915							// qSA looks outside Element context, which is not what we want
916							// Thanks to Andrew Dupont for this workaround technique
917							// Support: IE <=8
918							// Exclude object elements
919						} else if (context.nodeName.toLowerCase() !== "object") {
920
921							// Capture the context ID, setting it first if necessary
922							if (nid = context.getAttribute("id")) {
923								nid = nid.replace(rescape, "\\$&");
924							} else {
925								context.setAttribute("id", nid = expando);
926							}
927
928							// Prefix every selector in the list
929							groups = tokenize(selector);
930							i = groups.length;
931							nidselect = ridentifier.test(nid) ? "#" + nid : "[id='" + nid + "']";
932							while (i--) {
933								groups[i] = nidselect + " " + toSelector(groups[i]);
934							}
935							newSelector = groups.join(",");
936
937							// Expand context for sibling selectors
vendor: 18,442 bytes, lines 938-1532
938							newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
939						}
940
941						if (newSelector) {
942							try {
943								push.apply(results, newContext.querySelectorAll(newSelector));
944								return results;
945							} catch (qsaError) {} finally {
946								if (nid === expando) {
947									context.removeAttribute("id");
948								}
949							}
950						}
951					}
952				}
953			}
954
955			// All others
956			return select(selector.replace(rtrim, "$1"), context, results, seed);
957		}
958
959		/**
960   * Create key-value caches of limited size
961   * @returns {function(string, object)} Returns the Object data after storing it on itself with
962   *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
963   *	deleting the oldest entry
964   */
965		function createCache() {
966			var keys = [];
967
968			function cache(key, value) {
969				// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
970				if (keys.push(key + " ") > Expr.cacheLength) {
971					// Only keep the most recent entries
972					delete cache[keys.shift()];
973				}
974				return cache[key + " "] = value;
975			}
976			return cache;
977		}
978
979		/**
980   * Mark a function for special use by Sizzle
981   * @param {Function} fn The function to mark
982   */
983		function markFunction(fn) {
984			fn[expando] = true;
985			return fn;
986		}
987
988		/**
989   * Support testing using an element
990   * @param {Function} fn Passed the created div and expects a boolean result
991   */
992		function assert(fn) {
993			var div = document.createElement("div");
994
995			try {
996				return !!fn(div);
997			} catch (e) {
998				return false;
999			} finally {
1000				// Remove from its parent by default
1001				if (div.parentNode) {
1002					div.parentNode.removeChild(div);
1003				}
1004				// release memory in IE
1005				div = null;
1006			}
1007		}
1008
1009		/**
1010   * Adds the same handler for all of the specified attrs
1011   * @param {String} attrs Pipe-separated list of attributes
1012   * @param {Function} handler The method that will be applied
1013   */
1014		function addHandle(attrs, handler) {
1015			var arr = attrs.split("|"),
1016			    i = arr.length;
1017
1018			while (i--) {
1019				Expr.attrHandle[arr[i]] = handler;
1020			}
1021		}
1022
1023		/**
1024   * Checks document order of two siblings
1025   * @param {Element} a
1026   * @param {Element} b
1027   * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
1028   */
1029		function siblingCheck(a, b) {
1030			var cur = b && a,
1031			    diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
1032
1033			// Use IE sourceIndex if available on both nodes
1034			if (diff) {
1035				return diff;
1036			}
1037
1038			// Check if b follows a
1039			if (cur) {
1040				while (cur = cur.nextSibling) {
1041					if (cur === b) {
1042						return -1;
1043					}
1044				}
1045			}
1046
1047			return a ? 1 : -1;
1048		}
1049
1050		/**
1051   * Returns a function to use in pseudos for input types
1052   * @param {String} type
1053   */
1054		function createInputPseudo(type) {
1055			return function (elem) {
1056				var name = elem.nodeName.toLowerCase();
1057				return name === "input" && elem.type === type;
1058			};
1059		}
1060
1061		/**
1062   * Returns a function to use in pseudos for buttons
1063   * @param {String} type
1064   */
1065		function createButtonPseudo(type) {
1066			return function (elem) {
1067				var name = elem.nodeName.toLowerCase();
1068				return (name === "input" || name === "button") && elem.type === type;
1069			};
1070		}
1071
1072		/**
1073   * Returns a function to use in pseudos for positionals
1074   * @param {Function} fn
1075   */
1076		function createPositionalPseudo(fn) {
1077			return markFunction(function (argument) {
1078				argument = +argument;
1079				return markFunction(function (seed, matches) {
1080					var j,
1081					    matchIndexes = fn([], seed.length, argument),
1082					    i = matchIndexes.length;
1083
1084					// Match elements found at the specified indexes
1085					while (i--) {
1086						if (seed[j = matchIndexes[i]]) {
1087							seed[j] = !(matches[j] = seed[j]);
1088						}
1089					}
1090				});
1091			});
1092		}
1093
1094		/**
1095   * Checks a node for validity as a Sizzle context
1096   * @param {Element|Object=} context
1097   * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1098   */
1099		function testContext(context) {
1100			return context && typeof context.getElementsByTagName !== "undefined" && context;
1101		}
1102
1103		// Expose support vars for convenience
1104		support = Sizzle.support = {};
1105
1106		/**
1107   * Detects XML nodes
1108   * @param {Element|Object} elem An element or a document
1109   * @returns {Boolean} True iff elem is a non-HTML XML node
1110   */
1111		isXML = Sizzle.isXML = function (elem) {
1112			// documentElement is verified for cases where it doesn't yet exist
1113			// (such as loading iframes in IE - #4833)
1114			var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1115			return documentElement ? documentElement.nodeName !== "HTML" : false;
1116		};
1117
1118		/**
1119   * Sets document-related variables once based on the current document
1120   * @param {Element|Object} [doc] An element or document object to use to set the document
1121   * @returns {Object} Returns the current document
1122   */
1123		setDocument = Sizzle.setDocument = function (node) {
1124			var hasCompare,
1125			    parent,
1126			    doc = node ? node.ownerDocument || node : preferredDoc;
1127
1128			// Return early if doc is invalid or already selected
1129			if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
1130				return document;
1131			}
1132
1133			// Update global variables
1134			document = doc;
1135			docElem = document.documentElement;
1136			documentIsHTML = !isXML(document);
1137
1138			// Support: IE 9-11, Edge
1139			// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1140			if ((parent = document.defaultView) && parent.top !== parent) {
1141				// Support: IE 11
1142				if (parent.addEventListener) {
1143					parent.addEventListener("unload", unloadHandler, false);
1144
1145					// Support: IE 9 - 10 only
1146				} else if (parent.attachEvent) {
1147					parent.attachEvent("onunload", unloadHandler);
1148				}
1149			}
1150
1151			/* Attributes
1152   ---------------------------------------------------------------------- */
1153
1154			// Support: IE<8
1155			// Verify that getAttribute really returns attributes and not properties
1156			// (excepting IE8 booleans)
1157			support.attributes = assert(function (div) {
1158				div.className = "i";
1159				return !div.getAttribute("className");
1160			});
1161
1162			/* getElement(s)By*
1163   ---------------------------------------------------------------------- */
1164
1165			// Check if getElementsByTagName("*") returns only elements
1166			support.getElementsByTagName = assert(function (div) {
1167				div.appendChild(document.createComment(""));
1168				return !div.getElementsByTagName("*").length;
1169			});
1170
1171			// Support: IE<9
1172			support.getElementsByClassName = rnative.test(document.getElementsByClassName);
1173
1174			// Support: IE<10
1175			// Check if getElementById returns elements by name
1176			// The broken getElementById methods don't pick up programatically-set names,
1177			// so use a roundabout getElementsByName test
1178			support.getById = assert(function (div) {
1179				docElem.appendChild(div).id = expando;
1180				return !document.getElementsByName || !document.getElementsByName(expando).length;
1181			});
1182
1183			// ID find and filter
1184			if (support.getById) {
1185				Expr.find["ID"] = function (id, context) {
1186					if (typeof context.getElementById !== "undefined" && documentIsHTML) {
1187						var m = context.getElementById(id);
1188						return m ? [m] : [];
1189					}
1190				};
1191				Expr.filter["ID"] = function (id) {
1192					var attrId = id.replace(runescape, funescape);
1193					return function (elem) {
1194						return elem.getAttribute("id") === attrId;
1195					};
1196				};
1197			} else {
1198				// Support: IE6/7
1199				// getElementById is not reliable as a find shortcut
1200				delete Expr.find["ID"];
1201
1202				Expr.filter["ID"] = function (id) {
1203					var attrId = id.replace(runescape, funescape);
1204					return function (elem) {
1205						var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
1206						return node && node.value === attrId;
1207					};
1208				};
1209			}
1210
1211			// Tag
1212			Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) {
1213				if (typeof context.getElementsByTagName !== "undefined") {
1214					return context.getElementsByTagName(tag);
1215
1216					// DocumentFragment nodes don't have gEBTN
1217				} else if (support.qsa) {
1218					return context.querySelectorAll(tag);
1219				}
1220			} : function (tag, context) {
1221				var elem,
1222				    tmp = [],
1223				    i = 0,
1224
1225				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1226				results = context.getElementsByTagName(tag);
1227
1228				// Filter out possible comments
1229				if (tag === "*") {
1230					while (elem = results[i++]) {
1231						if (elem.nodeType === 1) {
1232							tmp.push(elem);
1233						}
1234					}
1235
1236					return tmp;
1237				}
1238				return results;
1239			};
1240
1241			// Class
1242			Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {
1243				if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
1244					return context.getElementsByClassName(className);
1245				}
1246			};
1247
1248			/* QSA/matchesSelector
1249   ---------------------------------------------------------------------- */
1250
1251			// QSA and matchesSelector support
1252
1253			// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1254			rbuggyMatches = [];
1255
1256			// qSa(:focus) reports false when true (Chrome 21)
1257			// We allow this because of a bug in IE8/9 that throws an error
1258			// whenever `document.activeElement` is accessed on an iframe
1259			// So, we allow :focus to pass through QSA all the time to avoid the IE error
1260			// See http://bugs.jquery.com/ticket/13378
1261			rbuggyQSA = [];
1262
1263			if (support.qsa = rnative.test(document.querySelectorAll)) {
1264				// Build QSA regex
1265				// Regex strategy adopted from Diego Perini
1266				assert(function (div) {
1267					// Select is set to empty string on purpose
1268					// This is to test IE's treatment of not explicitly
1269					// setting a boolean content attribute,
1270					// since its presence should be enough
1271					// http://bugs.jquery.com/ticket/12359
1272					docElem.appendChild(div).innerHTML = "<a id='" + expando + "'></a>" + "<select id='" + expando + "-\r\\' msallowcapture=''>" + "<option selected=''></option></select>";
1273
1274					// Support: IE8, Opera 11-12.16
1275					// Nothing should be selected when empty strings follow ^= or $= or *=
1276					// The test attribute must be unknown in Opera but "safe" for WinRT
1277					// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1278					if (div.querySelectorAll("[msallowcapture^='']").length) {
1279						rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
1280					}
1281
1282					// Support: IE8
1283					// Boolean attributes and "value" are not treated correctly
1284					if (!div.querySelectorAll("[selected]").length) {
1285						rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
1286					}
1287
1288					// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1289					if (!div.querySelectorAll("[id~=" + expando + "-]").length) {
1290						rbuggyQSA.push("~=");
1291					}
1292
1293					// Webkit/Opera - :checked should return selected option elements
1294					// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1295					// IE8 throws error here and will not see later tests
1296					if (!div.querySelectorAll(":checked").length) {
1297						rbuggyQSA.push(":checked");
1298					}
1299
1300					// Support: Safari 8+, iOS 8+
1301					// https://bugs.webkit.org/show_bug.cgi?id=136851
1302					// In-page `selector#id sibing-combinator selector` fails
1303					if (!div.querySelectorAll("a#" + expando + "+*").length) {
1304						rbuggyQSA.push(".#.+[+~]");
1305					}
1306				});
1307
1308				assert(function (div) {
1309					// Support: Windows 8 Native Apps
1310					// The type and name attributes are restricted during .innerHTML assignment
1311					var input = document.createElement("input");
1312					input.setAttribute("type", "hidden");
1313					div.appendChild(input).setAttribute("name", "D");
1314
1315					// Support: IE8
1316					// Enforce case-sensitivity of name attribute
1317					if (div.querySelectorAll("[name=d]").length) {
1318						rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");
1319					}
1320
1321					// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1322					// IE8 throws error here and will not see later tests
1323					if (!div.querySelectorAll(":enabled").length) {
1324						rbuggyQSA.push(":enabled", ":disabled");
1325					}
1326
1327					// Opera 10-11 does not throw on post-comma invalid pseudos
1328					div.querySelectorAll("*,:x");
1329					rbuggyQSA.push(",.*:");
1330				});
1331			}
1332
1333			if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {
1334
1335				assert(function (div) {
1336					// Check to see if it's possible to do matchesSelector
1337					// on a disconnected node (IE 9)
1338					support.disconnectedMatch = matches.call(div, "div");
1339
1340					// This should fail with an exception
1341					// Gecko does not error, returns false instead
1342					matches.call(div, "[s!='']:x");
1343					rbuggyMatches.push("!=", pseudos);
1344				});
1345			}
1346
1347			rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
1348			rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
1349
1350			/* Contains
1351   ---------------------------------------------------------------------- */
1352			hasCompare = rnative.test(docElem.compareDocumentPosition);
1353
1354			// Element contains another
1355			// Purposefully self-exclusive
1356			// As in, an element does not contain itself
1357			contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
1358				var adown = a.nodeType === 9 ? a.documentElement : a,
1359				    bup = b && b.parentNode;
1360				return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
1361			} : function (a, b) {
1362				if (b) {
1363					while (b = b.parentNode) {
1364						if (b === a) {
1365							return true;
1366						}
1367					}
1368				}
1369				return false;
1370			};
1371
1372			/* Sorting
1373   ---------------------------------------------------------------------- */
1374
1375			// Document order sorting
1376			sortOrder = hasCompare ? function (a, b) {
1377
1378				// Flag for duplicate removal
1379				if (a === b) {
1380					hasDuplicate = true;
1381					return 0;
1382				}
1383
1384				// Sort on method existence if only one input has compareDocumentPosition
1385				var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1386				if (compare) {
1387					return compare;
1388				}
1389
1390				// Calculate position if both inputs belong to the same document
1391				compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) :
1392
1393				// Otherwise we know they are disconnected
1394				1;
1395
1396				// Disconnected nodes
1397				if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
1398
1399					// Choose the first element that is related to our preferred document
1400					if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {
1401						return -1;
1402					}
1403					if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {
1404						return 1;
1405					}
1406
1407					// Maintain original order
1408					return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;
1409				}
1410
1411				return compare & 4 ? -1 : 1;
1412			} : function (a, b) {
1413				// Exit early if the nodes are identical
1414				if (a === b) {
1415					hasDuplicate = true;
1416					return 0;
1417				}
1418
1419				var cur,
1420				    i = 0,
1421				    aup = a.parentNode,
1422				    bup = b.parentNode,
1423				    ap = [a],
1424				    bp = [b];
1425
1426				// Parentless nodes are either documents or disconnected
1427				if (!aup || !bup) {
1428					return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;
1429
1430					// If the nodes are siblings, we can do a quick check
1431				} else if (aup === bup) {
1432					return siblingCheck(a, b);
1433				}
1434
1435				// Otherwise we need full lists of their ancestors for comparison
1436				cur = a;
1437				while (cur = cur.parentNode) {
1438					ap.unshift(cur);
1439				}
1440				cur = b;
1441				while (cur = cur.parentNode) {
1442					bp.unshift(cur);
1443				}
1444
1445				// Walk down the tree looking for a discrepancy
1446				while (ap[i] === bp[i]) {
1447					i++;
1448				}
1449
1450				return i ?
1451				// Do a sibling check if the nodes have a common ancestor
1452				siblingCheck(ap[i], bp[i]) :
1453
1454				// Otherwise nodes in our document sort first
1455				ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
1456			};
1457
1458			return document;
1459		};
1460
1461		Sizzle.matches = function (expr, elements) {
1462			return Sizzle(expr, null, null, elements);
1463		};
1464
1465		Sizzle.matchesSelector = function (elem, expr) {
1466			// Set document vars if needed
1467			if ((elem.ownerDocument || elem) !== document) {
1468				setDocument(elem);
1469			}
1470
1471			// Make sure that attribute selectors are quoted
1472			expr = expr.replace(rattributeQuotes, "='$1']");
1473
1474			if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
1475
1476				try {
1477					var ret = matches.call(elem, expr);
1478
1479					// IE 9's matchesSelector returns false on disconnected nodes
1480					if (ret || support.disconnectedMatch ||
1481					// As well, disconnected nodes are said to be in a document
1482					// fragment in IE 9
1483					elem.document && elem.document.nodeType !== 11) {
1484						return ret;
1485					}
1486				} catch (e) {}
1487			}
1488
1489			return Sizzle(expr, document, null, [elem]).length > 0;
1490		};
1491
1492		Sizzle.contains = function (context, elem) {
1493			// Set document vars if needed
1494			if ((context.ownerDocument || context) !== document) {
1495				setDocument(context);
1496			}
1497			return contains(context, elem);
1498		};
1499
1500		Sizzle.attr = function (elem, name) {
1501			// Set document vars if needed
1502			if ((elem.ownerDocument || elem) !== document) {
1503				setDocument(elem);
1504			}
1505
1506			var fn = Expr.attrHandle[name.toLowerCase()],
1507
1508			// Don't get fooled by Object.prototype properties (jQuery #13807)
1509			val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
1510
1511			return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
1512		};
1513
1514		Sizzle.error = function (msg) {
1515			throw new Error("Syntax error, unrecognized expression: " + msg);
1516		};
1517
1518		/**
1519   * Document sorting and removing duplicates
1520   * @param {ArrayLike} results
1521   */
1522		Sizzle.uniqueSort = function (results) {
1523			var elem,
1524			    duplicates = [],
1525			    j = 0,
1526			    i = 0;
1527
1528			// Unless we *know* we can detect duplicates, assume their presence
1529			hasDuplicate = !support.detectDuplicates;
1530			sortInput = !support.sortStable && results.slice(0);
1531			results.sort(sortOrder);
1532
vendor: 12,805 bytes, lines 1533-1939
1533			if (hasDuplicate) {
1534				while (elem = results[i++]) {
1535					if (elem === results[i]) {
1536						j = duplicates.push(i);
1537					}
1538				}
1539				while (j--) {
1540					results.splice(duplicates[j], 1);
1541				}
1542			}
1543
1544			// Clear input after sorting to release objects
1545			// See https://github.com/jquery/sizzle/pull/225
1546			sortInput = null;
1547
1548			return results;
1549		};
1550
1551		/**
1552   * Utility function for retrieving the text value of an array of DOM nodes
1553   * @param {Array|Element} elem
1554   */
1555		getText = Sizzle.getText = function (elem) {
1556			var node,
1557			    ret = "",
1558			    i = 0,
1559			    nodeType = elem.nodeType;
1560
1561			if (!nodeType) {
1562				// If no nodeType, this is expected to be an array
1563				while (node = elem[i++]) {
1564					// Do not traverse comment nodes
1565					ret += getText(node);
1566				}
1567			} else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
1568				// Use textContent for elements
1569				// innerText usage removed for consistency of new lines (jQuery #11153)
1570				if (typeof elem.textContent === "string") {
1571					return elem.textContent;
1572				} else {
1573					// Traverse its children
1574					for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
1575						ret += getText(elem);
1576					}
1577				}
1578			} else if (nodeType === 3 || nodeType === 4) {
1579				return elem.nodeValue;
1580			}
1581			// Do not include comment or processing instruction nodes
1582
1583			return ret;
1584		};
1585
1586		Expr = Sizzle.selectors = {
1587
1588			// Can be adjusted by the user
1589			cacheLength: 50,
1590
1591			createPseudo: markFunction,
1592
1593			match: matchExpr,
1594
1595			attrHandle: {},
1596
1597			find: {},
1598
1599			relative: {
1600				">": { dir: "parentNode", first: true },
1601				" ": { dir: "parentNode" },
1602				"+": { dir: "previousSibling", first: true },
1603				"~": { dir: "previousSibling" }
1604			},
1605
1606			preFilter: {
1607				"ATTR": function (match) {
1608					match[1] = match[1].replace(runescape, funescape);
1609
1610					// Move the given value to match[3] whether quoted or unquoted
1611					match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);
1612
1613					if (match[2] === "~=") {
1614						match[3] = " " + match[3] + " ";
1615					}
1616
1617					return match.slice(0, 4);
1618				},
1619
1620				"CHILD": function (match) {
1621					/* matches from matchExpr["CHILD"]
1622     	1 type (only|nth|...)
1623     	2 what (child|of-type)
1624     	3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1625     	4 xn-component of xn+y argument ([+-]?\d*n|)
1626     	5 sign of xn-component
1627     	6 x of xn-component
1628     	7 sign of y-component
1629     	8 y of y-component
1630     */
1631					match[1] = match[1].toLowerCase();
1632
1633					if (match[1].slice(0, 3) === "nth") {
1634						// nth-* requires argument
1635						if (!match[3]) {
1636							Sizzle.error(match[0]);
1637						}
1638
1639						// numeric x and y parameters for Expr.filter.CHILD
1640						// remember that false/true cast respectively to 0/1
1641						match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
1642						match[5] = +(match[7] + match[8] || match[3] === "odd");
1643
1644						// other types prohibit arguments
1645					} else if (match[3]) {
1646						Sizzle.error(match[0]);
1647					}
1648
1649					return match;
1650				},
1651
1652				"PSEUDO": function (match) {
1653					var excess,
1654					    unquoted = !match[6] && match[2];
1655
1656					if (matchExpr["CHILD"].test(match[0])) {
1657						return null;
1658					}
1659
1660					// Accept quoted arguments as-is
1661					if (match[3]) {
1662						match[2] = match[4] || match[5] || "";
1663
1664						// Strip excess characters from unquoted arguments
1665					} else if (unquoted && rpseudo.test(unquoted) && (
1666					// Get excess from tokenize (recursively)
1667					excess = tokenize(unquoted, true)) && (
1668					// advance to the next closing parenthesis
1669					excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
1670
1671						// excess is a negative index
1672						match[0] = match[0].slice(0, excess);
1673						match[2] = unquoted.slice(0, excess);
1674					}
1675
1676					// Return only captures needed by the pseudo filter method (type and argument)
1677					return match.slice(0, 3);
1678				}
1679			},
1680
1681			filter: {
1682
1683				"TAG": function (nodeNameSelector) {
1684					var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
1685					return nodeNameSelector === "*" ? function () {
1686						return true;
1687					} : function (elem) {
1688						return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1689					};
1690				},
1691
1692				"CLASS": function (className) {
1693					var pattern = classCache[className + " "];
1694
1695					return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) {
1696						return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
1697					});
1698				},
1699
1700				"ATTR": function (name, operator, check) {
1701					return function (elem) {
1702						var result = Sizzle.attr(elem, name);
1703
1704						if (result == null) {
1705							return operator === "!=";
1706						}
1707						if (!operator) {
1708							return true;
1709						}
1710
1711						result += "";
1712
1713						return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false;
1714					};
1715				},
1716
1717				"CHILD": function (type, what, argument, first, last) {
1718					var simple = type.slice(0, 3) !== "nth",
1719					    forward = type.slice(-4) !== "last",
1720					    ofType = what === "of-type";
1721
1722					return first === 1 && last === 0 ?
1723
1724					// Shortcut for :nth-*(n)
1725					function (elem) {
1726						return !!elem.parentNode;
1727					} : function (elem, context, xml) {
1728						var cache,
1729						    uniqueCache,
1730						    outerCache,
1731						    node,
1732						    nodeIndex,
1733						    start,
1734						    dir = simple !== forward ? "nextSibling" : "previousSibling",
1735						    parent = elem.parentNode,
1736						    name = ofType && elem.nodeName.toLowerCase(),
1737						    useCache = !xml && !ofType,
1738						    diff = false;
1739
1740						if (parent) {
1741
1742							// :(first|last|only)-(child|of-type)
1743							if (simple) {
1744								while (dir) {
1745									node = elem;
1746									while (node = node[dir]) {
1747										if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
1748
1749											return false;
1750										}
1751									}
1752									// Reverse direction for :only-* (if we haven't yet done so)
1753									start = dir = type === "only" && !start && "nextSibling";
1754								}
1755								return true;
1756							}
1757
1758							start = [forward ? parent.firstChild : parent.lastChild];
1759
1760							// non-xml :nth-child(...) stores cache data on `parent`
1761							if (forward && useCache) {
1762
1763								// Seek `elem` from a previously-cached index
1764
1765								// ...in a gzip-friendly way
1766								node = parent;
1767								outerCache = node[expando] || (node[expando] = {});
1768
1769								// Support: IE <9 only
1770								// Defend against cloned attroperties (jQuery gh-1709)
1771								uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
1772
1773								cache = uniqueCache[type] || [];
1774								nodeIndex = cache[0] === dirruns && cache[1];
1775								diff = nodeIndex && cache[2];
1776								node = nodeIndex && parent.childNodes[nodeIndex];
1777
1778								while (node = ++nodeIndex && node && node[dir] || (
1779
1780								// Fallback to seeking `elem` from the start
1781								diff = nodeIndex = 0) || start.pop()) {
1782
1783									// When found, cache indexes on `parent` and break
1784									if (node.nodeType === 1 && ++diff && node === elem) {
1785										uniqueCache[type] = [dirruns, nodeIndex, diff];
1786										break;
1787									}
1788								}
1789							} else {
1790								// Use previously-cached element index if available
1791								if (useCache) {
1792									// ...in a gzip-friendly way
1793									node = elem;
1794									outerCache = node[expando] || (node[expando] = {});
1795
1796									// Support: IE <9 only
1797									// Defend against cloned attroperties (jQuery gh-1709)
1798									uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
1799
1800									cache = uniqueCache[type] || [];
1801									nodeIndex = cache[0] === dirruns && cache[1];
1802									diff = nodeIndex;
1803								}
1804
1805								// xml :nth-child(...)
1806								// or :nth-last-child(...) or :nth(-last)?-of-type(...)
1807								if (diff === false) {
1808									// Use the same loop as above to seek `elem` from the start
1809									while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
1810
1811										if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
1812
1813											// Cache the index of each encountered element
1814											if (useCache) {
1815												outerCache = node[expando] || (node[expando] = {});
1816
1817												// Support: IE <9 only
1818												// Defend against cloned attroperties (jQuery gh-1709)
1819												uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});
1820
1821												uniqueCache[type] = [dirruns, diff];
1822											}
1823
1824											if (node === elem) {
1825												break;
1826											}
1827										}
1828									}
1829								}
1830							}
1831
1832							// Incorporate the offset, then check against cycle size
1833							diff -= last;
1834							return diff === first || diff % first === 0 && diff / first >= 0;
1835						}
1836					};
1837				},
1838
1839				"PSEUDO": function (pseudo, argument) {
1840					// pseudo-class names are case-insensitive
1841					// http://www.w3.org/TR/selectors/#pseudo-classes
1842					// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1843					// Remember that setFilters inherits from pseudos
1844					var args,
1845					    fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo);
1846
1847					// The user may use createPseudo to indicate that
1848					// arguments are needed to create the filter function
1849					// just as Sizzle does
1850					if (fn[expando]) {
1851						return fn(argument);
1852					}
1853
1854					// But maintain support for old signatures
1855					if (fn.length > 1) {
1856						args = [pseudo, pseudo, "", argument];
1857						return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
1858							var idx,
1859							    matched = fn(seed, argument),
1860							    i = matched.length;
1861							while (i--) {
1862								idx = indexOf(seed, matched[i]);
1863								seed[idx] = !(matches[idx] = matched[i]);
1864							}
1865						}) : function (elem) {
1866							return fn(elem, 0, args);
1867						};
1868					}
1869
1870					return fn;
1871				}
1872			},
1873
1874			pseudos: {
1875				// Potentially complex pseudos
1876				"not": markFunction(function (selector) {
1877					// Trim the selector passed to compile
1878					// to avoid treating leading and trailing
1879					// spaces as combinators
1880					var input = [],
1881					    results = [],
1882					    matcher = compile(selector.replace(rtrim, "$1"));
1883
1884					return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
1885						var elem,
1886						    unmatched = matcher(seed, null, xml, []),
1887						    i = seed.length;
1888
1889						// Match elements unmatched by `matcher`
1890						while (i--) {
1891							if (elem = unmatched[i]) {
1892								seed[i] = !(matches[i] = elem);
1893							}
1894						}
1895					}) : function (elem, context, xml) {
1896						input[0] = elem;
1897						matcher(input, null, xml, results);
1898						// Don't keep the element (issue #299)
1899						input[0] = null;
1900						return !results.pop();
1901					};
1902				}),
1903
1904				"has": markFunction(function (selector) {
1905					return function (elem) {
1906						return Sizzle(selector, elem).length > 0;
1907					};
1908				}),
1909
1910				"contains": markFunction(function (text) {
1911					text = text.replace(runescape, funescape);
1912					return function (elem) {
1913						return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
1914					};
1915				}),
1916
1917				// "Whether an element is represented by a :lang() selector
1918				// is based solely on the element's language value
1919				// being equal to the identifier C,
1920				// or beginning with the identifier C immediately followed by "-".
1921				// The matching of C against the element's language value is performed case-insensitively.
1922				// The identifier C does not have to be a valid language name."
1923				// http://www.w3.org/TR/selectors/#lang-pseudo
1924				"lang": markFunction(function (lang) {
1925					// lang value must be a valid identifier
1926					if (!ridentifier.test(lang || "")) {
1927						Sizzle.error("unsupported lang: " + lang);
1928					}
1929					lang = lang.replace(runescape, funescape).toLowerCase();
1930					return function (elem) {
1931						var elemLang;
1932						do {
1933							if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
1934
1935								elemLang = elemLang.toLowerCase();
1936								return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
1937							}
1938						} while ((elem = elem.parentNode) && elem.nodeType === 1);
1939						return false;
vendor: 4,299 bytes, lines 1940-2093
1940					};
1941				}),
1942
1943				// Miscellaneous
1944				"target": function (elem) {
1945					var hash = window.location && window.location.hash;
1946					return hash && hash.slice(1) === elem.id;
1947				},
1948
1949				"root": function (elem) {
1950					return elem === docElem;
1951				},
1952
1953				"focus": function (elem) {
1954					return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1955				},
1956
1957				// Boolean properties
1958				"enabled": function (elem) {
1959					return elem.disabled === false;
1960				},
1961
1962				"disabled": function (elem) {
1963					return elem.disabled === true;
1964				},
1965
1966				"checked": function (elem) {
1967					// In CSS3, :checked should return both checked and selected elements
1968					// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1969					var nodeName = elem.nodeName.toLowerCase();
1970					return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected;
1971				},
1972
1973				"selected": function (elem) {
1974					// Accessing this property makes selected-by-default
1975					// options in Safari work properly
1976					if (elem.parentNode) {
1977						elem.parentNode.selectedIndex;
1978					}
1979
1980					return elem.selected === true;
1981				},
1982
1983				// Contents
1984				"empty": function (elem) {
1985					// http://www.w3.org/TR/selectors/#empty-pseudo
1986					// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1987					//   but not by others (comment: 8; processing instruction: 7; etc.)
1988					// nodeType < 6 works because attributes (2) do not appear as children
1989					for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
1990						if (elem.nodeType < 6) {
1991							return false;
1992						}
1993					}
1994					return true;
1995				},
1996
1997				"parent": function (elem) {
1998					return !Expr.pseudos["empty"](elem);
1999				},
2000
2001				// Element/input types
2002				"header": function (elem) {
2003					return rheader.test(elem.nodeName);
2004				},
2005
2006				"input": function (elem) {
2007					return rinputs.test(elem.nodeName);
2008				},
2009
2010				"button": function (elem) {
2011					var name = elem.nodeName.toLowerCase();
2012					return name === "input" && elem.type === "button" || name === "button";
2013				},
2014
2015				"text": function (elem) {
2016					var attr;
2017					return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && (
2018
2019					// Support: IE<8
2020					// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2021					(attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
2022				},
2023
2024				// Position-in-collection
2025				"first": createPositionalPseudo(function () {
2026					return [0];
2027				}),
2028
2029				"last": createPositionalPseudo(function (matchIndexes, length) {
2030					return [length - 1];
2031				}),
2032
2033				"eq": createPositionalPseudo(function (matchIndexes, length, argument) {
2034					return [argument < 0 ? argument + length : argument];
2035				}),
2036
2037				"even": createPositionalPseudo(function (matchIndexes, length) {
2038					var i = 0;
2039					for (; i < length; i += 2) {
2040						matchIndexes.push(i);
2041					}
2042					return matchIndexes;
2043				}),
2044
2045				"odd": createPositionalPseudo(function (matchIndexes, length) {
2046					var i = 1;
2047					for (; i < length; i += 2) {
2048						matchIndexes.push(i);
2049					}
2050					return matchIndexes;
2051				}),
2052
2053				"lt": createPositionalPseudo(function (matchIndexes, length, argument) {
2054					var i = argument < 0 ? argument + length : argument;
2055					for (; --i >= 0;) {
2056						matchIndexes.push(i);
2057					}
2058					return matchIndexes;
2059				}),
2060
2061				"gt": createPositionalPseudo(function (matchIndexes, length, argument) {
2062					var i = argument < 0 ? argument + length : argument;
2063					for (; ++i < length;) {
2064						matchIndexes.push(i);
2065					}
2066					return matchIndexes;
2067				})
2068			}
2069		};
2070
2071		Expr.pseudos["nth"] = Expr.pseudos["eq"];
2072
2073		// Add button/input type pseudos
2074		for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) {
2075			Expr.pseudos[i] = createInputPseudo(i);
2076		}
2077		for (i in { submit: true, reset: true }) {
2078			Expr.pseudos[i] = createButtonPseudo(i);
2079		}
2080
2081		// Easy API for creating new setFilters
2082		function setFilters() {}
2083		setFilters.prototype = Expr.filters = Expr.pseudos;
2084		Expr.setFilters = new setFilters();
2085
2086		tokenize = Sizzle.tokenize = function (selector, parseOnly) {
2087			var matched,
2088			    match,
2089			    tokens,
2090			    type,
2091			    soFar,
2092			    groups,
2093			    preFilters,
vendor: 7,182 bytes, lines 2094-2359
2094			    cached = tokenCache[selector + " "];
2095
2096			if (cached) {
2097				return parseOnly ? 0 : cached.slice(0);
2098			}
2099
2100			soFar = selector;
2101			groups = [];
2102			preFilters = Expr.preFilter;
2103
2104			while (soFar) {
2105
2106				// Comma and first run
2107				if (!matched || (match = rcomma.exec(soFar))) {
2108					if (match) {
2109						// Don't consume trailing commas as valid
2110						soFar = soFar.slice(match[0].length) || soFar;
2111					}
2112					groups.push(tokens = []);
2113				}
2114
2115				matched = false;
2116
2117				// Combinators
2118				if (match = rcombinators.exec(soFar)) {
2119					matched = match.shift();
2120					tokens.push({
2121						value: matched,
2122						// Cast descendant combinators to space
2123						type: match[0].replace(rtrim, " ")
2124					});
2125					soFar = soFar.slice(matched.length);
2126				}
2127
2128				// Filters
2129				for (type in Expr.filter) {
2130					if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
2131						matched = match.shift();
2132						tokens.push({
2133							value: matched,
2134							type: type,
2135							matches: match
2136						});
2137						soFar = soFar.slice(matched.length);
2138					}
2139				}
2140
2141				if (!matched) {
2142					break;
2143				}
2144			}
2145
2146			// Return the length of the invalid excess
2147			// if we're just parsing
2148			// Otherwise, throw an error or return tokens
2149			return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) :
2150			// Cache the tokens
2151			tokenCache(selector, groups).slice(0);
2152		};
2153
2154		function toSelector(tokens) {
2155			var i = 0,
2156			    len = tokens.length,
2157			    selector = "";
2158			for (; i < len; i++) {
2159				selector += tokens[i].value;
2160			}
2161			return selector;
2162		}
2163
2164		function addCombinator(matcher, combinator, base) {
2165			var dir = combinator.dir,
2166			    checkNonElements = base && dir === "parentNode",
2167			    doneName = done++;
2168
2169			return combinator.first ?
2170			// Check against closest ancestor/preceding element
2171			function (elem, context, xml) {
2172				while (elem = elem[dir]) {
2173					if (elem.nodeType === 1 || checkNonElements) {
2174						return matcher(elem, context, xml);
2175					}
2176				}
2177			} :
2178
2179			// Check against all ancestor/preceding elements
2180			function (elem, context, xml) {
2181				var oldCache,
2182				    uniqueCache,
2183				    outerCache,
2184				    newCache = [dirruns, doneName];
2185
2186				// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2187				if (xml) {
2188					while (elem = elem[dir]) {
2189						if (elem.nodeType === 1 || checkNonElements) {
2190							if (matcher(elem, context, xml)) {
2191								return true;
2192							}
2193						}
2194					}
2195				} else {
2196					while (elem = elem[dir]) {
2197						if (elem.nodeType === 1 || checkNonElements) {
2198							outerCache = elem[expando] || (elem[expando] = {});
2199
2200							// Support: IE <9 only
2201							// Defend against cloned attroperties (jQuery gh-1709)
2202							uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {});
2203
2204							if ((oldCache = uniqueCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
2205
2206								// Assign to newCache so results back-propagate to previous elements
2207								return newCache[2] = oldCache[2];
2208							} else {
2209								// Reuse newcache so results back-propagate to previous elements
2210								uniqueCache[dir] = newCache;
2211
2212								// A match means we're done; a fail means we have to keep checking
2213								if (newCache[2] = matcher(elem, context, xml)) {
2214									return true;
2215								}
2216							}
2217						}
2218					}
2219				}
2220			};
2221		}
2222
2223		function elementMatcher(matchers) {
2224			return matchers.length > 1 ? function (elem, context, xml) {
2225				var i = matchers.length;
2226				while (i--) {
2227					if (!matchers[i](elem, context, xml)) {
2228						return false;
2229					}
2230				}
2231				return true;
2232			} : matchers[0];
2233		}
2234
2235		function multipleContexts(selector, contexts, results) {
2236			var i = 0,
2237			    len = contexts.length;
2238			for (; i < len; i++) {
2239				Sizzle(selector, contexts[i], results);
2240			}
2241			return results;
2242		}
2243
2244		function condense(unmatched, map, filter, context, xml) {
2245			var elem,
2246			    newUnmatched = [],
2247			    i = 0,
2248			    len = unmatched.length,
2249			    mapped = map != null;
2250
2251			for (; i < len; i++) {
2252				if (elem = unmatched[i]) {
2253					if (!filter || filter(elem, context, xml)) {
2254						newUnmatched.push(elem);
2255						if (mapped) {
2256							map.push(i);
2257						}
2258					}
2259				}
2260			}
2261
2262			return newUnmatched;
2263		}
2264
2265		function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
2266			if (postFilter && !postFilter[expando]) {
2267				postFilter = setMatcher(postFilter);
2268			}
2269			if (postFinder && !postFinder[expando]) {
2270				postFinder = setMatcher(postFinder, postSelector);
2271			}
2272			return markFunction(function (seed, results, context, xml) {
2273				var temp,
2274				    i,
2275				    elem,
2276				    preMap = [],
2277				    postMap = [],
2278				    preexisting = results.length,
2279
2280
2281				// Get initial elements from seed or context
2282				elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
2283
2284
2285				// Prefilter to get matcher input, preserving a map for seed-results synchronization
2286				matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems,
2287				    matcherOut = matcher ?
2288				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2289				postFinder || (seed ? preFilter : preexisting || postFilter) ?
2290
2291				// ...intermediate processing is necessary
2292				[] :
2293
2294				// ...otherwise use results directly
2295				results : matcherIn;
2296
2297				// Find primary matches
2298				if (matcher) {
2299					matcher(matcherIn, matcherOut, context, xml);
2300				}
2301
2302				// Apply postFilter
2303				if (postFilter) {
2304					temp = condense(matcherOut, postMap);
2305					postFilter(temp, [], context, xml);
2306
2307					// Un-match failing elements by moving them back to matcherIn
2308					i = temp.length;
2309					while (i--) {
2310						if (elem = temp[i]) {
2311							matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
2312						}
2313					}
2314				}
2315
2316				if (seed) {
2317					if (postFinder || preFilter) {
2318						if (postFinder) {
2319							// Get the final matcherOut by condensing this intermediate into postFinder contexts
2320							temp = [];
2321							i = matcherOut.length;
2322							while (i--) {
2323								if (elem = matcherOut[i]) {
2324									// Restore matcherIn since elem is not yet a final match
2325									temp.push(matcherIn[i] = elem);
2326								}
2327							}
2328							postFinder(null, matcherOut = [], temp, xml);
2329						}
2330
2331						// Move matched elements from seed to results to keep them synchronized
2332						i = matcherOut.length;
2333						while (i--) {
2334							if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {
2335
2336								seed[temp] = !(results[temp] = elem);
2337							}
2338						}
2339					}
2340
2341					// Add elements to results, through postFinder if defined
2342				} else {
2343					matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
2344					if (postFinder) {
2345						postFinder(null, results, matcherOut, xml);
2346					} else {
2347						push.apply(results, matcherOut);
2348					}
2349				}
2350			});
2351		}
2352
2353		function matcherFromTokens(tokens) {
2354			var checkContext,
2355			    matcher,
2356			    j,
2357			    len = tokens.length,
2358			    leadingRelative = Expr.relative[tokens[0].type],
2359			    implicitRelative = leadingRelative || Expr.relative[" "],
vendor: 7,952 bytes, lines 2360-2596
2360			    i = leadingRelative ? 1 : 0,
2361
2362
2363			// The foundational matcher ensures that elements are reachable from top-level context(s)
2364			matchContext = addCombinator(function (elem) {
2365				return elem === checkContext;
2366			}, implicitRelative, true),
2367			    matchAnyContext = addCombinator(function (elem) {
2368				return indexOf(checkContext, elem) > -1;
2369			}, implicitRelative, true),
2370			    matchers = [function (elem, context, xml) {
2371				var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
2372				// Avoid hanging onto element (issue #299)
2373				checkContext = null;
2374				return ret;
2375			}];
2376
2377			for (; i < len; i++) {
2378				if (matcher = Expr.relative[tokens[i].type]) {
2379					matchers = [addCombinator(elementMatcher(matchers), matcher)];
2380				} else {
2381					matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
2382
2383					// Return special upon seeing a positional matcher
2384					if (matcher[expando]) {
2385						// Find the next relative operator (if any) for proper handling
2386						j = ++i;
2387						for (; j < len; j++) {
2388							if (Expr.relative[tokens[j].type]) {
2389								break;
2390							}
2391						}
2392						return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(
2393						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2394						tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === " " ? "*" : "" })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
2395					}
2396					matchers.push(matcher);
2397				}
2398			}
2399
2400			return elementMatcher(matchers);
2401		}
2402
2403		function matcherFromGroupMatchers(elementMatchers, setMatchers) {
2404			var bySet = setMatchers.length > 0,
2405			    byElement = elementMatchers.length > 0,
2406			    superMatcher = function (seed, context, xml, results, outermost) {
2407				var elem,
2408				    j,
2409				    matcher,
2410				    matchedCount = 0,
2411				    i = "0",
2412				    unmatched = seed && [],
2413				    setMatched = [],
2414				    contextBackup = outermostContext,
2415
2416				// We must always have either seed elements or outermost context
2417				elems = seed || byElement && Expr.find["TAG"]("*", outermost),
2418
2419				// Use integer dirruns iff this is the outermost matcher
2420				dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1,
2421				    len = elems.length;
2422
2423				if (outermost) {
2424					outermostContext = context === document || context || outermost;
2425				}
2426
2427				// Add elements passing elementMatchers directly to results
2428				// Support: IE<9, Safari
2429				// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2430				for (; i !== len && (elem = elems[i]) != null; i++) {
2431					if (byElement && elem) {
2432						j = 0;
2433						if (!context && elem.ownerDocument !== document) {
2434							setDocument(elem);
2435							xml = !documentIsHTML;
2436						}
2437						while (matcher = elementMatchers[j++]) {
2438							if (matcher(elem, context || document, xml)) {
2439								results.push(elem);
2440								break;
2441							}
2442						}
2443						if (outermost) {
2444							dirruns = dirrunsUnique;
2445						}
2446					}
2447
2448					// Track unmatched elements for set filters
2449					if (bySet) {
2450						// They will have gone through all possible matchers
2451						if (elem = !matcher && elem) {
2452							matchedCount--;
2453						}
2454
2455						// Lengthen the array for every element, matched or not
2456						if (seed) {
2457							unmatched.push(elem);
2458						}
2459					}
2460				}
2461
2462				// `i` is now the count of elements visited above, and adding it to `matchedCount`
2463				// makes the latter nonnegative.
2464				matchedCount += i;
2465
2466				// Apply set filters to unmatched elements
2467				// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2468				// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2469				// no element matchers and no seed.
2470				// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2471				// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2472				// numerically zero.
2473				if (bySet && i !== matchedCount) {
2474					j = 0;
2475					while (matcher = setMatchers[j++]) {
2476						matcher(unmatched, setMatched, context, xml);
2477					}
2478
2479					if (seed) {
2480						// Reintegrate element matches to eliminate the need for sorting
2481						if (matchedCount > 0) {
2482							while (i--) {
2483								if (!(unmatched[i] || setMatched[i])) {
2484									setMatched[i] = pop.call(results);
2485								}
2486							}
2487						}
2488
2489						// Discard index placeholder values to get only actual matches
2490						setMatched = condense(setMatched);
2491					}
2492
2493					// Add matches to results
2494					push.apply(results, setMatched);
2495
2496					// Seedless set matches succeeding multiple successful matchers stipulate sorting
2497					if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
2498
2499						Sizzle.uniqueSort(results);
2500					}
2501				}
2502
2503				// Override manipulation of globals by nested matchers
2504				if (outermost) {
2505					dirruns = dirrunsUnique;
2506					outermostContext = contextBackup;
2507				}
2508
2509				return unmatched;
2510			};
2511
2512			return bySet ? markFunction(superMatcher) : superMatcher;
2513		}
2514
2515		compile = Sizzle.compile = function (selector, match /* Internal Use Only */) {
2516			var i,
2517			    setMatchers = [],
2518			    elementMatchers = [],
2519			    cached = compilerCache[selector + " "];
2520
2521			if (!cached) {
2522				// Generate a function of recursive functions that can be used to check each element
2523				if (!match) {
2524					match = tokenize(selector);
2525				}
2526				i = match.length;
2527				while (i--) {
2528					cached = matcherFromTokens(match[i]);
2529					if (cached[expando]) {
2530						setMatchers.push(cached);
2531					} else {
2532						elementMatchers.push(cached);
2533					}
2534				}
2535
2536				// Cache the compiled function
2537				cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
2538
2539				// Save selector and tokenization
2540				cached.selector = selector;
2541			}
2542			return cached;
2543		};
2544
2545		/**
2546   * A low-level selection function that works with Sizzle's compiled
2547   *  selector functions
2548   * @param {String|Function} selector A selector or a pre-compiled
2549   *  selector function built with Sizzle.compile
2550   * @param {Element} context
2551   * @param {Array} [results]
2552   * @param {Array} [seed] A set of elements to match against
2553   */
2554		select = Sizzle.select = function (selector, context, results, seed) {
2555			var i,
2556			    tokens,
2557			    token,
2558			    type,
2559			    find,
2560			    compiled = typeof selector === "function" && selector,
2561			    match = !seed && tokenize(selector = compiled.selector || selector);
2562
2563			results = results || [];
2564
2565			// Try to minimize operations if there is only one selector in the list and no seed
2566			// (the latter of which guarantees us context)
2567			if (match.length === 1) {
2568
2569				// Reduce context if the leading compound selector is an ID
2570				tokens = match[0] = match[0].slice(0);
2571				if (tokens.length > 2 && (token = tokens[0]).type === "ID" && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
2572
2573					context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
2574					if (!context) {
2575						return results;
2576
2577						// Precompiled matchers will still verify ancestry, so step up a level
2578					} else if (compiled) {
2579						context = context.parentNode;
2580					}
2581
2582					selector = selector.slice(tokens.shift().value.length);
2583				}
2584
2585				// Fetch a seed set for right-to-left matching
2586				i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
2587				while (i--) {
2588					token = tokens[i];
2589
2590					// Abort if we hit a combinator
2591					if (Expr.relative[type = token.type]) {
2592						break;
2593					}
2594					if (find = Expr.find[type]) {
2595						// Search, expanding context for leading sibling combinators
2596						if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testC
vendor: 5,935 bytes, lines 2596-2810
2596ontext(context.parentNode) || context)) {
2597
2598							// If seed is empty or no tokens remain, we can return early
2599							tokens.splice(i, 1);
2600							selector = seed.length && toSelector(tokens);
2601							if (!selector) {
2602								push.apply(results, seed);
2603								return results;
2604							}
2605
2606							break;
2607						}
2608					}
2609				}
2610			}
2611
2612			// Compile and execute a filtering function if one is not provided
2613			// Provide `match` to avoid retokenization if we modified the selector above
2614			(compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context);
2615			return results;
2616		};
2617
2618		// One-time assignments
2619
2620		// Sort stability
2621		support.sortStable = expando.split("").sort(sortOrder).join("") === expando;
2622
2623		// Support: Chrome 14-35+
2624		// Always assume duplicates if they aren't passed to the comparison function
2625		support.detectDuplicates = !!hasDuplicate;
2626
2627		// Initialize against the default document
2628		setDocument();
2629
2630		// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2631		// Detached nodes confoundingly follow *each other*
2632		support.sortDetached = assert(function (div1) {
2633			// Should return 1, but returns 4 (following)
2634			return div1.compareDocumentPosition(document.createElement("div")) & 1;
2635		});
2636
2637		// Support: IE<8
2638		// Prevent attribute/property "interpolation"
2639		// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2640		if (!assert(function (div) {
2641			div.innerHTML = "<a href='#'></a>";
2642			return div.firstChild.getAttribute("href") === "#";
2643		})) {
2644			addHandle("type|href|height|width", function (elem, name, isXML) {
2645				if (!isXML) {
2646					return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);
2647				}
2648			});
2649		}
2650
2651		// Support: IE<9
2652		// Use defaultValue in place of getAttribute("value")
2653		if (!support.attributes || !assert(function (div) {
2654			div.innerHTML = "<input/>";
2655			div.firstChild.setAttribute("value", "");
2656			return div.firstChild.getAttribute("value") === "";
2657		})) {
2658			addHandle("value", function (elem, name, isXML) {
2659				if (!isXML && elem.nodeName.toLowerCase() === "input") {
2660					return elem.defaultValue;
2661				}
2662			});
2663		}
2664
2665		// Support: IE<9
2666		// Use getAttributeNode to fetch booleans when getAttribute lies
2667		if (!assert(function (div) {
2668			return div.getAttribute("disabled") == null;
2669		})) {
2670			addHandle(booleans, function (elem, name, isXML) {
2671				var val;
2672				if (!isXML) {
2673					return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
2674				}
2675			});
2676		}
2677
2678		return Sizzle;
2679	}(window);
2680
2681	jQuery.find = Sizzle;
2682	jQuery.expr = Sizzle.selectors;
2683	jQuery.expr[":"] = jQuery.expr.pseudos;
2684	jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2685	jQuery.text = Sizzle.getText;
2686	jQuery.isXMLDoc = Sizzle.isXML;
2687	jQuery.contains = Sizzle.contains;
2688
2689	var dir = function (elem, dir, until) {
2690		var matched = [],
2691		    truncate = until !== undefined;
2692
2693		while ((elem = elem[dir]) && elem.nodeType !== 9) {
2694			if (elem.nodeType === 1) {
2695				if (truncate && jQuery(elem).is(until)) {
2696					break;
2697				}
2698				matched.push(elem);
2699			}
2700		}
2701		return matched;
2702	};
2703
2704	var siblings = function (n, elem) {
2705		var matched = [];
2706
2707		for (; n; n = n.nextSibling) {
2708			if (n.nodeType === 1 && n !== elem) {
2709				matched.push(n);
2710			}
2711		}
2712
2713		return matched;
2714	};
2715
2716	var rneedsContext = jQuery.expr.match.needsContext;
2717
2718	var rsingleTag = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;
2719
2720	var risSimple = /^.[^:#\[\.,]*$/;
2721
2722	// Implement the identical functionality for filter and not
2723	function winnow(elements, qualifier, not) {
2724		if (jQuery.isFunction(qualifier)) {
2725			return jQuery.grep(elements, function (elem, i) {
2726				/* jshint -W018 */
2727				return !!qualifier.call(elem, i, elem) !== not;
2728			});
2729		}
2730
2731		if (qualifier.nodeType) {
2732			return jQuery.grep(elements, function (elem) {
2733				return elem === qualifier !== not;
2734			});
2735		}
2736
2737		if (typeof qualifier === "string") {
2738			if (risSimple.test(qualifier)) {
2739				return jQuery.filter(qualifier, elements, not);
2740			}
2741
2742			qualifier = jQuery.filter(qualifier, elements);
2743		}
2744
2745		return jQuery.grep(elements, function (elem) {
2746			return jQuery.inArray(elem, qualifier) > -1 !== not;
2747		});
2748	}
2749
2750	jQuery.filter = function (expr, elems, not) {
2751		var elem = elems[0];
2752
2753		if (not) {
2754			expr = ":not(" + expr + ")";
2755		}
2756
2757		return elems.length === 1 && elem.nodeType === 1 ? jQuery.find.matchesSelector(elem, expr) ? [elem] : [] : jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
2758			return elem.nodeType === 1;
2759		}));
2760	};
2761
2762	jQuery.fn.extend({
2763		find: function (selector) {
2764			var i,
2765			    ret = [],
2766			    self = this,
2767			    len = self.length;
2768
2769			if (typeof selector !== "string") {
2770				return this.pushStack(jQuery(selector).filter(function () {
2771					for (i = 0; i < len; i++) {
2772						if (jQuery.contains(self[i], this)) {
2773							return true;
2774						}
2775					}
2776				}));
2777			}
2778
2779			for (i = 0; i < len; i++) {
2780				jQuery.find(selector, self[i], ret);
2781			}
2782
2783			// Needed because $( selector, context ) becomes $( context ).find( selector )
2784			ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
2785			ret.selector = this.selector ? this.selector + " " + selector : selector;
2786			return ret;
2787		},
2788		filter: function (selector) {
2789			return this.pushStack(winnow(this, selector || [], false));
2790		},
2791		not: function (selector) {
2792			return this.pushStack(winnow(this, selector || [], true));
2793		},
2794		is: function (selector) {
2795			return !!winnow(this,
2796
2797			// If this is a positional/relative selector, check membership in the returned set
2798			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2799			typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length;
2800		}
2801	});
2802
2803	// Initialize a jQuery object
2804
2805
2806	// A central reference to the root jQuery(document)
2807	var rootjQuery,
2808
2809
2810	// A simple way to check for HTML strings
vendor: 9,553 bytes, lines 2811-3167
2811	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2812	// Strict HTML recognition (#11290: must start with <)
2813	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2814	    init = jQuery.fn.init = function (selector, context, root) {
2815		var match, elem;
2816
2817		// HANDLE: $(""), $(null), $(undefined), $(false)
2818		if (!selector) {
2819			return this;
2820		}
2821
2822		// init accepts an alternate rootjQuery
2823		// so migrate can support jQuery.sub (gh-2101)
2824		root = root || rootjQuery;
2825
2826		// Handle HTML strings
2827		if (typeof selector === "string") {
2828			if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) {
2829
2830				// Assume that strings that start and end with <> are HTML and skip the regex check
2831				match = [null, selector, null];
2832			} else {
2833				match = rquickExpr.exec(selector);
2834			}
2835
2836			// Match html or make sure no context is specified for #id
2837			if (match && (match[1] || !context)) {
2838
2839				// HANDLE: $(html) -> $(array)
2840				if (match[1]) {
2841					context = context instanceof jQuery ? context[0] : context;
2842
2843					// scripts is true for back-compat
2844					// Intentionally let the error be thrown if parseHTML is not present
2845					jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true));
2846
2847					// HANDLE: $(html, props)
2848					if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
2849						for (match in context) {
2850
2851							// Properties of context are called as methods if possible
2852							if (jQuery.isFunction(this[match])) {
2853								this[match](context[match]);
2854
2855								// ...and otherwise set as attributes
2856							} else {
2857								this.attr(match, context[match]);
2858							}
2859						}
2860					}
2861
2862					return this;
2863
2864					// HANDLE: $(#id)
2865				} else {
2866					elem = document.getElementById(match[2]);
2867
2868					// Check parentNode to catch when Blackberry 4.6 returns
2869					// nodes that are no longer in the document #6963
2870					if (elem && elem.parentNode) {
2871
2872						// Handle the case where IE and Opera return items
2873						// by name instead of ID
2874						if (elem.id !== match[2]) {
2875							return rootjQuery.find(selector);
2876						}
2877
2878						// Otherwise, we inject the element directly into the jQuery object
2879						this.length = 1;
2880						this[0] = elem;
2881					}
2882
2883					this.context = document;
2884					this.selector = selector;
2885					return this;
2886				}
2887
2888				// HANDLE: $(expr, $(...))
2889			} else if (!context || context.jquery) {
2890				return (context || root).find(selector);
2891
2892				// HANDLE: $(expr, context)
2893				// (which is just equivalent to: $(context).find(expr)
2894			} else {
2895				return this.constructor(context).find(selector);
2896			}
2897
2898			// HANDLE: $(DOMElement)
2899		} else if (selector.nodeType) {
2900			this.context = this[0] = selector;
2901			this.length = 1;
2902			return this;
2903
2904			// HANDLE: $(function)
2905			// Shortcut for document ready
2906		} else if (jQuery.isFunction(selector)) {
2907			return typeof root.ready !== "undefined" ? root.ready(selector) :
2908
2909			// Execute immediately if ready is not present
2910			selector(jQuery);
2911		}
2912
2913		if (selector.selector !== undefined) {
2914			this.selector = selector.selector;
2915			this.context = selector.context;
2916		}
2917
2918		return jQuery.makeArray(selector, this);
2919	};
2920
2921	// Give the init function the jQuery prototype for later instantiation
2922	init.prototype = jQuery.fn;
2923
2924	// Initialize central reference
2925	rootjQuery = jQuery(document);
2926
2927	var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2928
2929
2930	// methods guaranteed to produce a unique set when starting from a unique set
2931	guaranteedUnique = {
2932		children: true,
2933		contents: true,
2934		next: true,
2935		prev: true
2936	};
2937
2938	jQuery.fn.extend({
2939		has: function (target) {
2940			var i,
2941			    targets = jQuery(target, this),
2942			    len = targets.length;
2943
2944			return this.filter(function () {
2945				for (i = 0; i < len; i++) {
2946					if (jQuery.contains(this, targets[i])) {
2947						return true;
2948					}
2949				}
2950			});
2951		},
2952
2953		closest: function (selectors, context) {
2954			var cur,
2955			    i = 0,
2956			    l = this.length,
2957			    matched = [],
2958			    pos = rneedsContext.test(selectors) || typeof selectors !== "string" ? jQuery(selectors, context || this.context) : 0;
2959
2960			for (; i < l; i++) {
2961				for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
2962
2963					// Always skip document fragments
2964					if (cur.nodeType < 11 && (pos ? pos.index(cur) > -1 :
2965
2966					// Don't pass non-elements to Sizzle
2967					cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {
2968
2969						matched.push(cur);
2970						break;
2971					}
2972				}
2973			}
2974
2975			return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
2976		},
2977
2978		// Determine the position of an element within
2979		// the matched set of elements
2980		index: function (elem) {
2981
2982			// No argument, return index in parent
2983			if (!elem) {
2984				return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;
2985			}
2986
2987			// index in selector
2988			if (typeof elem === "string") {
2989				return jQuery.inArray(this[0], jQuery(elem));
2990			}
2991
2992			// Locate the position of the desired element
2993			return jQuery.inArray(
2994
2995			// If it receives a jQuery object, the first element is used
2996			elem.jquery ? elem[0] : elem, this);
2997		},
2998
2999		add: function (selector, context) {
3000			return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context))));
3001		},
3002
3003		addBack: function (selector) {
3004			return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));
3005		}
3006	});
3007
3008	function sibling(cur, dir) {
3009		do {
3010			cur = cur[dir];
3011		} while (cur && cur.nodeType !== 1);
3012
3013		return cur;
3014	}
3015
3016	jQuery.each({
3017		parent: function (elem) {
3018			var parent = elem.parentNode;
3019			return parent && parent.nodeType !== 11 ? parent : null;
3020		},
3021		parents: function (elem) {
3022			return dir(elem, "parentNode");
3023		},
3024		parentsUntil: function (elem, i, until) {
3025			return dir(elem, "parentNode", until);
3026		},
3027		next: function (elem) {
3028			return sibling(elem, "nextSibling");
3029		},
3030		prev: function (elem) {
3031			return sibling(elem, "previousSibling");
3032		},
3033		nextAll: function (elem) {
3034			return dir(elem, "nextSibling");
3035		},
3036		prevAll: function (elem) {
3037			return dir(elem, "previousSibling");
3038		},
3039		nextUntil: function (elem, i, until) {
3040			return dir(elem, "nextSibling", until);
3041		},
3042		prevUntil: function (elem, i, until) {
3043			return dir(elem, "previousSibling", until);
3044		},
3045		siblings: function (elem) {
3046			return siblings((elem.parentNode || {}).firstChild, elem);
3047		},
3048		children: function (elem) {
3049			return siblings(elem.firstChild);
3050		},
3051		contents: function (elem) {
3052			return jQuery.nodeName(elem, "iframe") ? elem.contentDocument || elem.contentWindow.document : jQuery.merge([], elem.childNodes);
3053		}
3054	}, function (name, fn) {
3055		jQuery.fn[name] = function (until, selector) {
3056			var ret = jQuery.map(this, fn, until);
3057
3058			if (name.slice(-5) !== "Until") {
3059				selector = until;
3060			}
3061
3062			if (selector && typeof selector === "string") {
3063				ret = jQuery.filter(selector, ret);
3064			}
3065
3066			if (this.length > 1) {
3067
3068				// Remove duplicates
3069				if (!guaranteedUnique[name]) {
3070					ret = jQuery.uniqueSort(ret);
3071				}
3072
3073				// Reverse order for parents* and prev-derivatives
3074				if (rparentsprev.test(name)) {
3075					ret = ret.reverse();
3076				}
3077			}
3078
3079			return this.pushStack(ret);
3080		};
3081	});
3082	var rnotwhite = /\S+/g;
3083
3084	// Convert String-formatted options into Object-formatted ones
3085	function createOptions(options) {
3086		var object = {};
3087		jQuery.each(options.match(rnotwhite) || [], function (_, flag) {
3088			object[flag] = true;
3089		});
3090		return object;
3091	}
3092
3093	/*
3094  * Create a callback list using the following parameters:
3095  *
3096  *	options: an optional list of space-separated options that will change how
3097  *			the callback list behaves or a more traditional option object
3098  *
3099  * By default a callback list will act like an event callback list and can be
3100  * "fired" multiple times.
3101  *
3102  * Possible options:
3103  *
3104  *	once:			will ensure the callback list can only be fired once (like a Deferred)
3105  *
3106  *	memory:			will keep track of previous values and will call any callback added
3107  *					after the list has been fired right away with the latest "memorized"
3108  *					values (like a Deferred)
3109  *
3110  *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3111  *
3112  *	stopOnFalse:	interrupt callings when a callback returns false
3113  *
3114  */
3115	jQuery.Callbacks = function (options) {
3116
3117		// Convert options from String-formatted to Object-formatted if needed
3118		// (we check in cache first)
3119		options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options);
3120
3121		var // Flag to know if list is currently firing
3122		firing,
3123
3124
3125		// Last fire value for non-forgettable lists
3126		memory,
3127
3128
3129		// Flag to know if list was already fired
3130		fired,
3131
3132
3133		// Flag to prevent firing
3134		locked,
3135
3136
3137		// Actual callback list
3138		list = [],
3139
3140
3141		// Queue of execution data for repeatable lists
3142		queue = [],
3143
3144
3145		// Index of currently firing callback (modified by add/remove as needed)
3146		firingIndex = -1,
3147
3148
3149		// Fire callbacks
3150		fire = function () {
3151
3152			// Enforce single-firing
3153			locked = options.once;
3154
3155			// Execute callbacks for all pending executions,
3156			// respecting firingIndex overrides and runtime changes
3157			fired = firing = true;
3158			for (; queue.length; firingIndex = -1) {
3159				memory = queue.shift();
3160				while (++firingIndex < list.length) {
3161
3162					// Run callback and check for early termination
3163					if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) {
3164
3165						// Jump to end and forget the data so .add doesn't re-fire
3166						firingIndex = list.length;
3167						memory = false;
vendor: 8,134 bytes, lines 3168-3497
3168					}
3169				}
3170			}
3171
3172			// Forget the data if we're done with it
3173			if (!options.memory) {
3174				memory = false;
3175			}
3176
3177			firing = false;
3178
3179			// Clean up if we're done firing for good
3180			if (locked) {
3181
3182				// Keep an empty list if we have data for future add calls
3183				if (memory) {
3184					list = [];
3185
3186					// Otherwise, this object is spent
3187				} else {
3188					list = "";
3189				}
3190			}
3191		},
3192
3193
3194		// Actual Callbacks object
3195		self = {
3196
3197			// Add a callback or a collection of callbacks to the list
3198			add: function () {
3199				if (list) {
3200
3201					// If we have memory from a past run, we should fire after adding
3202					if (memory && !firing) {
3203						firingIndex = list.length - 1;
3204						queue.push(memory);
3205					}
3206
3207					(function add(args) {
3208						jQuery.each(args, function (_, arg) {
3209							if (jQuery.isFunction(arg)) {
3210								if (!options.unique || !self.has(arg)) {
3211									list.push(arg);
3212								}
3213							} else if (arg && arg.length && jQuery.type(arg) !== "string") {
3214
3215								// Inspect recursively
3216								add(arg);
3217							}
3218						});
3219					})(arguments);
3220
3221					if (memory && !firing) {
3222						fire();
3223					}
3224				}
3225				return this;
3226			},
3227
3228			// Remove a callback from the list
3229			remove: function () {
3230				jQuery.each(arguments, function (_, arg) {
3231					var index;
3232					while ((index = jQuery.inArray(arg, list, index)) > -1) {
3233						list.splice(index, 1);
3234
3235						// Handle firing indexes
3236						if (index <= firingIndex) {
3237							firingIndex--;
3238						}
3239					}
3240				});
3241				return this;
3242			},
3243
3244			// Check if a given callback is in the list.
3245			// If no argument is given, return whether or not list has callbacks attached.
3246			has: function (fn) {
3247				return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0;
3248			},
3249
3250			// Remove all callbacks from the list
3251			empty: function () {
3252				if (list) {
3253					list = [];
3254				}
3255				return this;
3256			},
3257
3258			// Disable .fire and .add
3259			// Abort any current/pending executions
3260			// Clear all callbacks and values
3261			disable: function () {
3262				locked = queue = [];
3263				list = memory = "";
3264				return this;
3265			},
3266			disabled: function () {
3267				return !list;
3268			},
3269
3270			// Disable .fire
3271			// Also disable .add unless we have memory (since it would have no effect)
3272			// Abort any pending executions
3273			lock: function () {
3274				locked = true;
3275				if (!memory) {
3276					self.disable();
3277				}
3278				return this;
3279			},
3280			locked: function () {
3281				return !!locked;
3282			},
3283
3284			// Call all callbacks with the given context and arguments
3285			fireWith: function (context, args) {
3286				if (!locked) {
3287					args = args || [];
3288					args = [context, args.slice ? args.slice() : args];
3289					queue.push(args);
3290					if (!firing) {
3291						fire();
3292					}
3293				}
3294				return this;
3295			},
3296
3297			// Call all the callbacks with the given arguments
3298			fire: function () {
3299				self.fireWith(this, arguments);
3300				return this;
3301			},
3302
3303			// To know if the callbacks have already been called at least once
3304			fired: function () {
3305				return !!fired;
3306			}
3307		};
3308
3309		return self;
3310	};
3311
3312	jQuery.extend({
3313
3314		Deferred: function (func) {
3315			var tuples = [
3316
3317			// action, add listener, listener list, final state
3318			["resolve", "done", jQuery.Callbacks("once memory"), "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"], ["notify", "progress", jQuery.Callbacks("memory")]],
3319			    state = "pending",
3320			    promise = {
3321				state: function () {
3322					return state;
3323				},
3324				always: function () {
3325					deferred.done(arguments).fail(arguments);
3326					return this;
3327				},
3328				then: function () /* fnDone, fnFail, fnProgress */{
3329					var fns = arguments;
3330					return jQuery.Deferred(function (newDefer) {
3331						jQuery.each(tuples, function (i, tuple) {
3332							var fn = jQuery.isFunction(fns[i]) && fns[i];
3333
3334							// deferred[ done | fail | progress ] for forwarding actions to newDefer
3335							deferred[tuple[1]](function () {
3336								var returned = fn && fn.apply(this, arguments);
3337								if (returned && jQuery.isFunction(returned.promise)) {
3338									returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);
3339								} else {
3340									newDefer[tuple[0] + "With"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments);
3341								}
3342							});
3343						});
3344						fns = null;
3345					}).promise();
3346				},
3347
3348				// Get a promise for this deferred
3349				// If obj is provided, the promise aspect is added to the object
3350				promise: function (obj) {
3351					return obj != null ? jQuery.extend(obj, promise) : promise;
3352				}
3353			},
3354			    deferred = {};
3355
3356			// Keep pipe for back-compat
3357			promise.pipe = promise.then;
3358
3359			// Add list-specific methods
3360			jQuery.each(tuples, function (i, tuple) {
3361				var list = tuple[2],
3362				    stateString = tuple[3];
3363
3364				// promise[ done | fail | progress ] = list.add
3365				promise[tuple[1]] = list.add;
3366
3367				// Handle state
3368				if (stateString) {
3369					list.add(function () {
3370
3371						// state = [ resolved | rejected ]
3372						state = stateString;
3373
3374						// [ reject_list | resolve_list ].disable; progress_list.lock
3375					}, tuples[i ^ 1][2].disable, tuples[2][2].lock);
3376				}
3377
3378				// deferred[ resolve | reject | notify ]
3379				deferred[tuple[0]] = function () {
3380					deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments);
3381					return this;
3382				};
3383				deferred[tuple[0] + "With"] = list.fireWith;
3384			});
3385
3386			// Make the deferred a promise
3387			promise.promise(deferred);
3388
3389			// Call given func if any
3390			if (func) {
3391				func.call(deferred, deferred);
3392			}
3393
3394			// All done!
3395			return deferred;
3396		},
3397
3398		// Deferred helper
3399		when: function (subordinate /* , ..., subordinateN */) {
3400			var i = 0,
3401			    resolveValues = slice.call(arguments),
3402			    length = resolveValues.length,
3403
3404
3405			// the count of uncompleted subordinates
3406			remaining = length !== 1 || subordinate && jQuery.isFunction(subordinate.promise) ? length : 0,
3407
3408
3409			// the master Deferred.
3410			// If resolveValues consist of only a single Deferred, just use that.
3411			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3412
3413
3414			// Update function for both resolve and progress values
3415			updateFunc = function (i, contexts, values) {
3416				return function (value) {
3417					contexts[i] = this;
3418					values[i] = arguments.length > 1 ? slice.call(arguments) : value;
3419					if (values === progressValues) {
3420						deferred.notifyWith(contexts, values);
3421					} else if (! --remaining) {
3422						deferred.resolveWith(contexts, values);
3423					}
3424				};
3425			},
3426			    progressValues,
3427			    progressContexts,
3428			    resolveContexts;
3429
3430			// add listeners to Deferred subordinates; treat others as resolved
3431			if (length > 1) {
3432				progressValues = new Array(length);
3433				progressContexts = new Array(length);
3434				resolveContexts = new Array(length);
3435				for (; i < length; i++) {
3436					if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {
3437						resolveValues[i].promise().progress(updateFunc(i, progressContexts, progressValues)).done(updateFunc(i, resolveContexts, resolveValues)).fail(deferred.reject);
3438					} else {
3439						--remaining;
3440					}
3441				}
3442			}
3443
3444			// if we're not waiting on anything, resolve the master
3445			if (!remaining) {
3446				deferred.resolveWith(resolveContexts, resolveValues);
3447			}
3448
3449			return deferred.promise();
3450		}
3451	});
3452
3453	// The deferred used on DOM ready
3454	var readyList;
3455
3456	jQuery.fn.ready = function (fn) {
3457
3458		// Add the callback
3459		jQuery.ready.promise().done(fn);
3460
3461		return this;
3462	};
3463
3464	jQuery.extend({
3465
3466		// Is the DOM ready to be used? Set to true once it occurs.
3467		isReady: false,
3468
3469		// A counter to track how many items to wait for before
3470		// the ready event fires. See #6781
3471		readyWait: 1,
3472
3473		// Hold (or release) the ready event
3474		holdReady: function (hold) {
3475			if (hold) {
3476				jQuery.readyWait++;
3477			} else {
3478				jQuery.ready(true);
3479			}
3480		},
3481
3482		// Handle when the DOM is ready
3483		ready: function (wait) {
3484
3485			// Abort if there are pending holds or we're already ready
3486			if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
3487				return;
3488			}
3489
3490			// Remember that the DOM is ready
3491			jQuery.isReady = true;
3492
3493			// If a normal DOM Ready event fired, decrement, and wait if need be
3494			if (wait !== true && --jQuery.readyWait > 0) {
3495				return;
3496			}
3497
3498			// If there are functions bound, to execute
3499			readyList.resolveWith(document, [jQuery]);
3500
3501			// Trigger any bound ready events
3502			if (jQuery.fn.triggerHandler) {
3503				jQuery(document).triggerHandler("ready");
3504				jQuery(document).off("ready");
3505			}
3506		}
3507	});
3508
3509	/**
3510  * Clean-up method for dom ready events
3511  */
3512	function detach() {
3513		if (document.addEventListener) {
3514			document.removeEventListener("DOMContentLoaded", completed);
3515			window.removeEventListener("load", completed);
3516		} else {
3517			document.detachEvent("onreadystatechange", completed);
3518			window.detachEvent("onload", completed);
3519		}
3520	}
3521
3522	/**
3523  * The ready event handler and self cleanup method
3524  */
3525	function completed() {
3526
3527		// readyState === "complete" is good enough for us to call the dom ready in oldIE
3528		if (document.addEventListener || window.event.type === "load" || document.readyState === "complete") {
3529
3530			detach();
3531			jQuery.ready();
3532		}
3533	}
3534
3535	jQuery.ready.promise = function (obj) {
3536		if (!readyList) {
3537
3538			readyList = jQuery.Deferred();
3539
3540			// Catch cases where $(document).ready() is called
3541			// after the browser event has already occurred.
3542			// Support: IE6-10
3543			// Older IE sometimes signals "interactive" too soon
3544			if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) {
3545
3546				// Handle it asynchronously to allow scripts the opportunity to delay ready
3547				window.setTimeout(jQuery.ready);
3548
3549				// Standards-based browsers support DOMContentLoaded
3550			} else if (document.addEventListener) {
3551
3552				// Use the handy event callback
3553				document.addEventListener("DOMContentLoaded", completed);
3554
3555				// A fallback to window.onload, that will always work
3556				window.addEventListener("load", completed);
3557
3558				// If IE event model is used
3559			} else {
3560
3561				// Ensure firing before onload, maybe late but safe also for iframes
3562				document.attachEvent("onreadystatechange", completed);
3563
3564				// A fallback to window.onload, that will always work
3565				window.attachEvent("onload", completed);
3566
3567				// If IE and not a frame
3568				// continually check to see if the document is ready
3569				var top = false;
3570
3571				try {
3572					top = window.frameElement == null && document.documentElement;
3573				} catch (e) {}
3574
3575				if (top && top.doScroll) {
3576					(function doScrollCheck() {
3577						if (!jQuery.isReady) {
3578
3579							try {
3580
3581								// Use the trick by Diego Perini
3582								// http://javascript.nwbox.com/IEContentLoaded/
3583								top.doScroll("left");
3584							} catch (e) {
3585								return window.setTimeout(doScrollCheck, 50);
3586							}
3587
3588							// detach all dom ready events
3589							detach();
3590
3591							// and execute any waiting functions
3592							jQuery.ready();
3593						}
3594					})();
3595				}
3596			}
3597		}
3598		return readyList.promise(obj);
3599	};
3600
3601	// Kick off the DOM ready check even if the user does not
3602	jQuery.ready.promise();
3603
3604	// Support: IE<9
3605	// Iteration over object's inherited properties before its own
3606	var i;
3607	for (i in jQuery(support)) {
3608		break;
3609	}
3610	support.ownFirst = i === "0";
3611
3612	// Note: most support tests are defined in their respective modules.
3613	// false until the test is run
3614	support.inlineBlockNeedsLayout = false;
3615
3616	// Execute ASAP in case we need to set body.style.zoom
3617	jQuery(function () {
3618
3619		// Minified: var a,b,c,d
3620		var val, div, body, container;
3621
3622		body = document.getElementsByTagName("body")[0];
3623		if (!body || !body.style) {
3624
3625			// Return for frameset docs that don't have a body
3626			return;
3627		}
3628
3629		// Setup
3630		div = document.createElement("div");
3631		container = document.createElement("div");
3632		container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
3633		body.appendChild(container).appendChild(div);
3634
3635		if (typeof div.style.zoom !== "undefined") {
3636
3637			// Support: IE<8
3638			// Check if natively block-level elements act like inline-block
3639			// elements when setting their display to 'inline' and giving
3640			// them layout
3641			div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
3642
3643			support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
3644			if (val) {
3645
3646				// Prevent IE 6 from affecting layout for positioned elements #11048
3647				// Prevent IE from shrinking the body in IE 7 mode #12869
vendor: 12,463 bytes, lines 3648-4159
3648				// Support: IE<8
3649				body.style.zoom = 1;
3650			}
3651		}
3652
3653		body.removeChild(container);
3654	});
3655
3656	(function () {
3657		var div = document.createElement("div");
3658
3659		// Support: IE<9
3660		support.deleteExpando = true;
3661		try {
3662			delete div.test;
3663		} catch (e) {
3664			support.deleteExpando = false;
3665		}
3666
3667		// Null elements to avoid leaks in IE.
3668		div = null;
3669	})();
3670	var acceptData = function (elem) {
3671		var noData = jQuery.noData[(elem.nodeName + " ").toLowerCase()],
3672		    nodeType = +elem.nodeType || 1;
3673
3674		// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3675		return nodeType !== 1 && nodeType !== 9 ? false :
3676
3677		// Nodes accept data unless otherwise specified; rejection can be conditional
3678		!noData || noData !== true && elem.getAttribute("classid") === noData;
3679	};
3680
3681	var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3682	    rmultiDash = /([A-Z])/g;
3683
3684	function dataAttr(elem, key, data) {
3685
3686		// If nothing was found internally, try to fetch any
3687		// data from the HTML5 data-* attribute
3688		if (data === undefined && elem.nodeType === 1) {
3689
3690			var name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();
3691
3692			data = elem.getAttribute(name);
3693
3694			if (typeof data === "string") {
3695				try {
3696					data = data === "true" ? true : data === "false" ? false : data === "null" ? null :
3697
3698					// Only convert to a number if it doesn't change the string
3699					+data + "" === data ? +data : rbrace.test(data) ? jQuery.parseJSON(data) : data;
3700				} catch (e) {}
3701
3702				// Make sure we set the data so it isn't changed later
3703				jQuery.data(elem, key, data);
3704			} else {
3705				data = undefined;
3706			}
3707		}
3708
3709		return data;
3710	}
3711
3712	// checks a cache object for emptiness
3713	function isEmptyDataObject(obj) {
3714		var name;
3715		for (name in obj) {
3716
3717			// if the public data object is empty, the private is still empty
3718			if (name === "data" && jQuery.isEmptyObject(obj[name])) {
3719				continue;
3720			}
3721			if (name !== "toJSON") {
3722				return false;
3723			}
3724		}
3725
3726		return true;
3727	}
3728
3729	function internalData(elem, name, data, pvt /* Internal Use Only */) {
3730		if (!acceptData(elem)) {
3731			return;
3732		}
3733
3734		var ret,
3735		    thisCache,
3736		    internalKey = jQuery.expando,
3737
3738
3739		// We have to handle DOM nodes and JS objects differently because IE6-7
3740		// can't GC object references properly across the DOM-JS boundary
3741		isNode = elem.nodeType,
3742
3743
3744		// Only DOM nodes need the global jQuery cache; JS object data is
3745		// attached directly to the object so GC can occur automatically
3746		cache = isNode ? jQuery.cache : elem,
3747
3748
3749		// Only defining an ID for JS objects if its cache already exists allows
3750		// the code to shortcut on the same path as a DOM node with no cache
3751		id = isNode ? elem[internalKey] : elem[internalKey] && internalKey;
3752
3753		// Avoid doing any more work than we need to when trying to get data on an
3754		// object that has no data at all
3755		if ((!id || !cache[id] || !pvt && !cache[id].data) && data === undefined && typeof name === "string") {
3756			return;
3757		}
3758
3759		if (!id) {
3760
3761			// Only DOM nodes need a new unique ID for each element since their data
3762			// ends up in the global cache
3763			if (isNode) {
3764				id = elem[internalKey] = deletedIds.pop() || jQuery.guid++;
3765			} else {
3766				id = internalKey;
3767			}
3768		}
3769
3770		if (!cache[id]) {
3771
3772			// Avoid exposing jQuery metadata on plain JS objects when the object
3773			// is serialized using JSON.stringify
3774			cache[id] = isNode ? {} : { toJSON: jQuery.noop };
3775		}
3776
3777		// An object can be passed to jQuery.data instead of a key/value pair; this gets
3778		// shallow copied over onto the existing cache
3779		if (typeof name === "object" || typeof name === "function") {
3780			if (pvt) {
3781				cache[id] = jQuery.extend(cache[id], name);
3782			} else {
3783				cache[id].data = jQuery.extend(cache[id].data, name);
3784			}
3785		}
3786
3787		thisCache = cache[id];
3788
3789		// jQuery data() is stored in a separate object inside the object's internal data
3790		// cache in order to avoid key collisions between internal data and user-defined
3791		// data.
3792		if (!pvt) {
3793			if (!thisCache.data) {
3794				thisCache.data = {};
3795			}
3796
3797			thisCache = thisCache.data;
3798		}
3799
3800		if (data !== undefined) {
3801			thisCache[jQuery.camelCase(name)] = data;
3802		}
3803
3804		// Check for both converted-to-camel and non-converted data property names
3805		// If a data property was specified
3806		if (typeof name === "string") {
3807
3808			// First Try to find as-is property data
3809			ret = thisCache[name];
3810
3811			// Test for null|undefined property data
3812			if (ret == null) {
3813
3814				// Try to find the camelCased property
3815				ret = thisCache[jQuery.camelCase(name)];
3816			}
3817		} else {
3818			ret = thisCache;
3819		}
3820
3821		return ret;
3822	}
3823
3824	function internalRemoveData(elem, name, pvt) {
3825		if (!acceptData(elem)) {
3826			return;
3827		}
3828
3829		var thisCache,
3830		    i,
3831		    isNode = elem.nodeType,
3832
3833
3834		// See jQuery.data for more information
3835		cache = isNode ? jQuery.cache : elem,
3836		    id = isNode ? elem[jQuery.expando] : jQuery.expando;
3837
3838		// If there is already no cache entry for this object, there is no
3839		// purpose in continuing
3840		if (!cache[id]) {
3841			return;
3842		}
3843
3844		if (name) {
3845
3846			thisCache = pvt ? cache[id] : cache[id].data;
3847
3848			if (thisCache) {
3849
3850				// Support array or space separated string names for data keys
3851				if (!jQuery.isArray(name)) {
3852
3853					// try the string as a key before any manipulation
3854					if (name in thisCache) {
3855						name = [name];
3856					} else {
3857
3858						// split the camel cased version by spaces unless a key with the spaces exists
3859						name = jQuery.camelCase(name);
3860						if (name in thisCache) {
3861							name = [name];
3862						} else {
3863							name = name.split(" ");
3864						}
3865					}
3866				} else {
3867
3868					// If "name" is an array of keys...
3869					// When data is initially created, via ("key", "val") signature,
3870					// keys will be converted to camelCase.
3871					// Since there is no way to tell _how_ a key was added, remove
3872					// both plain key and camelCase key. #12786
3873					// This will only penalize the array argument path.
3874					name = name.concat(jQuery.map(name, jQuery.camelCase));
3875				}
3876
3877				i = name.length;
3878				while (i--) {
3879					delete thisCache[name[i]];
3880				}
3881
3882				// If there is no data left in the cache, we want to continue
3883				// and let the cache object itself get destroyed
3884				if (pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache)) {
3885					return;
3886				}
3887			}
3888		}
3889
3890		// See jQuery.data for more information
3891		if (!pvt) {
3892			delete cache[id].data;
3893
3894			// Don't destroy the parent cache unless the internal data object
3895			// had been the only thing left in it
3896			if (!isEmptyDataObject(cache[id])) {
3897				return;
3898			}
3899		}
3900
3901		// Destroy the cache
3902		if (isNode) {
3903			jQuery.cleanData([elem], true);
3904
3905			// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
3906			/* jshint eqeqeq: false */
3907		} else if (support.deleteExpando || cache != cache.window) {
3908			/* jshint eqeqeq: true */
3909			delete cache[id];
3910
3911			// When all else fails, undefined
3912		} else {
3913			cache[id] = undefined;
3914		}
3915	}
3916
3917	jQuery.extend({
3918		cache: {},
3919
3920		// The following elements (space-suffixed to avoid Object.prototype collisions)
3921		// throw uncatchable exceptions if you attempt to set expando properties
3922		noData: {
3923			"applet ": true,
3924			"embed ": true,
3925
3926			// ...but Flash objects (which have this classid) *can* handle expandos
3927			"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
3928		},
3929
3930		hasData: function (elem) {
3931			elem = elem.nodeType ? jQuery.cache[elem[jQuery.expando]] : elem[jQuery.expando];
3932			return !!elem && !isEmptyDataObject(elem);
3933		},
3934
3935		data: function (elem, name, data) {
3936			return internalData(elem, name, data);
3937		},
3938
3939		removeData: function (elem, name) {
3940			return internalRemoveData(elem, name);
3941		},
3942
3943		// For internal use only.
3944		_data: function (elem, name, data) {
3945			return internalData(elem, name, data, true);
3946		},
3947
3948		_removeData: function (elem, name) {
3949			return internalRemoveData(elem, name, true);
3950		}
3951	});
3952
3953	jQuery.fn.extend({
3954		data: function (key, value) {
3955			var i,
3956			    name,
3957			    data,
3958			    elem = this[0],
3959			    attrs = elem && elem.attributes;
3960
3961			// Special expections of .data basically thwart jQuery.access,
3962			// so implement the relevant behavior ourselves
3963
3964			// Gets all values
3965			if (key === undefined) {
3966				if (this.length) {
3967					data = jQuery.data(elem);
3968
3969					if (elem.nodeType === 1 && !jQuery._data(elem, "parsedAttrs")) {
3970						i = attrs.length;
3971						while (i--) {
3972
3973							// Support: IE11+
3974							// The attrs elements can be null (#14894)
3975							if (attrs[i]) {
3976								name = attrs[i].name;
3977								if (name.indexOf("data-") === 0) {
3978									name = jQuery.camelCase(name.slice(5));
3979									dataAttr(elem, name, data[name]);
3980								}
3981							}
3982						}
3983						jQuery._data(elem, "parsedAttrs", true);
3984					}
3985				}
3986
3987				return data;
3988			}
3989
3990			// Sets multiple values
3991			if (typeof key === "object") {
3992				return this.each(function () {
3993					jQuery.data(this, key);
3994				});
3995			}
3996
3997			return arguments.length > 1 ?
3998
3999			// Sets one value
4000			this.each(function () {
4001				jQuery.data(this, key, value);
4002			}) :
4003
4004			// Gets one value
4005			// Try to fetch any internally stored data first
4006			elem ? dataAttr(elem, key, jQuery.data(elem, key)) : undefined;
4007		},
4008
4009		removeData: function (key) {
4010			return this.each(function () {
4011				jQuery.removeData(this, key);
4012			});
4013		}
4014	});
4015
4016	jQuery.extend({
4017		queue: function (elem, type, data) {
4018			var queue;
4019
4020			if (elem) {
4021				type = (type || "fx") + "queue";
4022				queue = jQuery._data(elem, type);
4023
4024				// Speed up dequeue by getting out quickly if this is just a lookup
4025				if (data) {
4026					if (!queue || jQuery.isArray(data)) {
4027						queue = jQuery._data(elem, type, jQuery.makeArray(data));
4028					} else {
4029						queue.push(data);
4030					}
4031				}
4032				return queue || [];
4033			}
4034		},
4035
4036		dequeue: function (elem, type) {
4037			type = type || "fx";
4038
4039			var queue = jQuery.queue(elem, type),
4040			    startLength = queue.length,
4041			    fn = queue.shift(),
4042			    hooks = jQuery._queueHooks(elem, type),
4043			    next = function () {
4044				jQuery.dequeue(elem, type);
4045			};
4046
4047			// If the fx queue is dequeued, always remove the progress sentinel
4048			if (fn === "inprogress") {
4049				fn = queue.shift();
4050				startLength--;
4051			}
4052
4053			if (fn) {
4054
4055				// Add a progress sentinel to prevent the fx queue from being
4056				// automatically dequeued
4057				if (type === "fx") {
4058					queue.unshift("inprogress");
4059				}
4060
4061				// clear up the last queue stop function
4062				delete hooks.stop;
4063				fn.call(elem, next, hooks);
4064			}
4065
4066			if (!startLength && hooks) {
4067				hooks.empty.fire();
4068			}
4069		},
4070
4071		// not intended for public consumption - generates a queueHooks object,
4072		// or returns the current one
4073		_queueHooks: function (elem, type) {
4074			var key = type + "queueHooks";
4075			return jQuery._data(elem, key) || jQuery._data(elem, key, {
4076				empty: jQuery.Callbacks("once memory").add(function () {
4077					jQuery._removeData(elem, type + "queue");
4078					jQuery._removeData(elem, key);
4079				})
4080			});
4081		}
4082	});
4083
4084	jQuery.fn.extend({
4085		queue: function (type, data) {
4086			var setter = 2;
4087
4088			if (typeof type !== "string") {
4089				data = type;
4090				type = "fx";
4091				setter--;
4092			}
4093
4094			if (arguments.length < setter) {
4095				return jQuery.queue(this[0], type);
4096			}
4097
4098			return data === undefined ? this : this.each(function () {
4099				var queue = jQuery.queue(this, type, data);
4100
4101				// ensure a hooks for this queue
4102				jQuery._queueHooks(this, type);
4103
4104				if (type === "fx" && queue[0] !== "inprogress") {
4105					jQuery.dequeue(this, type);
4106				}
4107			});
4108		},
4109		dequeue: function (type) {
4110			return this.each(function () {
4111				jQuery.dequeue(this, type);
4112			});
4113		},
4114		clearQueue: function (type) {
4115			return this.queue(type || "fx", []);
4116		},
4117
4118		// Get a promise resolved when queues of a certain type
4119		// are emptied (fx is the type by default)
4120		promise: function (type, obj) {
4121			var tmp,
4122			    count = 1,
4123			    defer = jQuery.Deferred(),
4124			    elements = this,
4125			    i = this.length,
4126			    resolve = function () {
4127				if (! --count) {
4128					defer.resolveWith(elements, [elements]);
4129				}
4130			};
4131
4132			if (typeof type !== "string") {
4133				obj = type;
4134				type = undefined;
4135			}
4136			type = type || "fx";
4137
4138			while (i--) {
4139				tmp = jQuery._data(elements[i], type + "queueHooks");
4140				if (tmp && tmp.empty) {
4141					count++;
4142					tmp.empty.add(resolve);
4143				}
4144			}
4145			resolve();
4146			return defer.promise(obj);
4147		}
4148	});
4149
4150	(function () {
4151		var shrinkWrapBlocksVal;
4152
4153		support.shrinkWrapBlocks = function () {
4154			if (shrinkWrapBlocksVal != null) {
4155				return shrinkWrapBlocksVal;
4156			}
4157
4158			// Will be changed later if needed.
4159			shrinkWrapBlocksVal = false;
4160
4161			// Minified: var b,c,d
4162			var div, body, container;
4163
4164			body = document.getElementsByTagName("body")[0];
4165			if (!body || !body.style) {
4166
4167				// Test fired too early or in an unsupported environment, exit.
4168				return;
4169			}
4170
4171			// Setup
4172			div = document.createElement("div");
4173			container = document.createElement("div");
4174			container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
4175			body.appendChild(container).appendChild(div);
4176
4177			// Support: IE6
4178			// Check if elements with layout shrink-wrap their children
4179			if (typeof div.style.zoom !== "undefined") {
4180
4181				// Reset CSS: box-sizing; display; margin; border
4182				div.style.cssText =
4183
4184				// Support: Firefox<29, Android 2.3
4185				// Vendor-prefix box-sizing
4186				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + "box-sizing:content-box;display:block;margin:0;border:0;" + "padding:1px;width:1px;zoom:1";
4187				div.appendChild(document.createElement("div")).style.width = "5px";
4188				shrinkWrapBlocksVal = div.offsetWidth !== 3;
4189			}
4190
4191			body.removeChild(container);
4192
4193			return shrinkWrapBlocksVal;
4194		};
4195	})();
4196	var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;
4197
4198	var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");
4199
4200	var cssExpand = ["Top", "Right", "Bottom", "Left"];
4201
4202	var isHidden = function (elem, el) {
4203
4204		// isHidden might be called from jQuery#filter function;
4205		// in that case, element will be second argument
4206		elem = el || elem;
4207		return jQuery.css(elem, "display") === "none" || !jQuery.contains(elem.ownerDocument, elem);
4208	};
4209
4210	function adjustCSS(elem, prop, valueParts, tween) {
4211		var adjusted,
4212		    scale = 1,
4213		    maxIterations = 20,
4214		    currentValue = tween ? function () {
4215			return tween.cur();
4216		} : function () {
4217			return jQuery.css(elem, prop, "");
4218		},
4219		    initial = currentValue(),
4220		    unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
4221
4222
4223		// Starting value computation is required for potential unit mismatches
4224		initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop));
4225
4226		if (initialInUnit && initialInUnit[3] !== unit) {
4227
4228			// Trust units reported by jQuery.css
4229			unit = unit || initialInUnit[3];
4230
4231			// Make sure we update the tween properties later on
4232			valueParts = valueParts || [];
4233
4234			// Iteratively approximate from a nonzero starting point
4235			initialInUnit = +initial || 1;
4236
4237			do {
4238
4239				// If previous iteration zeroed out, double until we get *something*.
4240				// Use string for doubling so we don't accidentally see scale as unchanged below
4241				scale = scale || ".5";
4242
4243				// Adjust and apply
4244				initialInUnit = initialInUnit / scale;
4245				jQuery.style(elem, prop, initialInUnit + unit);
4246
4247				// Update scale, tolerating zero or NaN from tween.cur()
4248				// Break the loop if scale is unchanged or perfect, or if we've just had enough.
4249			} while (scale !== (scale = currentValue() / initial) && scale !== 1 && --maxIterations);
4250		}
4251
4252		if (valueParts) {
4253			initialInUnit = +initialInUnit || +initial || 0;
4254
4255			// Apply relative offset (+=/-=) if specified
4256			adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2];
4257			if (tween) {
4258				tween.unit = unit;
4259				tween.start = initialInUnit;
4260				tween.end = adjusted;
4261			}
4262		}
4263		return adjusted;
4264	}
4265
4266	// Multifunctional method to get and set values of a collection
4267	// The value/s can optionally be executed if it's a function
4268	var access = function (elems, fn, key, value, chainable, emptyGet, raw) {
4269		var i = 0,
4270		    length = elems.length,
4271		    bulk = key == null;
4272
4273		// Sets many values
4274		if (jQuery.type(key) === "object") {
4275			chainable = true;
4276			for (i in key) {
4277				access(elems, fn, i, key[i], true, emptyGet, raw);
4278			}
4279
4280			// Sets one value
4281		} else if (value !== undefined) {
4282			chainable = true;
4283
4284			if (!jQuery.isFunction(value)) {
4285				raw = true;
4286			}
4287
4288			if (bulk) {
4289
4290				// Bulk operations run against the entire set
4291				if (raw) {
4292					fn.call(elems, value);
4293					fn = null;
4294
4295					// ...except when executing function values
4296				} else {
4297					bulk = fn;
4298					fn = function (elem, key, value) {
4299						return bulk.call(jQuery(elem), value);
4300					};
4301				}
4302			}
4303
4304			if (fn) {
4305				for (; i < length; i++) {
4306					fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
4307				}
4308			}
4309		}
4310
4311		return chainable ? elems :
4312
4313		// Gets
4314		bulk ? fn.call(elems) : length ? fn(elems[0], key) : emptyGet;
4315	};
4316	var rcheckableType = /^(?:checkbox|radio)$/i;
4317
4318	var rtagName = /<([\w:-]+)/;
4319
4320	var rscriptType = /^$|\/(?:java|ecma)script/i;
4321
4322	var rleadingWhitespace = /^\s+/;
4323
4324	var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" + "details|dialog|figcaption|figure|footer|header|hgroup|main|" + "mark|meter|nav|output|picture|progress|section|summary|template|time|video";
4325
4326	function createSafeFragment(document) {
4327		var list = nodeNames.split("|"),
4328		    safeFrag = document.createDocumentFragment();
4329
4330		if (safeFrag.createElement) {
4331			while (list.length) {
4332				safeFrag.createElement(list.pop());
4333			}
4334		}
4335		return safeFrag;
4336	}
4337
4338	(function () {
4339		var div = document.createElement("div"),
4340		    fragment = document.createDocumentFragment(),
4341		    input = document.createElement("input");
4342
4343		// Setup
4344		div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
4345
4346		// IE strips leading whitespace when .innerHTML is used
4347		support.leadingWhitespace = div.firstChild.nodeType === 3;
4348
4349		// Make sure that tbody elements aren't automatically inserted
4350		// IE will insert them into empty tables
4351		support.tbody = !div.getElementsByTagName("tbody").length;
4352
4353		// Make sure that link elements get serialized correctly by innerHTML
4354		// This requires a wrapper element in IE
4355		support.htmlSerialize = !!div.getElementsByTagName("link").length;
4356
4357		// Makes sure cloning an html5 element does not cause problems
4358		// Where outerHTML is undefined, this still works
4359		support.html5Clone = document.createElement("nav").cloneNode(true).outerHTML !== "<:nav></:nav>";
4360
4361		// Check if a disconnected checkbox will retain its checked
4362		// value of true after appended to the DOM (IE6/7)
4363		input.type = "checkbox";
4364		input.checked = true;
4365		fragment.appendChild(input);
4366		support.appendChecked = input.checked;
4367
4368		// Make sure textarea (and checkbox) defaultValue is properly cloned
4369		// Support: IE6-IE11+
4370		div.innerHTML = "<textarea>x</textarea>";
4371		support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
4372
4373		// #11217 - WebKit loses check when the name is after the checked attribute
4374		fragment.appendChild(div);
4375
4376		// Support: Windows Web Apps (WWA)
4377		// `name` and `type` must use .setAttribute for WWA (#14901)
4378		input = document.createElement("input");
4379		input.setAttribute("type", "radio");
4380		input.setAttribute("checked", "checked");
4381		input.setAttribute("name", "t");
4382
4383		div.appendChild(input);
4384
4385		// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4386		// old WebKit doesn't clone checked state correctly in fragments
4387		support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;
4388
4389		// Support: IE<9
4390		// Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
4391		support.noCloneEvent = !!div.addEventListener;
4392
4393		// Support: IE<9
4394		// Since attributes and properties are the same in IE,
4395		// cleanData must set properties to undefined rather than use removeAttribute
4396		div[jQuery.expando] = 1;
4397		support.attributes = !div.getAttribute(jQuery.expando);
4398	})();
4399
4400	// We have to close these tags to support XHTML (#13200)
4401	var wrapMap = {
4402		option: [1, "<select multiple='multiple'>", "</select>"],
4403		legend: [1, "<fieldset>", "</fieldset>"],
4404		area: [1, "<map>", "</map>"],
4405
4406		// Support: IE8
4407		param: [1, "<object>", "</object>"],
4408		thead: [1, "<table>", "</table>"],
4409		tr: [2, "<table><tbody>", "</tbody></table>"],
4410		col: [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"],
4411		td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
4412
4413		// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
4414		// unless wrapped in a div with non-breaking characters in front of it.
4415		_default: support.htmlSerialize ? [0, "", ""] : [1, "X<div>", "</div>"]
4416	};
4417
4418	// Support: IE8-IE9
4419	wrapMap.optgroup = wrapMap.option;
4420
4421	wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4422	wrapMap.th = wrapMap.td;
4423
4424	function getAll(context, tag) {
4425		var elems,
4426		    elem,
4427		    i = 0,
4428		    found = typeof context.getElementsByTagName !== "undefined" ? context.getElementsByTagName(tag || "*") : typeof context.querySelectorAll !== "undefined" ? context.querySelectorAll(tag || "*") : undefined;
4429
4430		if (!found) {
4431			for (found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++) {
4432				if (!tag || jQuery.nodeName(elem, tag)) {
4433					found.push(elem);
4434				} else {
4435					jQuery.merge(found, getAll(elem, tag));
4436				}
4437			}
4438		}
4439
4440		return tag === undefined || tag && jQuery.nodeName(context, tag) ? jQuery.merge([context], found) : found;
4441	}
4442
4443	// Mark scripts as having already been evaluated
4444	function setGlobalEval(elems, refElements) {
4445		var elem,
4446		    i = 0;
4447		for (; (elem = elems[i]) != null; i++) {
4448			jQuery._data(elem, "globalEval", !refElements || jQuery._data(refElements[i], "globalEval"));
4449		}
4450	}
4451
4452	var rhtml = /<|&#?\w+;/,
4453	    rtbody = /<tbody/i;
4454
4455	function fixDefaultChecked(elem) {
4456		if (rcheckableType.test(elem.type)) {
4457			elem.defaultChecked = elem.checked;
4458		}
4459	}
4460
4461	function buildFragment(elems, context, scripts, selection, ignored) {
4462		var j,
4463		    elem,
4464		    contains,
4465		    tmp,
4466		    tag,
4467		    tbody,
4468		    wrap,
4469		    l = elems.length,
4470
4471
4472		// Ensure a safe fragment
4473		safe = createSafeFragment(context),
4474		    nodes = [],
4475		    i = 0;
4476
4477		for (; i < l; i++) {
4478			elem = elems[i];
4479
4480			if (elem || elem === 0) {
4481
4482				// Add nodes directly
4483				if (jQuery.type(elem) === "object") {
4484					jQuery.merge(nodes, elem.nodeType ? [elem] : elem);
4485
4486					// Convert non-html into a text node
4487				} else if (!rhtml.test(elem)) {
4488					nodes.push(context.createTextNode(elem));
4489
4490					// Convert html into DOM nodes
4491				} else {
4492					tmp = tmp || safe.appendChild(context.createElement("div"));
4493
4494					// Deserialize a standard representation
4495					tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
4496					wrap = wrapMap[tag] || wrapMap._default;
4497
4498					tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];
4499
4500					// Descend through wrappers to the right content
4501					j = wrap[0];
4502					while (j--) {
4503						tmp = tmp.lastChild;
4504					}
4505
4506					// Manually add leading whitespace removed by IE
4507					if (!support.leadingWhitespace && rleadingWhitespace.test(elem)) {
4508						nodes.push(context.createTextNode(rleadingWhitespace.exec(elem)[0]));
4509					}
4510
4511					// Remove IE's autoinserted <tbody> from table fragments
4512					if (!support.tbody) {
4513
4514						// String was a <table>, *may* have spurious <tbody>
4515						elem = tag === "table" && !rtbody.test(elem) ? tmp.firstChild :
4516
4517						// String was a bare <thead> or <tfoot>
4518						wrap[1] === "<table>" && !rtbody.test(elem) ? tmp : 0;
4519
4520						j = elem && elem.childNodes.length;
4521						while (j--) {
4522							if (jQuery.nodeName(tbody = elem.childNodes[j], "tbody") && !tbody.childNodes.length) {
4523
4524								elem.removeChild(tbody);
4525							}
4526						}
4527					}
4528
4529					jQuery.merge(nodes, tmp.childNodes);
4530
4531					// Fix #12392 for WebKit and IE > 9
4532					tmp.textContent = "";
4533
4534					// Fix #12392 for oldIE
4535					while (tmp.firstChild) {
4536						tmp.removeChild(tmp.firstChild);
4537					}
4538
4539					// Remember the top-level container for proper cleanup
4540					tmp = safe.lastChild;
4541				}
4542			}
4543		}
4544
4545		// Fix #11356: Clear elements from fragment
4546		if (tmp) {
4547			safe.removeChild(tmp);
4548		}
4549
4550		// Reset defaultChecked for any radios and checkboxes
4551		// about to be appended to the DOM in IE 6/7 (#8060)
4552		if (!support.appendChecked) {
4553			jQuery.grep(getAll(nodes, "input"), fixDefaultChecked);
4554		}
4555
4556		i = 0;
4557		while (elem = nodes[i++]) {
4558
4559			// Skip elements already in the context collection (trac-4087)
4560			if (selection && jQuery.inArray(elem, selection) > -1) {
4561				if (ignored) {
4562					ignored.push(elem);
4563				}
4564
4565				continue;
4566			}
4567
4568			contains = jQuery.contains(elem.ownerDocument, elem);
4569
4570			// Append to fragment
4571			tmp = getAll(safe.appendChild(elem), "script");
4572
4573			// Preserve script evaluation history
4574			if (contains) {
4575				setGlobalEval(tmp);
4576			}
4577
4578			// Capture executables
4579			if (scripts) {
4580				j = 0;
4581				while (elem = tmp[j++]) {
4582					if (rscriptType.test(elem.type || "")) {
4583						scripts.push(elem);
4584					}
4585				}
4586			}
4587		}
4588
4589		tmp = null;
4590
4591		return safe;
4592	}
4593
4594	(function () {
4595		var i,
4596		    eventName,
4597		    div = document.createElement("div");
4598
4599		// Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
4600		for (i in { submit: true, change: true, focusin: true }) {
4601			eventName = "on" + i;
4602
vendor: 28,100 bytes, lines 4603-5571
4603			if (!(support[i] = eventName in window)) {
4604
4605				// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4606				div.setAttribute(eventName, "t");
4607				support[i] = div.attributes[eventName].expando === false;
4608			}
4609		}
4610
4611		// Null elements to avoid leaks in IE.
4612		div = null;
4613	})();
4614
4615	var rformElems = /^(?:input|select|textarea)$/i,
4616	    rkeyEvent = /^key/,
4617	    rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4618	    rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4619	    rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4620
4621	function returnTrue() {
4622		return true;
4623	}
4624
4625	function returnFalse() {
4626		return false;
4627	}
4628
4629	// Support: IE9
4630	// See #13393 for more info
4631	function safeActiveElement() {
4632		try {
4633			return document.activeElement;
4634		} catch (err) {}
4635	}
4636
4637	function on(elem, types, selector, data, fn, one) {
4638		var origFn, type;
4639
4640		// Types can be a map of types/handlers
4641		if (typeof types === "object") {
4642
4643			// ( types-Object, selector, data )
4644			if (typeof selector !== "string") {
4645
4646				// ( types-Object, data )
4647				data = data || selector;
4648				selector = undefined;
4649			}
4650			for (type in types) {
4651				on(elem, type, selector, data, types[type], one);
4652			}
4653			return elem;
4654		}
4655
4656		if (data == null && fn == null) {
4657
4658			// ( types, fn )
4659			fn = selector;
4660			data = selector = undefined;
4661		} else if (fn == null) {
4662			if (typeof selector === "string") {
4663
4664				// ( types, selector, fn )
4665				fn = data;
4666				data = undefined;
4667			} else {
4668
4669				// ( types, data, fn )
4670				fn = data;
4671				data = selector;
4672				selector = undefined;
4673			}
4674		}
4675		if (fn === false) {
4676			fn = returnFalse;
4677		} else if (!fn) {
4678			return elem;
4679		}
4680
4681		if (one === 1) {
4682			origFn = fn;
4683			fn = function (event) {
4684
4685				// Can use an empty set, since event contains the info
4686				jQuery().off(event);
4687				return origFn.apply(this, arguments);
4688			};
4689
4690			// Use same guid so caller can remove using origFn
4691			fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
4692		}
4693		return elem.each(function () {
4694			jQuery.event.add(this, types, fn, data, selector);
4695		});
4696	}
4697
4698	/*
4699  * Helper functions for managing events -- not part of the public interface.
4700  * Props to Dean Edwards' addEvent library for many of the ideas.
4701  */
4702	jQuery.event = {
4703
4704		global: {},
4705
4706		add: function (elem, types, handler, data, selector) {
4707			var tmp,
4708			    events,
4709			    t,
4710			    handleObjIn,
4711			    special,
4712			    eventHandle,
4713			    handleObj,
4714			    handlers,
4715			    type,
4716			    namespaces,
4717			    origType,
4718			    elemData = jQuery._data(elem);
4719
4720			// Don't attach events to noData or text/comment nodes (but allow plain objects)
4721			if (!elemData) {
4722				return;
4723			}
4724
4725			// Caller can pass in an object of custom data in lieu of the handler
4726			if (handler.handler) {
4727				handleObjIn = handler;
4728				handler = handleObjIn.handler;
4729				selector = handleObjIn.selector;
4730			}
4731
4732			// Make sure that the handler has a unique ID, used to find/remove it later
4733			if (!handler.guid) {
4734				handler.guid = jQuery.guid++;
4735			}
4736
4737			// Init the element's event structure and main handler, if this is the first
4738			if (!(events = elemData.events)) {
4739				events = elemData.events = {};
4740			}
4741			if (!(eventHandle = elemData.handle)) {
4742				eventHandle = elemData.handle = function (e) {
4743
4744					// Discard the second event of a jQuery.event.trigger() and
4745					// when an event is called after a page has unloaded
4746					return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply(eventHandle.elem, arguments) : undefined;
4747				};
4748
4749				// Add elem as a property of the handle fn to prevent a memory leak
4750				// with IE non-native events
4751				eventHandle.elem = elem;
4752			}
4753
4754			// Handle multiple events separated by a space
4755			types = (types || "").match(rnotwhite) || [""];
4756			t = types.length;
4757			while (t--) {
4758				tmp = rtypenamespace.exec(types[t]) || [];
4759				type = origType = tmp[1];
4760				namespaces = (tmp[2] || "").split(".").sort();
4761
4762				// There *must* be a type, no attaching namespace-only handlers
4763				if (!type) {
4764					continue;
4765				}
4766
4767				// If event changes its type, use the special event handlers for the changed type
4768				special = jQuery.event.special[type] || {};
4769
4770				// If selector defined, determine special event api type, otherwise given type
4771				type = (selector ? special.delegateType : special.bindType) || type;
4772
4773				// Update special based on newly reset type
4774				special = jQuery.event.special[type] || {};
4775
4776				// handleObj is passed to all event handlers
4777				handleObj = jQuery.extend({
4778					type: type,
4779					origType: origType,
4780					data: data,
4781					handler: handler,
4782					guid: handler.guid,
4783					selector: selector,
4784					needsContext: selector && jQuery.expr.match.needsContext.test(selector),
4785					namespace: namespaces.join(".")
4786				}, handleObjIn);
4787
4788				// Init the event handler queue if we're the first
4789				if (!(handlers = events[type])) {
4790					handlers = events[type] = [];
4791					handlers.delegateCount = 0;
4792
4793					// Only use addEventListener/attachEvent if the special events handler returns false
4794					if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
4795
4796						// Bind the global event handler to the element
4797						if (elem.addEventListener) {
4798							elem.addEventListener(type, eventHandle, false);
4799						} else if (elem.attachEvent) {
4800							elem.attachEvent("on" + type, eventHandle);
4801						}
4802					}
4803				}
4804
4805				if (special.add) {
4806					special.add.call(elem, handleObj);
4807
4808					if (!handleObj.handler.guid) {
4809						handleObj.handler.guid = handler.guid;
4810					}
4811				}
4812
4813				// Add to the element's handler list, delegates in front
4814				if (selector) {
4815					handlers.splice(handlers.delegateCount++, 0, handleObj);
4816				} else {
4817					handlers.push(handleObj);
4818				}
4819
4820				// Keep track of which events have ever been used, for event optimization
4821				jQuery.event.global[type] = true;
4822			}
4823
4824			// Nullify elem to prevent memory leaks in IE
4825			elem = null;
4826		},
4827
4828		// Detach an event or set of events from an element
4829		remove: function (elem, types, handler, selector, mappedTypes) {
4830			var j,
4831			    handleObj,
4832			    tmp,
4833			    origCount,
4834			    t,
4835			    events,
4836			    special,
4837			    handlers,
4838			    type,
4839			    namespaces,
4840			    origType,
4841			    elemData = jQuery.hasData(elem) && jQuery._data(elem);
4842
4843			if (!elemData || !(events = elemData.events)) {
4844				return;
4845			}
4846
4847			// Once for each type.namespace in types; type may be omitted
4848			types = (types || "").match(rnotwhite) || [""];
4849			t = types.length;
4850			while (t--) {
4851				tmp = rtypenamespace.exec(types[t]) || [];
4852				type = origType = tmp[1];
4853				namespaces = (tmp[2] || "").split(".").sort();
4854
4855				// Unbind all events (on this namespace, if provided) for the element
4856				if (!type) {
4857					for (type in events) {
4858						jQuery.event.remove(elem, type + types[t], handler, selector, true);
4859					}
4860					continue;
4861				}
4862
4863				special = jQuery.event.special[type] || {};
4864				type = (selector ? special.delegateType : special.bindType) || type;
4865				handlers = events[type] || [];
4866				tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
4867
4868				// Remove matching events
4869				origCount = j = handlers.length;
4870				while (j--) {
4871					handleObj = handlers[j];
4872
4873					if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
4874						handlers.splice(j, 1);
4875
4876						if (handleObj.selector) {
4877							handlers.delegateCount--;
4878						}
4879						if (special.remove) {
4880							special.remove.call(elem, handleObj);
4881						}
4882					}
4883				}
4884
4885				// Remove generic event handler if we removed something and no more handlers exist
4886				// (avoids potential for endless recursion during removal of special event handlers)
4887				if (origCount && !handlers.length) {
4888					if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
4889
4890						jQuery.removeEvent(elem, type, elemData.handle);
4891					}
4892
4893					delete events[type];
4894				}
4895			}
4896
4897			// Remove the expando if it's no longer used
4898			if (jQuery.isEmptyObject(events)) {
4899				delete elemData.handle;
4900
4901				// removeData also checks for emptiness and clears the expando if empty
4902				// so use it instead of delete
4903				jQuery._removeData(elem, "events");
4904			}
4905		},
4906
4907		trigger: function (event, data, elem, onlyHandlers) {
4908			var handle,
4909			    ontype,
4910			    cur,
4911			    bubbleType,
4912			    special,
4913			    tmp,
4914			    i,
4915			    eventPath = [elem || document],
4916			    type = hasOwn.call(event, "type") ? event.type : event,
4917			    namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
4918
4919			cur = tmp = elem = elem || document;
4920
4921			// Don't do events on text and comment nodes
4922			if (elem.nodeType === 3 || elem.nodeType === 8) {
4923				return;
4924			}
4925
4926			// focus/blur morphs to focusin/out; ensure we're not firing them right now
4927			if (rfocusMorph.test(type + jQuery.event.triggered)) {
4928				return;
4929			}
4930
4931			if (type.indexOf(".") > -1) {
4932
4933				// Namespaced trigger; create a regexp to match event type in handle()
4934				namespaces = type.split(".");
4935				type = namespaces.shift();
4936				namespaces.sort();
4937			}
4938			ontype = type.indexOf(":") < 0 && "on" + type;
4939
4940			// Caller can pass in a jQuery.Event object, Object, or just an event type string
4941			event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === "object" && event);
4942
4943			// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4944			event.isTrigger = onlyHandlers ? 2 : 3;
4945			event.namespace = namespaces.join(".");
4946			event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
4947
4948			// Clean up the event in case it is being reused
4949			event.result = undefined;
4950			if (!event.target) {
4951				event.target = elem;
4952			}
4953
4954			// Clone any incoming data and prepend the event, creating the handler arg list
4955			data = data == null ? [event] : jQuery.makeArray(data, [event]);
4956
4957			// Allow special events to draw outside the lines
4958			special = jQuery.event.special[type] || {};
4959			if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
4960				return;
4961			}
4962
4963			// Determine event propagation path in advance, per W3C events spec (#9951)
4964			// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4965			if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
4966
4967				bubbleType = special.delegateType || type;
4968				if (!rfocusMorph.test(bubbleType + type)) {
4969					cur = cur.parentNode;
4970				}
4971				for (; cur; cur = cur.parentNode) {
4972					eventPath.push(cur);
4973					tmp = cur;
4974				}
4975
4976				// Only add window if we got to document (e.g., not plain obj or detached DOM)
4977				if (tmp === (elem.ownerDocument || document)) {
4978					eventPath.push(tmp.defaultView || tmp.parentWindow || window);
4979				}
4980			}
4981
4982			// Fire handlers on the event path
4983			i = 0;
4984			while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
4985
4986				event.type = i > 1 ? bubbleType : special.bindType || type;
4987
4988				// jQuery handler
4989				handle = (jQuery._data(cur, "events") || {})[event.type] && jQuery._data(cur, "handle");
4990
4991				if (handle) {
4992					handle.apply(cur, data);
4993				}
4994
4995				// Native handler
4996				handle = ontype && cur[ontype];
4997				if (handle && handle.apply && acceptData(cur)) {
4998					event.result = handle.apply(cur, data);
4999					if (event.result === false) {
5000						event.preventDefault();
5001					}
5002				}
5003			}
5004			event.type = type;
5005
5006			// If nobody prevented the default action, do it now
5007			if (!onlyHandlers && !event.isDefaultPrevented()) {
5008
5009				if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) {
5010
5011					// Call a native DOM method on the target with the same name name as the event.
5012					// Can't use an .isFunction() check here because IE6/7 fails that test.
5013					// Don't do default actions on window, that's where global variables be (#6170)
5014					if (ontype && elem[type] && !jQuery.isWindow(elem)) {
5015
5016						// Don't re-trigger an onFOO event when we call its FOO() method
5017						tmp = elem[ontype];
5018
5019						if (tmp) {
5020							elem[ontype] = null;
5021						}
5022
5023						// Prevent re-triggering of the same event, since we already bubbled it above
5024						jQuery.event.triggered = type;
5025						try {
5026							elem[type]();
5027						} catch (e) {
5028
5029							// IE<9 dies on focus/blur to hidden element (#1486,#12518)
5030							// only reproducible on winXP IE8 native, not IE9 in IE8 mode
5031						}
5032						jQuery.event.triggered = undefined;
5033
5034						if (tmp) {
5035							elem[ontype] = tmp;
5036						}
5037					}
5038				}
5039			}
5040
5041			return event.result;
5042		},
5043
5044		dispatch: function (event) {
5045
5046			// Make a writable jQuery.Event from the native event object
5047			event = jQuery.event.fix(event);
5048
5049			var i,
5050			    j,
5051			    ret,
5052			    matched,
5053			    handleObj,
5054			    handlerQueue = [],
5055			    args = slice.call(arguments),
5056			    handlers = (jQuery._data(this, "events") || {})[event.type] || [],
5057			    special = jQuery.event.special[event.type] || {};
5058
5059			// Use the fix-ed jQuery.Event rather than the (read-only) native event
5060			args[0] = event;
5061			event.delegateTarget = this;
5062
5063			// Call the preDispatch hook for the mapped type, and let it bail if desired
5064			if (special.preDispatch && special.preDispatch.call(this, event) === false) {
5065				return;
5066			}
5067
5068			// Determine handlers
5069			handlerQueue = jQuery.event.handlers.call(this, event, handlers);
5070
5071			// Run delegates first; they may want to stop propagation beneath us
5072			i = 0;
5073			while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
5074				event.currentTarget = matched.elem;
5075
5076				j = 0;
5077				while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
5078
5079					// Triggered event must either 1) have no namespace, or 2) have namespace(s)
5080					// a subset or equal to those in the bound event (both can have no namespace).
5081					if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) {
5082
5083						event.handleObj = handleObj;
5084						event.data = handleObj.data;
5085
5086						ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);
5087
5088						if (ret !== undefined) {
5089							if ((event.result = ret) === false) {
5090								event.preventDefault();
5091								event.stopPropagation();
5092							}
5093						}
5094					}
5095				}
5096			}
5097
5098			// Call the postDispatch hook for the mapped type
5099			if (special.postDispatch) {
5100				special.postDispatch.call(this, event);
5101			}
5102
5103			return event.result;
5104		},
5105
5106		handlers: function (event, handlers) {
5107			var i,
5108			    matches,
5109			    sel,
5110			    handleObj,
5111			    handlerQueue = [],
5112			    delegateCount = handlers.delegateCount,
5113			    cur = event.target;
5114
5115			// Support (at least): Chrome, IE9
5116			// Find delegate handlers
5117			// Black-hole SVG <use> instance trees (#13180)
5118			//
5119			// Support: Firefox<=42+
5120			// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
5121			if (delegateCount && cur.nodeType && (event.type !== "click" || isNaN(event.button) || event.button < 1)) {
5122
5123				/* jshint eqeqeq: false */
5124				for (; cur != this; cur = cur.parentNode || this) {
5125					/* jshint eqeqeq: true */
5126
5127					// Don't check non-elements (#13208)
5128					// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5129					if (cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click")) {
5130						matches = [];
5131						for (i = 0; i < delegateCount; i++) {
5132							handleObj = handlers[i];
5133
5134							// Don't conflict with Object.prototype properties (#13203)
5135							sel = handleObj.selector + " ";
5136
5137							if (matches[sel] === undefined) {
5138								matches[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length;
5139							}
5140							if (matches[sel]) {
5141								matches.push(handleObj);
5142							}
5143						}
5144						if (matches.length) {
5145							handlerQueue.push({ elem: cur, handlers: matches });
5146						}
5147					}
5148				}
5149			}
5150
5151			// Add the remaining (directly-bound) handlers
5152			if (delegateCount < handlers.length) {
5153				handlerQueue.push({ elem: this, handlers: handlers.slice(delegateCount) });
5154			}
5155
5156			return handlerQueue;
5157		},
5158
5159		fix: function (event) {
5160			if (event[jQuery.expando]) {
5161				return event;
5162			}
5163
5164			// Create a writable copy of the event object and normalize some properties
5165			var i,
5166			    prop,
5167			    copy,
5168			    type = event.type,
5169			    originalEvent = event,
5170			    fixHook = this.fixHooks[type];
5171
5172			if (!fixHook) {
5173				this.fixHooks[type] = fixHook = rmouseEvent.test(type) ? this.mouseHooks : rkeyEvent.test(type) ? this.keyHooks : {};
5174			}
5175			copy = fixHook.props ? this.props.concat(fixHook.props) : this.props;
5176
5177			event = new jQuery.Event(originalEvent);
5178
5179			i = copy.length;
5180			while (i--) {
5181				prop = copy[i];
5182				event[prop] = originalEvent[prop];
5183			}
5184
5185			// Support: IE<9
5186			// Fix target property (#1925)
5187			if (!event.target) {
5188				event.target = originalEvent.srcElement || document;
5189			}
5190
5191			// Support: Safari 6-8+
5192			// Target should not be a text node (#504, #13143)
5193			if (event.target.nodeType === 3) {
5194				event.target = event.target.parentNode;
5195			}
5196
5197			// Support: IE<9
5198			// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
5199			event.metaKey = !!event.metaKey;
5200
5201			return fixHook.filter ? fixHook.filter(event, originalEvent) : event;
5202		},
5203
5204		// Includes some event props shared by KeyEvent and MouseEvent
5205		props: ("altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + "metaKey relatedTarget shiftKey target timeStamp view which").split(" "),
5206
5207		fixHooks: {},
5208
5209		keyHooks: {
5210			props: "char charCode key keyCode".split(" "),
5211			filter: function (event, original) {
5212
5213				// Add which for key events
5214				if (event.which == null) {
5215					event.which = original.charCode != null ? original.charCode : original.keyCode;
5216				}
5217
5218				return event;
5219			}
5220		},
5221
5222		mouseHooks: {
5223			props: ("button buttons clientX clientY fromElement offsetX offsetY " + "pageX pageY screenX screenY toElement").split(" "),
5224			filter: function (event, original) {
5225				var body,
5226				    eventDoc,
5227				    doc,
5228				    button = original.button,
5229				    fromElement = original.fromElement;
5230
5231				// Calculate pageX/Y if missing and clientX/Y available
5232				if (event.pageX == null && original.clientX != null) {
5233					eventDoc = event.target.ownerDocument || document;
5234					doc = eventDoc.documentElement;
5235					body = eventDoc.body;
5236
5237					event.pageX = original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
5238					event.pageY = original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
5239				}
5240
5241				// Add relatedTarget, if necessary
5242				if (!event.relatedTarget && fromElement) {
5243					event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
5244				}
5245
5246				// Add which for click: 1 === left; 2 === middle; 3 === right
5247				// Note: button is not normalized, so don't use it
5248				if (!event.which && button !== undefined) {
5249					event.which = button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0;
5250				}
5251
5252				return event;
5253			}
5254		},
5255
5256		special: {
5257			load: {
5258
5259				// Prevent triggered image.load events from bubbling to window.load
5260				noBubble: true
5261			},
5262			focus: {
5263
5264				// Fire native event if possible so blur/focus sequence is correct
5265				trigger: function () {
5266					if (this !== safeActiveElement() && this.focus) {
5267						try {
5268							this.focus();
5269							return false;
5270						} catch (e) {
5271
5272							// Support: IE<9
5273							// If we error on focus to hidden element (#1486, #12518),
5274							// let .trigger() run the handlers
5275						}
5276					}
5277				},
5278				delegateType: "focusin"
5279			},
5280			blur: {
5281				trigger: function () {
5282					if (this === safeActiveElement() && this.blur) {
5283						this.blur();
5284						return false;
5285					}
5286				},
5287				delegateType: "focusout"
5288			},
5289			click: {
5290
5291				// For checkbox, fire native event so checked state will be right
5292				trigger: function () {
5293					if (jQuery.nodeName(this, "input") && this.type === "checkbox" && this.click) {
5294						this.click();
5295						return false;
5296					}
5297				},
5298
5299				// For cross-browser consistency, don't fire native .click() on links
5300				_default: function (event) {
5301					return jQuery.nodeName(event.target, "a");
5302				}
5303			},
5304
5305			beforeunload: {
5306				postDispatch: function (event) {
5307
5308					// Support: Firefox 20+
5309					// Firefox doesn't alert if the returnValue field is not set.
5310					if (event.result !== undefined && event.originalEvent) {
5311						event.originalEvent.returnValue = event.result;
5312					}
5313				}
5314			}
5315		},
5316
5317		// Piggyback on a donor event to simulate a different one
5318		simulate: function (type, elem, event) {
5319			var e = jQuery.extend(new jQuery.Event(), event, {
5320				type: type,
5321				isSimulated: true
5322
5323				// Previously, `originalEvent: {}` was set here, so stopPropagation call
5324				// would not be triggered on donor event, since in our own
5325				// jQuery.event.stopPropagation function we had a check for existence of
5326				// originalEvent.stopPropagation method, so, consequently it would be a noop.
5327				//
5328				// Guard for simulated events was moved to jQuery.event.stopPropagation function
5329				// since `originalEvent` should point to the original event for the
5330				// constancy with other events and for more focused logic
5331			});
5332
5333			jQuery.event.trigger(e, null, elem);
5334
5335			if (e.isDefaultPrevented()) {
5336				event.preventDefault();
5337			}
5338		}
5339	};
5340
5341	jQuery.removeEvent = document.removeEventListener ? function (elem, type, handle) {
5342
5343		// This "if" is needed for plain objects
5344		if (elem.removeEventListener) {
5345			elem.removeEventListener(type, handle);
5346		}
5347	} : function (elem, type, handle) {
5348		var name = "on" + type;
5349
5350		if (elem.detachEvent) {
5351
5352			// #8545, #7054, preventing memory leaks for custom events in IE6-8
5353			// detachEvent needed property on element, by name of that event,
5354			// to properly expose it to GC
5355			if (typeof elem[name] === "undefined") {
5356				elem[name] = null;
5357			}
5358
5359			elem.detachEvent(name, handle);
5360		}
5361	};
5362
5363	jQuery.Event = function (src, props) {
5364
5365		// Allow instantiation without the 'new' keyword
5366		if (!(this instanceof jQuery.Event)) {
5367			return new jQuery.Event(src, props);
5368		}
5369
5370		// Event object
5371		if (src && src.type) {
5372			this.originalEvent = src;
5373			this.type = src.type;
5374
5375			// Events bubbling up the document may have been marked as prevented
5376			// by a handler lower down the tree; reflect the correct value.
5377			this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined &&
5378
5379			// Support: IE < 9, Android < 4.0
5380			src.returnValue === false ? returnTrue : returnFalse;
5381
5382			// Event type
5383		} else {
5384			this.type = src;
5385		}
5386
5387		// Put explicitly provided properties onto the event object
5388		if (props) {
5389			jQuery.extend(this, props);
5390		}
5391
5392		// Create a timestamp if incoming event doesn't have one
5393		this.timeStamp = src && src.timeStamp || jQuery.now();
5394
5395		// Mark it as fixed
5396		this[jQuery.expando] = true;
5397	};
5398
5399	// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5400	// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5401	jQuery.Event.prototype = {
5402		constructor: jQuery.Event,
5403		isDefaultPrevented: returnFalse,
5404		isPropagationStopped: returnFalse,
5405		isImmediatePropagationStopped: returnFalse,
5406
5407		preventDefault: function () {
5408			var e = this.originalEvent;
5409
5410			this.isDefaultPrevented = returnTrue;
5411			if (!e) {
5412				return;
5413			}
5414
5415			// If preventDefault exists, run it on the original event
5416			if (e.preventDefault) {
5417				e.preventDefault();
5418
5419				// Support: IE
5420				// Otherwise set the returnValue property of the original event to false
5421			} else {
5422				e.returnValue = false;
5423			}
5424		},
5425		stopPropagation: function () {
5426			var e = this.originalEvent;
5427
5428			this.isPropagationStopped = returnTrue;
5429
5430			if (!e || this.isSimulated) {
5431				return;
5432			}
5433
5434			// If stopPropagation exists, run it on the original event
5435			if (e.stopPropagation) {
5436				e.stopPropagation();
5437			}
5438
5439			// Support: IE
5440			// Set the cancelBubble property of the original event to true
5441			e.cancelBubble = true;
5442		},
5443		stopImmediatePropagation: function () {
5444			var e = this.originalEvent;
5445
5446			this.isImmediatePropagationStopped = returnTrue;
5447
5448			if (e && e.stopImmediatePropagation) {
5449				e.stopImmediatePropagation();
5450			}
5451
5452			this.stopPropagation();
5453		}
5454	};
5455
5456	// Create mouseenter/leave events using mouseover/out and event-time checks
5457	// so that event delegation works in jQuery.
5458	// Do the same for pointerenter/pointerleave and pointerover/pointerout
5459	//
5460	// Support: Safari 7 only
5461	// Safari sends mouseenter too often; see:
5462	// https://code.google.com/p/chromium/issues/detail?id=470258
5463	// for the description of the bug (it existed in older Chrome versions as well).
5464	jQuery.each({
5465		mouseenter: "mouseover",
5466		mouseleave: "mouseout",
5467		pointerenter: "pointerover",
5468		pointerleave: "pointerout"
5469	}, function (orig, fix) {
5470		jQuery.event.special[orig] = {
5471			delegateType: fix,
5472			bindType: fix,
5473
5474			handle: function (event) {
5475				var ret,
5476				    target = this,
5477				    related = event.relatedTarget,
5478				    handleObj = event.handleObj;
5479
5480				// For mouseenter/leave call the handler if related is outside the target.
5481				// NB: No relatedTarget if the mouse left/entered the browser window
5482				if (!related || related !== target && !jQuery.contains(target, related)) {
5483					event.type = handleObj.origType;
5484					ret = handleObj.handler.apply(this, arguments);
5485					event.type = fix;
5486				}
5487				return ret;
5488			}
5489		};
5490	});
5491
5492	// IE submit delegation
5493	if (!support.submit) {
5494
5495		jQuery.event.special.submit = {
5496			setup: function () {
5497
5498				// Only need this for delegated form submit events
5499				if (jQuery.nodeName(this, "form")) {
5500					return false;
5501				}
5502
5503				// Lazy-add a submit handler when a descendant form may potentially be submitted
5504				jQuery.event.add(this, "click._submit keypress._submit", function (e) {
5505
5506					// Node name check avoids a VML-related crash in IE (#9807)
5507					var elem = e.target,
5508					    form = jQuery.nodeName(elem, "input") || jQuery.nodeName(elem, "button") ?
5509
5510					// Support: IE <=8
5511					// We use jQuery.prop instead of elem.form
5512					// to allow fixing the IE8 delegated submit issue (gh-2332)
5513					// by 3rd party polyfills/workarounds.
5514					jQuery.prop(elem, "form") : undefined;
5515
5516					if (form && !jQuery._data(form, "submit")) {
5517						jQuery.event.add(form, "submit._submit", function (event) {
5518							event._submitBubble = true;
5519						});
5520						jQuery._data(form, "submit", true);
5521					}
5522				});
5523
5524				// return undefined since we don't need an event listener
5525			},
5526
5527			postDispatch: function (event) {
5528
5529				// If form was submitted by the user, bubble the event up the tree
5530				if (event._submitBubble) {
5531					delete event._submitBubble;
5532					if (this.parentNode && !event.isTrigger) {
5533						jQuery.event.simulate("submit", this.parentNode, event);
5534					}
5535				}
5536			},
5537
5538			teardown: function () {
5539
5540				// Only need this for delegated form submit events
5541				if (jQuery.nodeName(this, "form")) {
5542					return false;
5543				}
5544
5545				// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5546				jQuery.event.remove(this, "._submit");
5547			}
5548		};
5549	}
5550
5551	// IE change delegation and checkbox/radio fix
5552	if (!support.change) {
5553
5554		jQuery.event.special.change = {
5555
5556			setup: function () {
5557
5558				if (rformElems.test(this.nodeName)) {
5559
5560					// IE doesn't fire change on a check/radio until blur; trigger it on click
5561					// after a propertychange. Eat the blur-change in special.change.handle.
5562					// This still fires onchange a second time for check/radio after blur.
5563					if (this.type === "checkbox" || this.type === "radio") {
5564						jQuery.event.add(this, "propertychange._change", function (event) {
5565							if (event.originalEvent.propertyName === "checked") {
5566								this._justChanged = true;
5567							}
5568						});
5569						jQuery.event.add(this, "click._change", function (event) {
5570							if (this._justChanged && !event.isTrigger) {
5571								this._justChanged = false;
5572							}
5573
5574							// Allow triggered, simulated change events (#11500)
5575							jQuery.event.simulate("change", this, event);
5576						});
5577					}
5578					return false;
5579				}
5580
5581				// Delegated event; lazy-add a change handler on descendant inputs
5582				jQuery.event.add(this, "beforeactivate._change", function (e) {
5583					var elem = e.target;
5584
5585					if (rformElems.test(elem.nodeName) && !jQuery._data(elem, "change")) {
5586						jQuery.event.add(elem, "change._change", function (event) {
5587							if (this.parentNode && !event.isSimulated && !event.isTrigger) {
5588								jQuery.event.simulate("change", this.parentNode, event);
5589							}
5590						});
5591						jQuery._data(elem, "change", true);
5592					}
5593				});
5594			},
5595
5596			handle: function (event) {
5597				var elem = event.target;
5598
5599				// Swallow native change events from checkbox/radio, we already triggered them above
5600				if (this !== elem || event.isSimulated || event.isTrigger || elem.type !== "radio" && elem.type !== "checkbox") {
5601
5602					return event.handleObj.handler.apply(this, arguments);
5603				}
5604			},
5605
5606			teardown: function () {
5607				jQuery.event.remove(this, "._change");
5608
5609				return !rformElems.test(this.nodeName);
5610			}
5611		};
5612	}
5613
5614	// Support: Firefox
5615	// Firefox doesn't have focus(in | out) events
vendor: 1,180 bytes, lines 5616-5647
5616	// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
5617	//
5618	// Support: Chrome, Safari
5619	// focus(in | out) events fire after focus & blur events,
5620	// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
5621	// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
5622	if (!support.focusin) {
5623		jQuery.each({ focus: "focusin", blur: "focusout" }, function (orig, fix) {
5624
5625			// Attach a single capturing handler on the document while someone wants focusin/focusout
5626			var handler = function (event) {
5627				jQuery.event.simulate(fix, event.target, jQuery.event.fix(event));
5628			};
5629
5630			jQuery.event.special[fix] = {
5631				setup: function () {
5632					var doc = this.ownerDocument || this,
5633					    attaches = jQuery._data(doc, fix);
5634
5635					if (!attaches) {
5636						doc.addEventListener(orig, handler, true);
5637					}
5638					jQuery._data(doc, fix, (attaches || 0) + 1);
5639				},
5640				teardown: function () {
5641					var doc = this.ownerDocument || this,
5642					    attaches = jQuery._data(doc, fix) - 1;
5643
5644					if (!attaches) {
5645						doc.removeEventListener(orig, handler, true);
5646						jQuery._removeData(doc, fix);
5647					} else {
vendor: 11,646 bytes, lines 5648-6057
5648						jQuery._data(doc, fix, attaches);
5649					}
5650				}
5651			};
5652		});
5653	}
5654
5655	jQuery.fn.extend({
5656
5657		on: function (types, selector, data, fn) {
5658			return on(this, types, selector, data, fn);
5659		},
5660		one: function (types, selector, data, fn) {
5661			return on(this, types, selector, data, fn, 1);
5662		},
5663		off: function (types, selector, fn) {
5664			var handleObj, type;
5665			if (types && types.preventDefault && types.handleObj) {
5666
5667				// ( event )  dispatched jQuery.Event
5668				handleObj = types.handleObj;
5669				jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);
5670				return this;
5671			}
5672			if (typeof types === "object") {
5673
5674				// ( types-object [, selector] )
5675				for (type in types) {
5676					this.off(type, selector, types[type]);
5677				}
5678				return this;
5679			}
5680			if (selector === false || typeof selector === "function") {
5681
5682				// ( types [, fn] )
5683				fn = selector;
5684				selector = undefined;
5685			}
5686			if (fn === false) {
5687				fn = returnFalse;
5688			}
5689			return this.each(function () {
5690				jQuery.event.remove(this, types, fn, selector);
5691			});
5692		},
5693
5694		trigger: function (type, data) {
5695			return this.each(function () {
5696				jQuery.event.trigger(type, data, this);
5697			});
5698		},
5699		triggerHandler: function (type, data) {
5700			var elem = this[0];
5701			if (elem) {
5702				return jQuery.event.trigger(type, data, elem, true);
5703			}
5704		}
5705	});
5706
5707	var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5708	    rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
5709	    rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5710
5711
5712	// Support: IE 10-11, Edge 10240+
5713	// In IE/Edge using regex groups here causes severe slowdowns.
5714	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5715	rnoInnerhtml = /<script|<style|<link/i,
5716
5717
5718	// checked="checked" or checked
5719	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5720	    rscriptTypeMasked = /^true\/(.*)/,
5721	    rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5722	    safeFragment = createSafeFragment(document),
5723	    fragmentDiv = safeFragment.appendChild(document.createElement("div"));
5724
5725	// Support: IE<8
5726	// Manipulating tables requires a tbody
5727	function manipulationTarget(elem, content) {
5728		return jQuery.nodeName(elem, "table") && jQuery.nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr") ? elem.getElementsByTagName("tbody")[0] || elem.appendChild(elem.ownerDocument.createElement("tbody")) : elem;
5729	}
5730
5731	// Replace/restore the type attribute of script elements for safe DOM manipulation
5732	function disableScript(elem) {
5733		elem.type = (jQuery.find.attr(elem, "type") !== null) + "/" + elem.type;
5734		return elem;
5735	}
5736	function restoreScript(elem) {
5737		var match = rscriptTypeMasked.exec(elem.type);
5738		if (match) {
5739			elem.type = match[1];
5740		} else {
5741			elem.removeAttribute("type");
5742		}
5743		return elem;
5744	}
5745
5746	function cloneCopyEvent(src, dest) {
5747		if (dest.nodeType !== 1 || !jQuery.hasData(src)) {
5748			return;
5749		}
5750
5751		var type,
5752		    i,
5753		    l,
5754		    oldData = jQuery._data(src),
5755		    curData = jQuery._data(dest, oldData),
5756		    events = oldData.events;
5757
5758		if (events) {
5759			delete curData.handle;
5760			curData.events = {};
5761
5762			for (type in events) {
5763				for (i = 0, l = events[type].length; i < l; i++) {
5764					jQuery.event.add(dest, type, events[type][i]);
5765				}
5766			}
5767		}
5768
5769		// make the cloned public data object a copy from the original
5770		if (curData.data) {
5771			curData.data = jQuery.extend({}, curData.data);
5772		}
5773	}
5774
5775	function fixCloneNodeIssues(src, dest) {
5776		var nodeName, e, data;
5777
5778		// We do not need to do anything for non-Elements
5779		if (dest.nodeType !== 1) {
5780			return;
5781		}
5782
5783		nodeName = dest.nodeName.toLowerCase();
5784
5785		// IE6-8 copies events bound via attachEvent when using cloneNode.
5786		if (!support.noCloneEvent && dest[jQuery.expando]) {
5787			data = jQuery._data(dest);
5788
5789			for (e in data.events) {
5790				jQuery.removeEvent(dest, e, data.handle);
5791			}
5792
5793			// Event data gets referenced instead of copied if the expando gets copied too
5794			dest.removeAttribute(jQuery.expando);
5795		}
5796
5797		// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5798		if (nodeName === "script" && dest.text !== src.text) {
5799			disableScript(dest).text = src.text;
5800			restoreScript(dest);
5801
5802			// IE6-10 improperly clones children of object elements using classid.
5803			// IE10 throws NoModificationAllowedError if parent is null, #12132.
5804		} else if (nodeName === "object") {
5805			if (dest.parentNode) {
5806				dest.outerHTML = src.outerHTML;
5807			}
5808
5809			// This path appears unavoidable for IE9. When cloning an object
5810			// element in IE9, the outerHTML strategy above is not sufficient.
5811			// If the src has innerHTML and the destination does not,
5812			// copy the src.innerHTML into the dest.innerHTML. #10324
5813			if (support.html5Clone && src.innerHTML && !jQuery.trim(dest.innerHTML)) {
5814				dest.innerHTML = src.innerHTML;
5815			}
5816		} else if (nodeName === "input" && rcheckableType.test(src.type)) {
5817
5818			// IE6-8 fails to persist the checked state of a cloned checkbox
5819			// or radio button. Worse, IE6-7 fail to give the cloned element
5820			// a checked appearance if the defaultChecked value isn't also set
5821
5822			dest.defaultChecked = dest.checked = src.checked;
5823
5824			// IE6-7 get confused and end up setting the value of a cloned
5825			// checkbox/radio button to an empty string instead of "on"
5826			if (dest.value !== src.value) {
5827				dest.value = src.value;
5828			}
5829
5830			// IE6-8 fails to return the selected option to the default selected
5831			// state when cloning options
5832		} else if (nodeName === "option") {
5833			dest.defaultSelected = dest.selected = src.defaultSelected;
5834
5835			// IE6-8 fails to set the defaultValue to the correct value when
5836			// cloning other types of input fields
5837		} else if (nodeName === "input" || nodeName === "textarea") {
5838			dest.defaultValue = src.defaultValue;
5839		}
5840	}
5841
5842	function domManip(collection, args, callback, ignored) {
5843
5844		// Flatten any nested arrays
5845		args = concat.apply([], args);
5846
5847		var first,
5848		    node,
5849		    hasScripts,
5850		    scripts,
5851		    doc,
5852		    fragment,
5853		    i = 0,
5854		    l = collection.length,
5855		    iNoClone = l - 1,
5856		    value = args[0],
5857		    isFunction = jQuery.isFunction(value);
5858
5859		// We can't cloneNode fragments that contain checked, in WebKit
5860		if (isFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) {
5861			return collection.each(function (index) {
5862				var self = collection.eq(index);
5863				if (isFunction) {
5864					args[0] = value.call(this, index, self.html());
5865				}
5866				domManip(self, args, callback, ignored);
5867			});
5868		}
5869
5870		if (l) {
5871			fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);
5872			first = fragment.firstChild;
5873
5874			if (fragment.childNodes.length === 1) {
5875				fragment = first;
5876			}
5877
5878			// Require either new content or an interest in ignored elements to invoke the callback
5879			if (first || ignored) {
5880				scripts = jQuery.map(getAll(fragment, "script"), disableScript);
5881				hasScripts = scripts.length;
5882
5883				// Use the original fragment for the last item
5884				// instead of the first because it can end up
5885				// being emptied incorrectly in certain situations (#8070).
5886				for (; i < l; i++) {
5887					node = fragment;
5888
5889					if (i !== iNoClone) {
5890						node = jQuery.clone(node, true, true);
5891
5892						// Keep references to cloned scripts for later restoration
5893						if (hasScripts) {
5894
5895							// Support: Android<4.1, PhantomJS<2
5896							// push.apply(_, arraylike) throws on ancient WebKit
5897							jQuery.merge(scripts, getAll(node, "script"));
5898						}
5899					}
5900
5901					callback.call(collection[i], node, i);
5902				}
5903
5904				if (hasScripts) {
5905					doc = scripts[scripts.length - 1].ownerDocument;
5906
5907					// Reenable scripts
5908					jQuery.map(scripts, restoreScript);
5909
5910					// Evaluate executable scripts on first document insertion
5911					for (i = 0; i < hasScripts; i++) {
5912						node = scripts[i];
5913						if (rscriptType.test(node.type || "") && !jQuery._data(node, "globalEval") && jQuery.contains(doc, node)) {
5914
5915							if (node.src) {
5916
5917								// Optional AJAX dependency, but won't run scripts if not present
5918								if (jQuery._evalUrl) {
5919									jQuery._evalUrl(node.src);
5920								}
5921							} else {
5922								jQuery.globalEval((node.text || node.textContent || node.innerHTML || "").replace(rcleanScript, ""));
5923							}
5924						}
5925					}
5926				}
5927
5928				// Fix #11809: Avoid leaking memory
5929				fragment = first = null;
5930			}
5931		}
5932
5933		return collection;
5934	}
5935
5936	function remove(elem, selector, keepData) {
5937		var node,
5938		    elems = selector ? jQuery.filter(selector, elem) : elem,
5939		    i = 0;
5940
5941		for (; (node = elems[i]) != null; i++) {
5942
5943			if (!keepData && node.nodeType === 1) {
5944				jQuery.cleanData(getAll(node));
5945			}
5946
5947			if (node.parentNode) {
5948				if (keepData && jQuery.contains(node.ownerDocument, node)) {
5949					setGlobalEval(getAll(node, "script"));
5950				}
5951				node.parentNode.removeChild(node);
5952			}
5953		}
5954
5955		return elem;
5956	}
5957
5958	jQuery.extend({
5959		htmlPrefilter: function (html) {
5960			return html.replace(rxhtmlTag, "<$1></$2>");
5961		},
5962
5963		clone: function (elem, dataAndEvents, deepDataAndEvents) {
5964			var destElements,
5965			    node,
5966			    clone,
5967			    i,
5968			    srcElements,
5969			    inPage = jQuery.contains(elem.ownerDocument, elem);
5970
5971			if (support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test("<" + elem.nodeName + ">")) {
5972
5973				clone = elem.cloneNode(true);
5974
5975				// IE<=8 does not properly clone detached, unknown element nodes
5976			} else {
5977				fragmentDiv.innerHTML = elem.outerHTML;
5978				fragmentDiv.removeChild(clone = fragmentDiv.firstChild);
5979			}
5980
5981			if ((!support.noCloneEvent || !support.noCloneChecked) && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) {
5982
5983				// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5984				destElements = getAll(clone);
5985				srcElements = getAll(elem);
5986
5987				// Fix all IE cloning issues
5988				for (i = 0; (node = srcElements[i]) != null; ++i) {
5989
5990					// Ensure that the destination node is not null; Fixes #9587
5991					if (destElements[i]) {
5992						fixCloneNodeIssues(node, destElements[i]);
5993					}
5994				}
5995			}
5996
5997			// Copy the events from the original to the clone
5998			if (dataAndEvents) {
5999				if (deepDataAndEvents) {
6000					srcElements = srcElements || getAll(elem);
6001					destElements = destElements || getAll(clone);
6002
6003					for (i = 0; (node = srcElements[i]) != null; i++) {
6004						cloneCopyEvent(node, destElements[i]);
6005					}
6006				} else {
6007					cloneCopyEvent(elem, clone);
6008				}
6009			}
6010
6011			// Preserve script evaluation history
6012			destElements = getAll(clone, "script");
6013			if (destElements.length > 0) {
6014				setGlobalEval(destElements, !inPage && getAll(elem, "script"));
6015			}
6016
6017			destElements = srcElements = node = null;
6018
6019			// Return the cloned set
6020			return clone;
6021		},
6022
6023		cleanData: function (elems, /* internal */forceAcceptData) {
6024			var elem,
6025			    type,
6026			    id,
6027			    data,
6028			    i = 0,
6029			    internalKey = jQuery.expando,
6030			    cache = jQuery.cache,
6031			    attributes = support.attributes,
6032			    special = jQuery.event.special;
6033
6034			for (; (elem = elems[i]) != null; i++) {
6035				if (forceAcceptData || acceptData(elem)) {
6036
6037					id = elem[internalKey];
6038					data = id && cache[id];
6039
6040					if (data) {
6041						if (data.events) {
6042							for (type in data.events) {
6043								if (special[type]) {
6044									jQuery.event.remove(elem, type);
6045
6046									// This is a shortcut to avoid jQuery.event.remove's overhead
6047								} else {
6048									jQuery.removeEvent(elem, type, data.handle);
6049								}
6050							}
6051						}
6052
6053						// Remove cache only if it was not already removed by jQuery.event.remove
6054						if (cache[id]) {
6055
6056							delete cache[id];
6057
6058							// Support: IE<9
6059							// IE does not allow us to delete expando properties from nodes
6060							// IE creates expando attributes along with the property
6061							// IE does not have a removeAttribute function on Document nodes
6062							if (!attributes && typeof elem.removeAttribute !== "undefined") {
6063								elem.removeAttribute(internalKey);
6064
6065								// Webkit & Blink performance suffers when deleting properties
6066								// from DOM nodes, so set to undefined instead
6067								// https://code.google.com/p/chromium/issues/detail?id=378607
6068							} else {
6069								elem[internalKey] = undefined;
6070							}
6071
6072							deletedIds.push(id);
6073						}
6074					}
6075				}
6076			}
6077		}
6078	});
6079
6080	jQuery.fn.extend({
6081
6082		// Keep domManip exposed until 3.0 (gh-2225)
6083		domManip: domManip,
6084
6085		detach: function (selector) {
6086			return remove(this, selector, true);
6087		},
6088
6089		remove: function (selector) {
6090			return remove(this, selector);
6091		},
6092
6093		text: function (value) {
6094			return access(this, function (value) {
6095				return value === undefined ? jQuery.text(this) : this.empty().append((this[0] && this[0].ownerDocument || document).createTextNode(value));
6096			}, null, value, arguments.length);
6097		},
6098
6099		append: function () {
6100			return domManip(this, arguments, function (elem) {
6101				if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
6102					var target = manipulationTarget(this, elem);
6103					target.appendChild(elem);
6104				}
6105			});
6106		},
6107
6108		prepend: function () {
6109			return domManip(this, arguments, function (elem) {
6110				if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
6111					var target = manipulationTarget(this, elem);
6112					target.insertBefore(elem, target.firstChild);
6113				}
6114			});
6115		},
6116
6117		before: function () {
6118			return domManip(this, arguments, function (elem) {
6119				if (this.parentNode) {
6120					this.parentNode.insertBefore(elem, this);
6121				}
6122			});
6123		},
6124
6125		after: function () {
6126			return domManip(this, arguments, function (elem) {
6127				if (this.parentNode) {
6128					this.parentNode.insertBefore(elem, this.nextSibling);
6129				}
6130			});
6131		},
6132
6133		empty: function () {
6134			var elem,
6135			    i = 0;
6136
6137			for (; (elem = this[i]) != null; i++) {
6138
6139				// Remove element nodes and prevent memory leaks
6140				if (elem.nodeType === 1) {
6141					jQuery.cleanData(getAll(elem, false));
6142				}
6143
6144				// Remove any remaining nodes
6145				while (elem.firstChild) {
6146					elem.removeChild(elem.firstChild);
6147				}
6148
6149				// If this is a select, ensure that it displays empty (#12336)
6150				// Support: IE<9
6151				if (elem.options && jQuery.nodeName(elem, "select")) {
6152					elem.options.length = 0;
6153				}
6154			}
6155
6156			return this;
6157		},
6158
6159		clone: function (dataAndEvents, deepDataAndEvents) {
6160			dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6161			deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6162
6163			return this.map(function () {
6164				return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
6165			});
6166		},
6167
6168		html: function (value) {
6169			return access(this, function (value) {
6170				var elem = this[0] || {},
6171				    i = 0,
6172				    l = this.length;
6173
6174				if (value === undefined) {
6175					return elem.nodeType === 1 ? elem.innerHTML.replace(rinlinejQuery, "") : undefined;
6176				}
6177
6178				// See if we can take a shortcut and just use innerHTML
6179				if (typeof value === "string" && !rnoInnerhtml.test(value) && (support.htmlSerialize || !rnoshimcache.test(value)) && (support.leadingWhitespace || !rleadingWhitespace.test(value)) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
6180
6181					value = jQuery.htmlPrefilter(value);
6182
6183					try {
6184						for (; i < l; i++) {
6185
6186							// Remove element nodes and prevent memory leaks
6187							elem = this[i] || {};
6188							if (elem.nodeType === 1) {
6189								jQuery.cleanData(getAll(elem, false));
6190								elem.innerHTML = value;
6191							}
6192						}
6193
6194						elem = 0;
6195
6196						// If using innerHTML throws an exception, use the fallback method
6197					} catch (e) {}
6198				}
6199
6200				if (elem) {
6201					this.empty().append(value);
6202				}
6203			}, null, value, arguments.length);
6204		},
6205
6206		replaceWith: function () {
6207			var ignored = [];
6208
6209			// Make the changes, replacing each non-ignored context element with the new content
6210			return domManip(this, arguments, function (elem) {
6211				var parent = this.parentNode;
6212
6213				if (jQuery.inArray(this, ignored) < 0) {
6214					jQuery.cleanData(getAll(this));
6215					if (parent) {
6216						parent.replaceChild(elem, this);
6217					}
6218				}
6219
6220				// Force callback invocation
6221			}, ignored);
6222		}
6223	});
6224
6225	jQuery.each({
6226		appendTo: "append",
vendor: 1,203 bytes, lines 6227-6274
6227		prependTo: "prepend",
6228		insertBefore: "before",
6229		insertAfter: "after",
6230		replaceAll: "replaceWith"
6231	}, function (name, original) {
6232		jQuery.fn[name] = function (selector) {
6233			var elems,
6234			    i = 0,
6235			    ret = [],
6236			    insert = jQuery(selector),
6237			    last = insert.length - 1;
6238
6239			for (; i <= last; i++) {
6240				elems = i === last ? this : this.clone(true);
6241				jQuery(insert[i])[original](elems);
6242
6243				// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
6244				push.apply(ret, elems.get());
6245			}
6246
6247			return this.pushStack(ret);
6248		};
6249	});
6250
6251	var iframe,
6252	    elemdisplay = {
6253
6254		// Support: Firefox
6255		// We have to pre-define these values for FF (#10227)
6256		HTML: "block",
6257		BODY: "block"
6258	};
6259
6260	/**
6261  * Retrieve the actual display of a element
6262  * @param {String} name nodeName of the element
6263  * @param {Object} doc Document object
6264  */
6265
6266	// Called only from within defaultDisplay
6267	function actualDisplay(name, doc) {
6268		var elem = jQuery(doc.createElement(name)).appendTo(doc.body),
6269		    display = jQuery.css(elem[0], "display");
6270
6271		// We don't have any data stored on the element,
6272		// so use "detach" method as fast way to get rid of the element
6273		elem.detach();
6274
6275		return display;
6276	}
6277
6278	/**
6279  * Try to determine the default display value of an element
6280  * @param {String} nodeName
6281  */
6282	function defaultDisplay(nodeName) {
6283		var doc = document,
6284		    display = elemdisplay[nodeName];
6285
6286		if (!display) {
6287			display = actualDisplay(nodeName, doc);
6288
6289			// If the simple way fails, read from inside an iframe
6290			if (display === "none" || !display) {
6291
6292				// Use the already-created iframe if possible
6293				iframe = (iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>")).appendTo(doc.documentElement);
6294
6295				// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6296				doc = (iframe[0].contentWindow || iframe[0].contentDocument).document;
6297
6298				// Support: IE
6299				doc.write();
6300				doc.close();
6301
6302				display = actualDisplay(nodeName, doc);
6303				iframe.detach();
6304			}
6305
6306			// Store the correct default display
6307			elemdisplay[nodeName] = display;
6308		}
6309
6310		return display;
6311	}
6312	var rmargin = /^margin/;
6313
6314	var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");
6315
6316	var swap = function (elem, options, callback, args) {
6317		var ret,
6318		    name,
6319		    old = {};
6320
6321		// Remember the old values, and insert the new ones
6322		for (name in options) {
6323			old[name] = elem.style[name];
6324			elem.style[name] = options[name];
6325		}
6326
6327		ret = callback.apply(elem, args || []);
6328
6329		// Revert the old values
6330		for (name in options) {
6331			elem.style[name] = old[name];
6332		}
6333
6334		return ret;
6335	};
6336
6337	var documentElement = document.documentElement;
6338
6339	(function () {
6340		var pixelPositionVal,
6341		    pixelMarginRightVal,
6342		    boxSizingReliableVal,
6343		    reliableHiddenOffsetsVal,
6344		    reliableMarginRightVal,
6345		    reliableMarginLeftVal,
6346		    container = document.createElement("div"),
6347		    div = document.createElement("div");
6348
6349		// Finish early in limited (non-browser) environments
6350		if (!div.style) {
6351			return;
6352		}
6353
6354		div.style.cssText = "float:left;opacity:.5";
6355
6356		// Support: IE<9
6357		// Make sure that element opacity exists (as opposed to filter)
6358		support.opacity = div.style.opacity === "0.5";
6359
6360		// Verify style float existence
6361		// (IE uses styleFloat instead of cssFloat)
6362		support.cssFloat = !!div.style.cssFloat;
6363
6364		div.style.backgroundClip = "content-box";
6365		div.cloneNode(true).style.backgroundClip = "";
6366		support.clearCloneStyle = div.style.backgroundClip === "content-box";
6367
6368		container = document.createElement("div");
6369		container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + "padding:0;margin-top:1px;position:absolute";
6370		div.innerHTML = "";
6371		container.appendChild(div);
6372
6373		// Support: Firefox<29, Android 2.3
6374		// Vendor-prefix box-sizing
6375		support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" || div.style.WebkitBoxSizing === "";
6376
6377		jQuery.extend(support, {
6378			reliableHiddenOffsets: function () {
6379				if (pixelPositionVal == null) {
6380					computeStyleTests();
6381				}
6382				return reliableHiddenOffsetsVal;
6383			},
6384
6385			boxSizingReliable: function () {
6386
6387				// We're checking for pixelPositionVal here instead of boxSizingReliableVal
6388				// since that compresses better and they're computed together anyway.
6389				if (pixelPositionVal == null) {
6390					computeStyleTests();
6391				}
6392				return boxSizingReliableVal;
6393			},
6394
6395			pixelMarginRight: function () {
6396
6397				// Support: Android 4.0-4.3
6398				if (pixelPositionVal == null) {
6399					computeStyleTests();
6400				}
6401				return pixelMarginRightVal;
6402			},
6403
6404			pixelPosition: function () {
6405				if (pixelPositionVal == null) {
6406					computeStyleTests();
6407				}
6408				return pixelPositionVal;
6409			},
6410
6411			reliableMarginRight: function () {
6412
6413				// Support: Android 2.3
6414				if (pixelPositionVal == null) {
6415					computeStyleTests();
6416				}
6417				return reliableMarginRightVal;
6418			},
6419
6420			reliableMarginLeft: function () {
6421
6422				// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
6423				if (pixelPositionVal == null) {
6424					computeStyleTests();
6425				}
6426				return reliableMarginLeftVal;
6427			}
6428		});
6429
6430		function computeStyleTests() {
6431			var contents,
6432			    divStyle,
6433			    documentElement = document.documentElement;
6434
6435			// Setup
6436			documentElement.appendChild(container);
6437
6438			div.style.cssText =
6439
6440			// Support: Android 2.3
6441			// Vendor-prefix box-sizing
6442			"-webkit-box-sizing:border-box;box-sizing:border-box;" + "position:relative;display:block;" + "margin:auto;border:1px;padding:1px;" + "top:1%;width:50%";
6443
6444			// Support: IE<9
6445			// Assume reasonable values in the absence of getComputedStyle
6446			pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
6447			pixelMarginRightVal = reliableMarginRightVal = true;
6448
6449			// Check for getComputedStyle so that this code is not run in IE<9.
6450			if (window.getComputedStyle) {
6451				divStyle = window.getComputedStyle(div);
6452				pixelPositionVal = (divStyle || {}).top !== "1%";
6453				reliableMarginLeftVal = (divStyle || {}).marginLeft === "2px";
6454				boxSizingReliableVal = (divStyle || { width: "4px" }).width === "4px";
6455
6456				// Support: Android 4.0 - 4.3 only
6457				// Some styles come back with percentage values, even though they shouldn't
6458				div.style.marginRight = "50%";
6459				pixelMarginRightVal = (divStyle || { marginRight: "4px" }).marginRight === "4px";
6460
6461				// Support: Android 2.3 only
6462				// Div with explicit width and no margin-right incorrectly
6463				// gets computed margin-right based on width of container (#3333)
6464				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6465				contents = div.appendChild(document.createElement("div"));
6466
6467				// Reset CSS: box-sizing; display; margin; border; padding
6468				contents.style.cssText = div.style.cssText =
6469
6470				// Support: Android 2.3
6471				// Vendor-prefix box-sizing
6472				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
6473				contents.style.marginRight = contents.style.width = "0";
6474				div.style.width = "1px";
6475
6476				reliableMarginRightVal = !parseFloat((window.getComputedStyle(contents) || {}).marginRight);
6477
6478				div.removeChild(contents);
6479			}
6480
6481			// Support: IE6-8
6482			// First check that getClientRects works as expected
6483			// Check if table cells still have offsetWidth/Height when they are set
6484			// to display:none and there are still other visible table cells in a
6485			// table row; if so, offsetWidth/Height are not reliable for use when
6486			// determining if an element has been hidden directly using
6487			// display:none (it is still safe to use offsets if a parent element is
6488			// hidden; don safety goggles and see bug #4512 for more information).
6489			div.style.display = "none";
6490			reliableHiddenOffsetsVal = div.getClientRects().length === 0;
6491			if (reliableHiddenOffsetsVal) {
6492				div.style.display = "";
6493				div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6494				div.childNodes[0].style.borderCollapse = "separate";
6495				contents = div.getElementsByTagName("td");
6496				contents[0].style.cssText = "margin:0;border:0;padding:0;display:none";
6497				reliableHiddenOffsetsVal = contents[0].offsetHeight === 0;
6498				if (reliableHiddenOffsetsVal) {
6499					contents[0].style.display = "";
6500					contents[1].style.display = "none";
6501					reliableHiddenOffsetsVal = contents[0].offsetHeight === 0;
6502				}
6503			}
6504
6505			// Teardown
6506			documentElement.removeChild(container);
6507		}
6508	})();
6509
6510	var getStyles,
6511	    curCSS,
6512	    rposition = /^(top|right|bottom|left)$/;
6513
6514	if (window.getComputedStyle) {
6515		getStyles = function (elem) {
6516
6517			// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
6518			// IE throws on elements created in popups
6519			// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6520			var view = elem.ownerDocument.defaultView;
6521
6522			if (!view || !view.opener) {
6523				view = window;
6524			}
6525
6526			return view.getComputedStyle(elem);
6527		};
6528
6529		curCSS = function (elem, name, computed) {
6530			var width,
6531			    minWidth,
6532			    maxWidth,
6533			    ret,
6534			    style = elem.style;
6535
6536			computed = computed || getStyles(elem);
6537
6538			// getPropertyValue is only needed for .css('filter') in IE9, see #12537
6539			ret = computed ? computed.getPropertyValue(name) || computed[name] : undefined;
6540
6541			// Support: Opera 12.1x only
6542			// Fall back to style even without computed
6543			// computed is undefined for elems on document fragments
6544			if ((ret === "" || ret === undefined) && !jQuery.contains(elem.ownerDocument, elem)) {
6545				ret = jQuery.style(elem, name);
6546			}
6547
6548			if (computed) {
6549
6550				// A tribute to the "awesome hack by Dean Edwards"
6551				// Chrome < 17 and Safari 5.0 uses "computed value"
6552				// instead of "used value" for margin-right
6553				// Safari 5.1.7 (at least) returns percentage for a larger set of values,
6554				// but width seems to be reliably pixels
6555				// this is against the CSSOM draft spec:
6556				// http://dev.w3.org/csswg/cssom/#resolved-values
6557				if (!support.pixelMarginRight() && rnumnonpx.test(ret) && rmargin.test(name)) {
6558
6559					// Remember the original values
6560					width = style.width;
6561					minWidth = style.minWidth;
6562					maxWidth = style.maxWidth;
6563
6564					// Put in the new values to get a computed value out
6565					style.minWidth = style.maxWidth = style.width = ret;
6566					ret = computed.width;
6567
6568					// Revert the changed values
6569					style.width = width;
6570					style.minWidth = minWidth;
6571					style.maxWidth = maxWidth;
6572				}
6573			}
6574
vendor: 4,252 bytes, lines 6575-6727
6575			// Support: IE
6576			// IE returns zIndex value as an integer.
6577			return ret === undefined ? ret : ret + "";
6578		};
6579	} else if (documentElement.currentStyle) {
6580		getStyles = function (elem) {
6581			return elem.currentStyle;
6582		};
6583
6584		curCSS = function (elem, name, computed) {
6585			var left,
6586			    rs,
6587			    rsLeft,
6588			    ret,
6589			    style = elem.style;
6590
6591			computed = computed || getStyles(elem);
6592			ret = computed ? computed[name] : undefined;
6593
6594			// Avoid setting ret to empty string here
6595			// so we don't default to auto
6596			if (ret == null && style && style[name]) {
6597				ret = style[name];
6598			}
6599
6600			// From the awesome hack by Dean Edwards
6601			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6602
6603			// If we're not dealing with a regular pixel number
6604			// but a number that has a weird ending, we need to convert it to pixels
6605			// but not position css attributes, as those are
6606			// proportional to the parent element instead
6607			// and we can't measure the parent instead because it
6608			// might trigger a "stacking dolls" problem
6609			if (rnumnonpx.test(ret) && !rposition.test(name)) {
6610
6611				// Remember the original values
6612				left = style.left;
6613				rs = elem.runtimeStyle;
6614				rsLeft = rs && rs.left;
6615
6616				// Put in the new values to get a computed value out
6617				if (rsLeft) {
6618					rs.left = elem.currentStyle.left;
6619				}
6620				style.left = name === "fontSize" ? "1em" : ret;
6621				ret = style.pixelLeft + "px";
6622
6623				// Revert the changed values
6624				style.left = left;
6625				if (rsLeft) {
6626					rs.left = rsLeft;
6627				}
6628			}
6629
6630			// Support: IE
6631			// IE returns zIndex value as an integer.
6632			return ret === undefined ? ret : ret + "" || "auto";
6633		};
6634	}
6635
6636	function addGetHookIf(conditionFn, hookFn) {
6637
6638		// Define the hook, we'll check on the first run if it's really needed.
6639		return {
6640			get: function () {
6641				if (conditionFn()) {
6642
6643					// Hook not needed (or it's not possible to use it due
6644					// to missing dependency), remove it.
6645					delete this.get;
6646					return;
6647				}
6648
6649				// Hook needed; redefine it so that the support test is not executed again.
6650				return (this.get = hookFn).apply(this, arguments);
6651			}
6652		};
6653	}
6654
6655	var ralpha = /alpha\([^)]*\)/i,
6656	    ropacity = /opacity\s*=\s*([^)]*)/i,
6657
6658
6659	// swappable if display is none or starts with table except
6660	// "table", "table-cell", or "table-caption"
6661	// see here for display values:
6662	// https://developer.mozilla.org/en-US/docs/CSS/display
6663	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6664	    rnumsplit = new RegExp("^(" + pnum + ")(.*)$", "i"),
6665	    cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6666	    cssNormalTransform = {
6667		letterSpacing: "0",
6668		fontWeight: "400"
6669	},
6670	    cssPrefixes = ["Webkit", "O", "Moz", "ms"],
6671	    emptyStyle = document.createElement("div").style;
6672
6673	// return a css property mapped to a potentially vendor prefixed property
6674	function vendorPropName(name) {
6675
6676		// shortcut for names that are not vendor prefixed
6677		if (name in emptyStyle) {
6678			return name;
6679		}
6680
6681		// check for vendor prefixed names
6682		var capName = name.charAt(0).toUpperCase() + name.slice(1),
6683		    i = cssPrefixes.length;
6684
6685		while (i--) {
6686			name = cssPrefixes[i] + capName;
6687			if (name in emptyStyle) {
6688				return name;
6689			}
6690		}
6691	}
6692
6693	function showHide(elements, show) {
6694		var display,
6695		    elem,
6696		    hidden,
6697		    values = [],
6698		    index = 0,
6699		    length = elements.length;
6700
6701		for (; index < length; index++) {
6702			elem = elements[index];
6703			if (!elem.style) {
6704				continue;
6705			}
6706
6707			values[index] = jQuery._data(elem, "olddisplay");
6708			display = elem.style.display;
6709			if (show) {
6710
6711				// Reset the inline display of this element to learn if it is
6712				// being hidden by cascaded rules or not
6713				if (!values[index] && display === "none") {
6714					elem.style.display = "";
6715				}
6716
6717				// Set elements which have been overridden with display: none
6718				// in a stylesheet to whatever the default browser style is
6719				// for such an element
6720				if (elem.style.display === "" && isHidden(elem)) {
6721					values[index] = jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
6722				}
6723			} else {
6724				hidden = isHidden(elem);
6725
6726				if (display && display !== "none" || !hidden) {
6727					jQuery._data(elem, "olddisplay", hidden ? display : jQuery.css(elem, "dis
vendor: 6,095 bytes, lines 6727-6928
6727play"));
6728				}
6729			}
6730		}
6731
6732		// Set the display of most of the elements in a second loop
6733		// to avoid the constant reflow
6734		for (index = 0; index < length; index++) {
6735			elem = elements[index];
6736			if (!elem.style) {
6737				continue;
6738			}
6739			if (!show || elem.style.display === "none" || elem.style.display === "") {
6740				elem.style.display = show ? values[index] || "" : "none";
6741			}
6742		}
6743
6744		return elements;
6745	}
6746
6747	function setPositiveNumber(elem, value, subtract) {
6748		var matches = rnumsplit.exec(value);
6749		return matches ?
6750
6751		// Guard against undefined "subtract", e.g., when used as in cssHooks
6752		Math.max(0, matches[1] - (subtract || 0)) + (matches[2] || "px") : value;
6753	}
6754
6755	function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
6756		var i = extra === (isBorderBox ? "border" : "content") ?
6757
6758		// If we already have the right measurement, avoid augmentation
6759		4 :
6760
6761		// Otherwise initialize for horizontal or vertical properties
6762		name === "width" ? 1 : 0,
6763		    val = 0;
6764
6765		for (; i < 4; i += 2) {
6766
6767			// both box models exclude margin, so add it if we want it
6768			if (extra === "margin") {
6769				val += jQuery.css(elem, extra + cssExpand[i], true, styles);
6770			}
6771
6772			if (isBorderBox) {
6773
6774				// border-box includes padding, so remove it if we want content
6775				if (extra === "content") {
6776					val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
6777				}
6778
6779				// at this point, extra isn't border nor margin, so remove border
6780				if (extra !== "margin") {
6781					val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6782				}
6783			} else {
6784
6785				// at this point, extra isn't content, so add padding
6786				val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
6787
6788				// at this point, extra isn't content nor padding, so add border
6789				if (extra !== "padding") {
6790					val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
6791				}
6792			}
6793		}
6794
6795		return val;
6796	}
6797
6798	function getWidthOrHeight(elem, name, extra) {
6799
6800		// Start with offset property, which is equivalent to the border-box value
6801		var valueIsBorderBox = true,
6802		    val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6803		    styles = getStyles(elem),
6804		    isBorderBox = support.boxSizing && jQuery.css(elem, "boxSizing", false, styles) === "border-box";
6805
6806		// some non-html elements return undefined for offsetWidth, so check for null/undefined
6807		// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6808		// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6809		if (val <= 0 || val == null) {
6810
6811			// Fall back to computed then uncomputed css if necessary
6812			val = curCSS(elem, name, styles);
6813			if (val < 0 || val == null) {
6814				val = elem.style[name];
6815			}
6816
6817			// Computed unit is not pixels. Stop here and return.
6818			if (rnumnonpx.test(val)) {
6819				return val;
6820			}
6821
6822			// we need the check for style in case a browser which returns unreliable values
6823			// for getComputedStyle silently falls back to the reliable elem.style
6824			valueIsBorderBox = isBorderBox && (support.boxSizingReliable() || val === elem.style[name]);
6825
6826			// Normalize "", auto, and prepare for extra
6827			val = parseFloat(val) || 0;
6828		}
6829
6830		// use the active box-sizing model to add/subtract irrelevant styles
6831		return val + augmentWidthOrHeight(elem, name, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles) + "px";
6832	}
6833
6834	jQuery.extend({
6835
6836		// Add in style property hooks for overriding the default
6837		// behavior of getting and setting a style property
6838		cssHooks: {
6839			opacity: {
6840				get: function (elem, computed) {
6841					if (computed) {
6842
6843						// We should always get a number back from opacity
6844						var ret = curCSS(elem, "opacity");
6845						return ret === "" ? "1" : ret;
6846					}
6847				}
6848			}
6849		},
6850
6851		// Don't automatically add "px" to these possibly-unitless properties
6852		cssNumber: {
6853			"animationIterationCount": true,
6854			"columnCount": true,
6855			"fillOpacity": true,
6856			"flexGrow": true,
6857			"flexShrink": true,
6858			"fontWeight": true,
6859			"lineHeight": true,
6860			"opacity": true,
6861			"order": true,
6862			"orphans": true,
6863			"widows": true,
6864			"zIndex": true,
6865			"zoom": true
6866		},
6867
6868		// Add in properties whose names you wish to fix before
6869		// setting or getting the value
6870		cssProps: {
6871
6872			// normalize float css property
6873			"float": support.cssFloat ? "cssFloat" : "styleFloat"
6874		},
6875
6876		// Get and set the style property on a DOM Node
6877		style: function (elem, name, value, extra) {
6878
6879			// Don't set styles on text and comment nodes
6880			if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
6881				return;
6882			}
6883
6884			// Make sure that we're working with the right name
6885			var ret,
6886			    type,
6887			    hooks,
6888			    origName = jQuery.camelCase(name),
6889			    style = elem.style;
6890
6891			name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(origName) || origName);
6892
6893			// gets hook for the prefixed version
6894			// followed by the unprefixed version
6895			hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
6896
6897			// Check if we're setting a value
6898			if (value !== undefined) {
6899				type = typeof value;
6900
6901				// Convert "+=" or "-=" to relative numbers (#7345)
6902				if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {
6903					value = adjustCSS(elem, name, ret);
6904
6905					// Fixes bug #9237
6906					type = "number";
6907				}
6908
6909				// Make sure that null and NaN values aren't set. See: #7116
6910				if (value == null || value !== value) {
6911					return;
6912				}
6913
6914				// If a number was passed in, add the unit (except for certain CSS properties)
6915				if (type === "number") {
6916					value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px");
6917				}
6918
6919				// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
6920				// but it would mean to define eight
6921				// (for every problematic property) identical functions
6922				if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
6923					style[name] = "inherit";
6924				}
6925
6926				// If a hook was provided, use that value, otherwise just set the specified value
6927				if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {
6928
vendor: 4,360 bytes, lines 6929-7055
6929					// Support: IE
6930					// Swallow errors from 'invalid' CSS values (#5509)
6931					try {
6932						style[name] = value;
6933					} catch (e) {}
6934				}
6935			} else {
6936
6937				// If a hook was provided get the non-computed value from there
6938				if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {
6939
6940					return ret;
6941				}
6942
6943				// Otherwise just get the value from the style object
6944				return style[name];
6945			}
6946		},
6947
6948		css: function (elem, name, extra, styles) {
6949			var num,
6950			    val,
6951			    hooks,
6952			    origName = jQuery.camelCase(name);
6953
6954			// Make sure that we're working with the right name
6955			name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(origName) || origName);
6956
6957			// gets hook for the prefixed version
6958			// followed by the unprefixed version
6959			hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
6960
6961			// If a hook was provided get the computed value from there
6962			if (hooks && "get" in hooks) {
6963				val = hooks.get(elem, true, extra);
6964			}
6965
6966			// Otherwise, if a way to get the computed value exists, use that
6967			if (val === undefined) {
6968				val = curCSS(elem, name, styles);
6969			}
6970
6971			//convert "normal" to computed value
6972			if (val === "normal" && name in cssNormalTransform) {
6973				val = cssNormalTransform[name];
6974			}
6975
6976			// Return, converting to number if forced or a qualifier was provided and val looks numeric
6977			if (extra === "" || extra) {
6978				num = parseFloat(val);
6979				return extra === true || isFinite(num) ? num || 0 : val;
6980			}
6981			return val;
6982		}
6983	});
6984
6985	jQuery.each(["height", "width"], function (i, name) {
6986		jQuery.cssHooks[name] = {
6987			get: function (elem, computed, extra) {
6988				if (computed) {
6989
6990					// certain elements can have dimension info if we invisibly show them
6991					// however, it must have a current display style that would benefit from this
6992					return rdisplayswap.test(jQuery.css(elem, "display")) && elem.offsetWidth === 0 ? swap(elem, cssShow, function () {
6993						return getWidthOrHeight(elem, name, extra);
6994					}) : getWidthOrHeight(elem, name, extra);
6995				}
6996			},
6997
6998			set: function (elem, value, extra) {
6999				var styles = extra && getStyles(elem);
7000				return setPositiveNumber(elem, value, extra ? augmentWidthOrHeight(elem, name, extra, support.boxSizing && jQuery.css(elem, "boxSizing", false, styles) === "border-box", styles) : 0);
7001			}
7002		};
7003	});
7004
7005	if (!support.opacity) {
7006		jQuery.cssHooks.opacity = {
7007			get: function (elem, computed) {
7008
7009				// IE uses filters for opacity
7010				return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ? 0.01 * parseFloat(RegExp.$1) + "" : computed ? "1" : "";
7011			},
7012
7013			set: function (elem, value) {
7014				var style = elem.style,
7015				    currentStyle = elem.currentStyle,
7016				    opacity = jQuery.isNumeric(value) ? "alpha(opacity=" + value * 100 + ")" : "",
7017				    filter = currentStyle && currentStyle.filter || style.filter || "";
7018
7019				// IE has trouble with opacity if it does not have layout
7020				// Force it by setting the zoom level
7021				style.zoom = 1;
7022
7023				// if setting opacity to 1, and no other filters exist -
7024				// attempt to remove filter attribute #6652
7025				// if value === "", then remove inline opacity #12685
7026				if ((value >= 1 || value === "") && jQuery.trim(filter.replace(ralpha, "")) === "" && style.removeAttribute) {
7027
7028					// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7029					// if "filter:" is present at all, clearType is disabled, we want to avoid this
7030					// style.removeAttribute is IE Only, but so apparently is this code path...
7031					style.removeAttribute("filter");
7032
7033					// if there is no filter style applied in a css rule
7034					// or unset inline opacity, we are done
7035					if (value === "" || currentStyle && !currentStyle.filter) {
7036						return;
7037					}
7038				}
7039
7040				// otherwise, set new filter values
7041				style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : filter + " " + opacity;
7042			}
7043		};
7044	}
7045
7046	jQuery.cssHooks.marginRight = addGetHookIf(support.reliableMarginRight, function (elem, computed) {
7047		if (computed) {
7048			return swap(elem, { "display": "inline-block" }, curCSS, [elem, "marginRight"]);
7049		}
7050	});
7051
7052	jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) {
7053		if (computed) {
7054			return (parseFloat(curCSS(elem, "marginLeft")) || (
7055
vendor: 4,554 bytes, lines 7056-7219
7056			// Support: IE<=11+
7057			// Running getBoundingClientRect on a disconnected node in IE throws an error
7058			// Support: IE8 only
7059			// getClientRects() errors on disconnected elems
7060			jQuery.contains(elem.ownerDocument, elem) ? elem.getBoundingClientRect().left - swap(elem, { marginLeft: 0 }, function () {
7061				return elem.getBoundingClientRect().left;
7062			}) : 0)) + "px";
7063		}
7064	});
7065
7066	// These hooks are used by animate to expand properties
7067	jQuery.each({
7068		margin: "",
7069		padding: "",
7070		border: "Width"
7071	}, function (prefix, suffix) {
7072		jQuery.cssHooks[prefix + suffix] = {
7073			expand: function (value) {
7074				var i = 0,
7075				    expanded = {},
7076
7077
7078				// assumes a single number if not a string
7079				parts = typeof value === "string" ? value.split(" ") : [value];
7080
7081				for (; i < 4; i++) {
7082					expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0];
7083				}
7084
7085				return expanded;
7086			}
7087		};
7088
7089		if (!rmargin.test(prefix)) {
7090			jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
7091		}
7092	});
7093
7094	jQuery.fn.extend({
7095		css: function (name, value) {
7096			return access(this, function (elem, name, value) {
7097				var styles,
7098				    len,
7099				    map = {},
7100				    i = 0;
7101
7102				if (jQuery.isArray(name)) {
7103					styles = getStyles(elem);
7104					len = name.length;
7105
7106					for (; i < len; i++) {
7107						map[name[i]] = jQuery.css(elem, name[i], false, styles);
7108					}
7109
7110					return map;
7111				}
7112
7113				return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name);
7114			}, name, value, arguments.length > 1);
7115		},
7116		show: function () {
7117			return showHide(this, true);
7118		},
7119		hide: function () {
7120			return showHide(this);
7121		},
7122		toggle: function (state) {
7123			if (typeof state === "boolean") {
7124				return state ? this.show() : this.hide();
7125			}
7126
7127			return this.each(function () {
7128				if (isHidden(this)) {
7129					jQuery(this).show();
7130				} else {
7131					jQuery(this).hide();
7132				}
7133			});
7134		}
7135	});
7136
7137	function Tween(elem, options, prop, end, easing) {
7138		return new Tween.prototype.init(elem, options, prop, end, easing);
7139	}
7140	jQuery.Tween = Tween;
7141
7142	Tween.prototype = {
7143		constructor: Tween,
7144		init: function (elem, options, prop, end, easing, unit) {
7145			this.elem = elem;
7146			this.prop = prop;
7147			this.easing = easing || jQuery.easing._default;
7148			this.options = options;
7149			this.start = this.now = this.cur();
7150			this.end = end;
7151			this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
7152		},
7153		cur: function () {
7154			var hooks = Tween.propHooks[this.prop];
7155
7156			return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this);
7157		},
7158		run: function (percent) {
7159			var eased,
7160			    hooks = Tween.propHooks[this.prop];
7161
7162			if (this.options.duration) {
7163				this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration);
7164			} else {
7165				this.pos = eased = percent;
7166			}
7167			this.now = (this.end - this.start) * eased + this.start;
7168
7169			if (this.options.step) {
7170				this.options.step.call(this.elem, this.now, this);
7171			}
7172
7173			if (hooks && hooks.set) {
7174				hooks.set(this);
7175			} else {
7176				Tween.propHooks._default.set(this);
7177			}
7178			return this;
7179		}
7180	};
7181
7182	Tween.prototype.init.prototype = Tween.prototype;
7183
7184	Tween.propHooks = {
7185		_default: {
7186			get: function (tween) {
7187				var result;
7188
7189				// Use a property on the element directly when it is not a DOM element,
7190				// or when there is no matching style property that exists.
7191				if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) {
7192					return tween.elem[tween.prop];
7193				}
7194
7195				// passing an empty string as a 3rd parameter to .css will automatically
7196				// attempt a parseFloat and fallback to a string if the parse fails
7197				// so, simple values such as "10px" are parsed to Float.
7198				// complex values such as "rotate(1rad)" are returned as is.
7199				result = jQuery.css(tween.elem, tween.prop, "");
7200
7201				// Empty strings, null, undefined and "auto" are converted to 0.
7202				return !result || result === "auto" ? 0 : result;
7203			},
7204			set: function (tween) {
7205
7206				// use step hook for back compat - use cssHook if its there - use .style if its
7207				// available and use plain properties where available
7208				if (jQuery.fx.step[tween.prop]) {
7209					jQuery.fx.step[tween.prop](tween);
7210				} else if (tween.elem.nodeType === 1 && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
7211					jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
7212				} else {
7213					tween.elem[tween.prop] = tween.now;
7214				}
7215			}
7216		}
7217	};
7218
7219	// Support: IE <=9
vendor: 5,745 bytes, lines 7220-7439
7220	// Panic based approach to setting things on disconnected nodes
7221
7222	Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7223		set: function (tween) {
7224			if (tween.elem.nodeType && tween.elem.parentNode) {
7225				tween.elem[tween.prop] = tween.now;
7226			}
7227		}
7228	};
7229
7230	jQuery.easing = {
7231		linear: function (p) {
7232			return p;
7233		},
7234		swing: function (p) {
7235			return 0.5 - Math.cos(p * Math.PI) / 2;
7236		},
7237		_default: "swing"
7238	};
7239
7240	jQuery.fx = Tween.prototype.init;
7241
7242	// Back Compat <1.8 extension point
7243	jQuery.fx.step = {};
7244
7245	var fxNow,
7246	    timerId,
7247	    rfxtypes = /^(?:toggle|show|hide)$/,
7248	    rrun = /queueHooks$/;
7249
7250	// Animations created synchronously will run synchronously
7251	function createFxNow() {
7252		window.setTimeout(function () {
7253			fxNow = undefined;
7254		});
7255		return fxNow = jQuery.now();
7256	}
7257
7258	// Generate parameters to create a standard animation
7259	function genFx(type, includeWidth) {
7260		var which,
7261		    attrs = { height: type },
7262		    i = 0;
7263
7264		// if we include width, step value is 1 to do all cssExpand values,
7265		// if we don't include width, step value is 2 to skip over Left and Right
7266		includeWidth = includeWidth ? 1 : 0;
7267		for (; i < 4; i += 2 - includeWidth) {
7268			which = cssExpand[i];
7269			attrs["margin" + which] = attrs["padding" + which] = type;
7270		}
7271
7272		if (includeWidth) {
7273			attrs.opacity = attrs.width = type;
7274		}
7275
7276		return attrs;
7277	}
7278
7279	function createTween(value, prop, animation) {
7280		var tween,
7281		    collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]),
7282		    index = 0,
7283		    length = collection.length;
7284		for (; index < length; index++) {
7285			if (tween = collection[index].call(animation, prop, value)) {
7286
7287				// we're done with this property
7288				return tween;
7289			}
7290		}
7291	}
7292
7293	function defaultPrefilter(elem, props, opts) {
7294		/* jshint validthis: true */
7295		var prop,
7296		    value,
7297		    toggle,
7298		    tween,
7299		    hooks,
7300		    oldfire,
7301		    display,
7302		    checkDisplay,
7303		    anim = this,
7304		    orig = {},
7305		    style = elem.style,
7306		    hidden = elem.nodeType && isHidden(elem),
7307		    dataShow = jQuery._data(elem, "fxshow");
7308
7309		// handle queue: false promises
7310		if (!opts.queue) {
7311			hooks = jQuery._queueHooks(elem, "fx");
7312			if (hooks.unqueued == null) {
7313				hooks.unqueued = 0;
7314				oldfire = hooks.empty.fire;
7315				hooks.empty.fire = function () {
7316					if (!hooks.unqueued) {
7317						oldfire();
7318					}
7319				};
7320			}
7321			hooks.unqueued++;
7322
7323			anim.always(function () {
7324
7325				// doing this makes sure that the complete handler will be called
7326				// before this completes
7327				anim.always(function () {
7328					hooks.unqueued--;
7329					if (!jQuery.queue(elem, "fx").length) {
7330						hooks.empty.fire();
7331					}
7332				});
7333			});
7334		}
7335
7336		// height/width overflow pass
7337		if (elem.nodeType === 1 && ("height" in props || "width" in props)) {
7338
7339			// Make sure that nothing sneaks out
7340			// Record all 3 overflow attributes because IE does not
7341			// change the overflow attribute when overflowX and
7342			// overflowY are set to the same value
7343			opts.overflow = [style.overflow, style.overflowX, style.overflowY];
7344
7345			// Set display property to inline-block for height/width
7346			// animations on inline elements that are having width/height animated
7347			display = jQuery.css(elem, "display");
7348
7349			// Test default display if display is currently "none"
7350			checkDisplay = display === "none" ? jQuery._data(elem, "olddisplay") || defaultDisplay(elem.nodeName) : display;
7351
7352			if (checkDisplay === "inline" && jQuery.css(elem, "float") === "none") {
7353
7354				// inline-level elements accept inline-block;
7355				// block-level elements need to be inline with layout
7356				if (!support.inlineBlockNeedsLayout || defaultDisplay(elem.nodeName) === "inline") {
7357					style.display = "inline-block";
7358				} else {
7359					style.zoom = 1;
7360				}
7361			}
7362		}
7363
7364		if (opts.overflow) {
7365			style.overflow = "hidden";
7366			if (!support.shrinkWrapBlocks()) {
7367				anim.always(function () {
7368					style.overflow = opts.overflow[0];
7369					style.overflowX = opts.overflow[1];
7370					style.overflowY = opts.overflow[2];
7371				});
7372			}
7373		}
7374
7375		// show/hide pass
7376		for (prop in props) {
7377			value = props[prop];
7378			if (rfxtypes.exec(value)) {
7379				delete props[prop];
7380				toggle = toggle || value === "toggle";
7381				if (value === (hidden ? "hide" : "show")) {
7382
7383					// If there is dataShow left over from a stopped hide or show
7384					// and we are going to proceed with show, we should pretend to be hidden
7385					if (value === "show" && dataShow && dataShow[prop] !== undefined) {
7386						hidden = true;
7387					} else {
7388						continue;
7389					}
7390				}
7391				orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
7392
7393				// Any non-fx value stops us from restoring the original display value
7394			} else {
7395				display = undefined;
7396			}
7397		}
7398
7399		if (!jQuery.isEmptyObject(orig)) {
7400			if (dataShow) {
7401				if ("hidden" in dataShow) {
7402					hidden = dataShow.hidden;
7403				}
7404			} else {
7405				dataShow = jQuery._data(elem, "fxshow", {});
7406			}
7407
7408			// store state if its toggle - enables .stop().toggle() to "reverse"
7409			if (toggle) {
7410				dataShow.hidden = !hidden;
7411			}
7412			if (hidden) {
7413				jQuery(elem).show();
7414			} else {
7415				anim.done(function () {
7416					jQuery(elem).hide();
7417				});
7418			}
7419			anim.done(function () {
7420				var prop;
7421				jQuery._removeData(elem, "fxshow");
7422				for (prop in orig) {
7423					jQuery.style(elem, prop, orig[prop]);
7424				}
7425			});
7426			for (prop in orig) {
7427				tween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
7428
7429				if (!(prop in dataShow)) {
7430					dataShow[prop] = tween.start;
7431					if (hidden) {
7432						tween.end = tween.start;
7433						tween.start = prop === "width" || prop === "height" ? 1 : 0;
7434					}
7435				}
7436			}
7437
7438			// If this is a noop like .hide().hide(), restore an overwritten display value
7439		} else if ((display === "none" ? defaultDisplay(elem.nodeName) : dis
vendor: 5,869 bytes, lines 7439-7665
7439play) === "inline") {
7440			style.display = display;
7441		}
7442	}
7443
7444	function propFilter(props, specialEasing) {
7445		var index, name, easing, value, hooks;
7446
7447		// camelCase, specialEasing and expand cssHook pass
7448		for (index in props) {
7449			name = jQuery.camelCase(index);
7450			easing = specialEasing[name];
7451			value = props[index];
7452			if (jQuery.isArray(value)) {
7453				easing = value[1];
7454				value = props[index] = value[0];
7455			}
7456
7457			if (index !== name) {
7458				props[name] = value;
7459				delete props[index];
7460			}
7461
7462			hooks = jQuery.cssHooks[name];
7463			if (hooks && "expand" in hooks) {
7464				value = hooks.expand(value);
7465				delete props[name];
7466
7467				// not quite $.extend, this wont overwrite keys already present.
7468				// also - reusing 'index' from above because we have the correct "name"
7469				for (index in value) {
7470					if (!(index in props)) {
7471						props[index] = value[index];
7472						specialEasing[index] = easing;
7473					}
7474				}
7475			} else {
7476				specialEasing[name] = easing;
7477			}
7478		}
7479	}
7480
7481	function Animation(elem, properties, options) {
7482		var result,
7483		    stopped,
7484		    index = 0,
7485		    length = Animation.prefilters.length,
7486		    deferred = jQuery.Deferred().always(function () {
7487
7488			// don't match elem in the :animated selector
7489			delete tick.elem;
7490		}),
7491		    tick = function () {
7492			if (stopped) {
7493				return false;
7494			}
7495			var currentTime = fxNow || createFxNow(),
7496			    remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
7497
7498
7499			// Support: Android 2.3
7500			// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7501			temp = remaining / animation.duration || 0,
7502			    percent = 1 - temp,
7503			    index = 0,
7504			    length = animation.tweens.length;
7505
7506			for (; index < length; index++) {
7507				animation.tweens[index].run(percent);
7508			}
7509
7510			deferred.notifyWith(elem, [animation, percent, remaining]);
7511
7512			if (percent < 1 && length) {
7513				return remaining;
7514			} else {
7515				deferred.resolveWith(elem, [animation]);
7516				return false;
7517			}
7518		},
7519		    animation = deferred.promise({
7520			elem: elem,
7521			props: jQuery.extend({}, properties),
7522			opts: jQuery.extend(true, {
7523				specialEasing: {},
7524				easing: jQuery.easing._default
7525			}, options),
7526			originalProperties: properties,
7527			originalOptions: options,
7528			startTime: fxNow || createFxNow(),
7529			duration: options.duration,
7530			tweens: [],
7531			createTween: function (prop, end) {
7532				var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing);
7533				animation.tweens.push(tween);
7534				return tween;
7535			},
7536			stop: function (gotoEnd) {
7537				var index = 0,
7538
7539
7540				// if we are going to the end, we want to run all the tweens
7541				// otherwise we skip this part
7542				length = gotoEnd ? animation.tweens.length : 0;
7543				if (stopped) {
7544					return this;
7545				}
7546				stopped = true;
7547				for (; index < length; index++) {
7548					animation.tweens[index].run(1);
7549				}
7550
7551				// resolve when we played the last frame
7552				// otherwise, reject
7553				if (gotoEnd) {
7554					deferred.notifyWith(elem, [animation, 1, 0]);
7555					deferred.resolveWith(elem, [animation, gotoEnd]);
7556				} else {
7557					deferred.rejectWith(elem, [animation, gotoEnd]);
7558				}
7559				return this;
7560			}
7561		}),
7562		    props = animation.props;
7563
7564		propFilter(props, animation.opts.specialEasing);
7565
7566		for (; index < length; index++) {
7567			result = Animation.prefilters[index].call(animation, elem, props, animation.opts);
7568			if (result) {
7569				if (jQuery.isFunction(result.stop)) {
7570					jQuery._queueHooks(animation.elem, animation.opts.queue).stop = jQuery.proxy(result.stop, result);
7571				}
7572				return result;
7573			}
7574		}
7575
7576		jQuery.map(props, createTween, animation);
7577
7578		if (jQuery.isFunction(animation.opts.start)) {
7579			animation.opts.start.call(elem, animation);
7580		}
7581
7582		jQuery.fx.timer(jQuery.extend(tick, {
7583			elem: elem,
7584			anim: animation,
7585			queue: animation.opts.queue
7586		}));
7587
7588		// attach callbacks from options
7589		return animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always);
7590	}
7591
7592	jQuery.Animation = jQuery.extend(Animation, {
7593
7594		tweeners: {
7595			"*": [function (prop, value) {
7596				var tween = this.createTween(prop, value);
7597				adjustCSS(tween.elem, prop, rcssNum.exec(value), tween);
7598				return tween;
7599			}]
7600		},
7601
7602		tweener: function (props, callback) {
7603			if (jQuery.isFunction(props)) {
7604				callback = props;
7605				props = ["*"];
7606			} else {
7607				props = props.match(rnotwhite);
7608			}
7609
7610			var prop,
7611			    index = 0,
7612			    length = props.length;
7613
7614			for (; index < length; index++) {
7615				prop = props[index];
7616				Animation.tweeners[prop] = Animation.tweeners[prop] || [];
7617				Animation.tweeners[prop].unshift(callback);
7618			}
7619		},
7620
7621		prefilters: [defaultPrefilter],
7622
7623		prefilter: function (callback, prepend) {
7624			if (prepend) {
7625				Animation.prefilters.unshift(callback);
7626			} else {
7627				Animation.prefilters.push(callback);
7628			}
7629		}
7630	});
7631
7632	jQuery.speed = function (speed, easing, fn) {
7633		var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
7634			complete: fn || !fn && easing || jQuery.isFunction(speed) && speed,
7635			duration: speed,
7636			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
7637		};
7638
7639		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
7640
7641		// normalize opt.queue - true/undefined/null -> "fx"
7642		if (opt.queue == null || opt.queue === true) {
7643			opt.queue = "fx";
7644		}
7645
7646		// Queueing
7647		opt.old = opt.complete;
7648
7649		opt.complete = function () {
7650			if (jQuery.isFunction(opt.old)) {
7651				opt.old.call(this);
7652			}
7653
7654			if (opt.queue) {
7655				jQuery.dequeue(this, opt.queue);
7656			}
7657		};
7658
7659		return opt;
7660	};
7661
7662	jQuery.fn.extend({
7663		fadeTo: function (speed, to, easing, callback) {
7664
7665			// show any hidden elements after setting opacity to 0
vendor: 8,995 bytes, lines 7666-8006
7666			return this.filter(isHidden).css("opacity", 0).show()
7667
7668			// animate to the value specified
7669			.end().animate({ opacity: to }, speed, easing, callback);
7670		},
7671		animate: function (prop, speed, easing, callback) {
7672			var empty = jQuery.isEmptyObject(prop),
7673			    optall = jQuery.speed(speed, easing, callback),
7674			    doAnimation = function () {
7675
7676				// Operate on a copy of prop so per-property easing won't be lost
7677				var anim = Animation(this, jQuery.extend({}, prop), optall);
7678
7679				// Empty animations, or finishing resolves immediately
7680				if (empty || jQuery._data(this, "finish")) {
7681					anim.stop(true);
7682				}
7683			};
7684			doAnimation.finish = doAnimation;
7685
7686			return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation);
7687		},
7688		stop: function (type, clearQueue, gotoEnd) {
7689			var stopQueue = function (hooks) {
7690				var stop = hooks.stop;
7691				delete hooks.stop;
7692				stop(gotoEnd);
7693			};
7694
7695			if (typeof type !== "string") {
7696				gotoEnd = clearQueue;
7697				clearQueue = type;
7698				type = undefined;
7699			}
7700			if (clearQueue && type !== false) {
7701				this.queue(type || "fx", []);
7702			}
7703
7704			return this.each(function () {
7705				var dequeue = true,
7706				    index = type != null && type + "queueHooks",
7707				    timers = jQuery.timers,
7708				    data = jQuery._data(this);
7709
7710				if (index) {
7711					if (data[index] && data[index].stop) {
7712						stopQueue(data[index]);
7713					}
7714				} else {
7715					for (index in data) {
7716						if (data[index] && data[index].stop && rrun.test(index)) {
7717							stopQueue(data[index]);
7718						}
7719					}
7720				}
7721
7722				for (index = timers.length; index--;) {
7723					if (timers[index].elem === this && (type == null || timers[index].queue === type)) {
7724
7725						timers[index].anim.stop(gotoEnd);
7726						dequeue = false;
7727						timers.splice(index, 1);
7728					}
7729				}
7730
7731				// start the next in the queue if the last step wasn't forced
7732				// timers currently will call their complete callbacks, which will dequeue
7733				// but only if they were gotoEnd
7734				if (dequeue || !gotoEnd) {
7735					jQuery.dequeue(this, type);
7736				}
7737			});
7738		},
7739		finish: function (type) {
7740			if (type !== false) {
7741				type = type || "fx";
7742			}
7743			return this.each(function () {
7744				var index,
7745				    data = jQuery._data(this),
7746				    queue = data[type + "queue"],
7747				    hooks = data[type + "queueHooks"],
7748				    timers = jQuery.timers,
7749				    length = queue ? queue.length : 0;
7750
7751				// enable finishing flag on private data
7752				data.finish = true;
7753
7754				// empty the queue first
7755				jQuery.queue(this, type, []);
7756
7757				if (hooks && hooks.stop) {
7758					hooks.stop.call(this, true);
7759				}
7760
7761				// look for any active animations, and finish them
7762				for (index = timers.length; index--;) {
7763					if (timers[index].elem === this && timers[index].queue === type) {
7764						timers[index].anim.stop(true);
7765						timers.splice(index, 1);
7766					}
7767				}
7768
7769				// look for any animations in the old queue and finish them
7770				for (index = 0; index < length; index++) {
7771					if (queue[index] && queue[index].finish) {
7772						queue[index].finish.call(this);
7773					}
7774				}
7775
7776				// turn off finishing flag
7777				delete data.finish;
7778			});
7779		}
7780	});
7781
7782	jQuery.each(["toggle", "show", "hide"], function (i, name) {
7783		var cssFn = jQuery.fn[name];
7784		jQuery.fn[name] = function (speed, easing, callback) {
7785			return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback);
7786		};
7787	});
7788
7789	// Generate shortcuts for custom animations
7790	jQuery.each({
7791		slideDown: genFx("show"),
7792		slideUp: genFx("hide"),
7793		slideToggle: genFx("toggle"),
7794		fadeIn: { opacity: "show" },
7795		fadeOut: { opacity: "hide" },
7796		fadeToggle: { opacity: "toggle" }
7797	}, function (name, props) {
7798		jQuery.fn[name] = function (speed, easing, callback) {
7799			return this.animate(props, speed, easing, callback);
7800		};
7801	});
7802
7803	jQuery.timers = [];
7804	jQuery.fx.tick = function () {
7805		var timer,
7806		    timers = jQuery.timers,
7807		    i = 0;
7808
7809		fxNow = jQuery.now();
7810
7811		for (; i < timers.length; i++) {
7812			timer = timers[i];
7813
7814			// Checks the timer has not already been removed
7815			if (!timer() && timers[i] === timer) {
7816				timers.splice(i--, 1);
7817			}
7818		}
7819
7820		if (!timers.length) {
7821			jQuery.fx.stop();
7822		}
7823		fxNow = undefined;
7824	};
7825
7826	jQuery.fx.timer = function (timer) {
7827		jQuery.timers.push(timer);
7828		if (timer()) {
7829			jQuery.fx.start();
7830		} else {
7831			jQuery.timers.pop();
7832		}
7833	};
7834
7835	jQuery.fx.interval = 13;
7836
7837	jQuery.fx.start = function () {
7838		if (!timerId) {
7839			timerId = window.setInterval(jQuery.fx.tick, jQuery.fx.interval);
7840		}
7841	};
7842
7843	jQuery.fx.stop = function () {
7844		window.clearInterval(timerId);
7845		timerId = null;
7846	};
7847
7848	jQuery.fx.speeds = {
7849		slow: 600,
7850		fast: 200,
7851
7852		// Default speed
7853		_default: 400
7854	};
7855
7856	// Based off of the plugin by Clint Helfers, with permission.
7857	// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7858	jQuery.fn.delay = function (time, type) {
7859		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
7860		type = type || "fx";
7861
7862		return this.queue(type, function (next, hooks) {
7863			var timeout = window.setTimeout(next, time);
7864			hooks.stop = function () {
7865				window.clearTimeout(timeout);
7866			};
7867		});
7868	};
7869
7870	(function () {
7871		var a,
7872		    input = document.createElement("input"),
7873		    div = document.createElement("div"),
7874		    select = document.createElement("select"),
7875		    opt = select.appendChild(document.createElement("option"));
7876
7877		// Setup
7878		div = document.createElement("div");
7879		div.setAttribute("className", "t");
7880		div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
7881		a = div.getElementsByTagName("a")[0];
7882
7883		// Support: Windows Web Apps (WWA)
7884		// `type` must use .setAttribute for WWA (#14901)
7885		input.setAttribute("type", "checkbox");
7886		div.appendChild(input);
7887
7888		a = div.getElementsByTagName("a")[0];
7889
7890		// First batch of tests.
7891		a.style.cssText = "top:1px";
7892
7893		// Test setAttribute on camelCase class.
7894		// If it works, we need attrFixes when doing get/setAttribute (ie6/7)
7895		support.getSetAttribute = div.className !== "t";
7896
7897		// Get the style information from getAttribute
7898		// (IE uses .cssText instead)
7899		support.style = /top/.test(a.getAttribute("style"));
7900
7901		// Make sure that URLs aren't manipulated
7902		// (IE normalizes it by default)
7903		support.hrefNormalized = a.getAttribute("href") === "/a";
7904
7905		// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
7906		support.checkOn = !!input.value;
7907
7908		// Make sure that a selected-by-default option has a working selected property.
7909		// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
7910		support.optSelected = opt.selected;
7911
7912		// Tests for enctype support on a form (#6743)
7913		support.enctype = !!document.createElement("form").enctype;
7914
7915		// Make sure that the options inside disabled selects aren't marked as disabled
7916		// (WebKit marks them as disabled)
7917		select.disabled = true;
7918		support.optDisabled = !opt.disabled;
7919
7920		// Support: IE8 only
7921		// Check if we can trust getAttribute("value")
7922		input = document.createElement("input");
7923		input.setAttribute("value", "");
7924		support.input = input.getAttribute("value") === "";
7925
7926		// Check if an input maintains its value after becoming a radio
7927		input.value = "t";
7928		input.setAttribute("type", "radio");
7929		support.radioValue = input.value === "t";
7930	})();
7931
7932	var rreturn = /\r/g,
7933	    rspaces = /[\x20\t\r\n\f]+/g;
7934
7935	jQuery.fn.extend({
7936		val: function (value) {
7937			var hooks,
7938			    ret,
7939			    isFunction,
7940			    elem = this[0];
7941
7942			if (!arguments.length) {
7943				if (elem) {
7944					hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];
7945
7946					if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
7947						return ret;
7948					}
7949
7950					ret = elem.value;
7951
7952					return typeof ret === "string" ?
7953
7954					// handle most common string cases
7955					ret.replace(rreturn, "") :
7956
7957					// handle cases where value is null/undef or number
7958					ret == null ? "" : ret;
7959				}
7960
7961				return;
7962			}
7963
7964			isFunction = jQuery.isFunction(value);
7965
7966			return this.each(function (i) {
7967				var val;
7968
7969				if (this.nodeType !== 1) {
7970					return;
7971				}
7972
7973				if (isFunction) {
7974					val = value.call(this, i, jQuery(this).val());
7975				} else {
7976					val = value;
7977				}
7978
7979				// Treat null/undefined as ""; convert numbers to string
7980				if (val == null) {
7981					val = "";
7982				} else if (typeof val === "number") {
7983					val += "";
7984				} else if (jQuery.isArray(val)) {
7985					val = jQuery.map(val, function (value) {
7986						return value == null ? "" : value + "";
7987					});
7988				}
7989
7990				hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];
7991
7992				// If set returns undefined, fall back to normal setting
7993				if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
7994					this.value = val;
7995				}
7996			});
7997		}
7998	});
7999
8000	jQuery.extend({
8001		valHooks: {
8002			option: {
8003				get: function (elem) {
8004					var val = jQuery.find.attr(elem, "value");
8005					return val != null ? val :
8006
vendor: 4,966 bytes, lines 8007-8195
8007					// Support: IE10-11+
8008					// option.text throws exceptions (#14686, #14858)
8009					// Strip and collapse whitespace
8010					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8011					jQuery.trim(jQuery.text(elem)).replace(rspaces, " ");
8012				}
8013			},
8014			select: {
8015				get: function (elem) {
8016					var value,
8017					    option,
8018					    options = elem.options,
8019					    index = elem.selectedIndex,
8020					    one = elem.type === "select-one" || index < 0,
8021					    values = one ? null : [],
8022					    max = one ? index + 1 : options.length,
8023					    i = index < 0 ? max : one ? index : 0;
8024
8025					// Loop through all the selected options
8026					for (; i < max; i++) {
8027						option = options[i];
8028
8029						// oldIE doesn't update selected after form reset (#2551)
8030						if ((option.selected || i === index) && (
8031
8032						// Don't return options that are disabled or in a disabled optgroup
8033						support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) {
8034
8035							// Get the specific value for the option
8036							value = jQuery(option).val();
8037
8038							// We don't need an array for one selects
8039							if (one) {
8040								return value;
8041							}
8042
8043							// Multi-Selects return an array
8044							values.push(value);
8045						}
8046					}
8047
8048					return values;
8049				},
8050
8051				set: function (elem, value) {
8052					var optionSet,
8053					    option,
8054					    options = elem.options,
8055					    values = jQuery.makeArray(value),
8056					    i = options.length;
8057
8058					while (i--) {
8059						option = options[i];
8060
8061						if (jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) {
8062
8063							// Support: IE6
8064							// When new option element is added to select box we need to
8065							// force reflow of newly added node in order to workaround delay
8066							// of initialization properties
8067							try {
8068								option.selected = optionSet = true;
8069							} catch (_) {
8070
8071								// Will be executed only in IE6
8072								option.scrollHeight;
8073							}
8074						} else {
8075							option.selected = false;
8076						}
8077					}
8078
8079					// Force browsers to behave consistently when non-matching value is set
8080					if (!optionSet) {
8081						elem.selectedIndex = -1;
8082					}
8083
8084					return options;
8085				}
8086			}
8087		}
8088	});
8089
8090	// Radios and checkboxes getter/setter
8091	jQuery.each(["radio", "checkbox"], function () {
8092		jQuery.valHooks[this] = {
8093			set: function (elem, value) {
8094				if (jQuery.isArray(value)) {
8095					return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1;
8096				}
8097			}
8098		};
8099		if (!support.checkOn) {
8100			jQuery.valHooks[this].get = function (elem) {
8101				return elem.getAttribute("value") === null ? "on" : elem.value;
8102			};
8103		}
8104	});
8105
8106	var nodeHook,
8107	    boolHook,
8108	    attrHandle = jQuery.expr.attrHandle,
8109	    ruseDefault = /^(?:checked|selected)$/i,
8110	    getSetAttribute = support.getSetAttribute,
8111	    getSetInput = support.input;
8112
8113	jQuery.fn.extend({
8114		attr: function (name, value) {
8115			return access(this, jQuery.attr, name, value, arguments.length > 1);
8116		},
8117
8118		removeAttr: function (name) {
8119			return this.each(function () {
8120				jQuery.removeAttr(this, name);
8121			});
8122		}
8123	});
8124
8125	jQuery.extend({
8126		attr: function (elem, name, value) {
8127			var ret,
8128			    hooks,
8129			    nType = elem.nodeType;
8130
8131			// Don't get/set attributes on text, comment and attribute nodes
8132			if (nType === 3 || nType === 8 || nType === 2) {
8133				return;
8134			}
8135
8136			// Fallback to prop when attributes are not supported
8137			if (typeof elem.getAttribute === "undefined") {
8138				return jQuery.prop(elem, name, value);
8139			}
8140
8141			// All attributes are lowercase
8142			// Grab necessary hook if one is defined
8143			if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
8144				name = name.toLowerCase();
8145				hooks = jQuery.attrHooks[name] || (jQuery.expr.match.bool.test(name) ? boolHook : nodeHook);
8146			}
8147
8148			if (value !== undefined) {
8149				if (value === null) {
8150					jQuery.removeAttr(elem, name);
8151					return;
8152				}
8153
8154				if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
8155					return ret;
8156				}
8157
8158				elem.setAttribute(name, value + "");
8159				return value;
8160			}
8161
8162			if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
8163				return ret;
8164			}
8165
8166			ret = jQuery.find.attr(elem, name);
8167
8168			// Non-existent attributes return null, we normalize to undefined
8169			return ret == null ? undefined : ret;
8170		},
8171
8172		attrHooks: {
8173			type: {
8174				set: function (elem, value) {
8175					if (!support.radioValue && value === "radio" && jQuery.nodeName(elem, "input")) {
8176
8177						// Setting the type on a radio button after the value resets the value in IE8-9
8178						// Reset value to default in case type is set after value during creation
8179						var val = elem.value;
8180						elem.setAttribute("type", value);
8181						if (val) {
8182							elem.value = val;
8183						}
8184						return value;
8185					}
8186				}
8187			}
8188		},
8189
8190		removeAttr: function (elem, value) {
8191			var name,
8192			    propName,
8193			    i = 0,
8194			    attrNames = value && value.match(rnotwhite);
8195
vendor: 4,714 bytes, lines 8196-8359
8196			if (attrNames && elem.nodeType === 1) {
8197				while (name = attrNames[i++]) {
8198					propName = jQuery.propFix[name] || name;
8199
8200					// Boolean attributes get special treatment (#10870)
8201					if (jQuery.expr.match.bool.test(name)) {
8202
8203						// Set corresponding property to false
8204						if (getSetInput && getSetAttribute || !ruseDefault.test(name)) {
8205							elem[propName] = false;
8206
8207							// Support: IE<9
8208							// Also clear defaultChecked/defaultSelected (if appropriate)
8209						} else {
8210							elem[jQuery.camelCase("default-" + name)] = elem[propName] = false;
8211						}
8212
8213						// See #9699 for explanation of this approach (setting first, then removal)
8214					} else {
8215						jQuery.attr(elem, name, "");
8216					}
8217
8218					elem.removeAttribute(getSetAttribute ? name : propName);
8219				}
8220			}
8221		}
8222	});
8223
8224	// Hooks for boolean attributes
8225	boolHook = {
8226		set: function (elem, value, name) {
8227			if (value === false) {
8228
8229				// Remove boolean attributes when set to false
8230				jQuery.removeAttr(elem, name);
8231			} else if (getSetInput && getSetAttribute || !ruseDefault.test(name)) {
8232
8233				// IE<8 needs the *property* name
8234				elem.setAttribute(!getSetAttribute && jQuery.propFix[name] || name, name);
8235			} else {
8236
8237				// Support: IE<9
8238				// Use defaultChecked and defaultSelected for oldIE
8239				elem[jQuery.camelCase("default-" + name)] = elem[name] = true;
8240			}
8241			return name;
8242		}
8243	};
8244
8245	jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) {
8246		var getter = attrHandle[name] || jQuery.find.attr;
8247
8248		if (getSetInput && getSetAttribute || !ruseDefault.test(name)) {
8249			attrHandle[name] = function (elem, name, isXML) {
8250				var ret, handle;
8251				if (!isXML) {
8252
8253					// Avoid an infinite loop by temporarily removing this function from the getter
8254					handle = attrHandle[name];
8255					attrHandle[name] = ret;
8256					ret = getter(elem, name, isXML) != null ? name.toLowerCase() : null;
8257					attrHandle[name] = handle;
8258				}
8259				return ret;
8260			};
8261		} else {
8262			attrHandle[name] = function (elem, name, isXML) {
8263				if (!isXML) {
8264					return elem[jQuery.camelCase("default-" + name)] ? name.toLowerCase() : null;
8265				}
8266			};
8267		}
8268	});
8269
8270	// fix oldIE attroperties
8271	if (!getSetInput || !getSetAttribute) {
8272		jQuery.attrHooks.value = {
8273			set: function (elem, value, name) {
8274				if (jQuery.nodeName(elem, "input")) {
8275
8276					// Does not return so that setAttribute is also used
8277					elem.defaultValue = value;
8278				} else {
8279
8280					// Use nodeHook if defined (#1954); otherwise setAttribute is fine
8281					return nodeHook && nodeHook.set(elem, value, name);
8282				}
8283			}
8284		};
8285	}
8286
8287	// IE6/7 do not support getting/setting some attributes with get/setAttribute
8288	if (!getSetAttribute) {
8289
8290		// Use this for any attribute in IE6/7
8291		// This fixes almost every IE6/7 issue
8292		nodeHook = {
8293			set: function (elem, value, name) {
8294
8295				// Set the existing or create a new attribute node
8296				var ret = elem.getAttributeNode(name);
8297				if (!ret) {
8298					elem.setAttributeNode(ret = elem.ownerDocument.createAttribute(name));
8299				}
8300
8301				ret.value = value += "";
8302
8303				// Break association with cloned elements by also using setAttribute (#9646)
8304				if (name === "value" || value === elem.getAttribute(name)) {
8305					return value;
8306				}
8307			}
8308		};
8309
8310		// Some attributes are constructed with empty-string values when not defined
8311		attrHandle.id = attrHandle.name = attrHandle.coords = function (elem, name, isXML) {
8312			var ret;
8313			if (!isXML) {
8314				return (ret = elem.getAttributeNode(name)) && ret.value !== "" ? ret.value : null;
8315			}
8316		};
8317
8318		// Fixing value retrieval on a button requires this module
8319		jQuery.valHooks.button = {
8320			get: function (elem, name) {
8321				var ret = elem.getAttributeNode(name);
8322				if (ret && ret.specified) {
8323					return ret.value;
8324				}
8325			},
8326			set: nodeHook.set
8327		};
8328
8329		// Set contenteditable to false on removals(#10429)
8330		// Setting to empty string throws an error as an invalid value
8331		jQuery.attrHooks.contenteditable = {
8332			set: function (elem, value, name) {
8333				nodeHook.set(elem, value === "" ? false : value, name);
8334			}
8335		};
8336
8337		// Set width and height to auto instead of 0 on empty string( Bug #8150 )
8338		// This is for removals
8339		jQuery.each(["width", "height"], function (i, name) {
8340			jQuery.attrHooks[name] = {
8341				set: function (elem, value) {
8342					if (value === "") {
8343						elem.setAttribute(name, "auto");
8344						return value;
8345					}
8346				}
8347			};
8348		});
8349	}
8350
8351	if (!support.style) {
8352		jQuery.attrHooks.style = {
8353			get: function (elem) {
8354
8355				// Return undefined in the case of empty string
8356				// Note: IE uppercases css property names, but if we were to .toLowerCase()
8357				// .cssText, that would destroy case sensitivity in URL's, like in "background"
8358				return elem.style.cssText || undefined;
8359			},
8360			set: function (elem, value) {
8361				return elem.style.cssText = value + "";
8362			}
8363		};
8364	}
8365
8366	var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8367	    rclickable = /^(?:a|area)$/i;
8368
8369	jQuery.fn.extend({
8370		prop: function (name, value) {
8371			return access(this, jQuery.prop, name, value, arguments.length > 1);
8372		},
8373
8374		removeProp: function (name) {
8375			name = jQuery.propFix[name] || name;
8376			return this.each(function () {
8377
8378				// try/catch handles cases where IE balks (such as removing a property on window)
8379				try {
8380					this[name] = undefined;
8381					delete this[name];
8382				} catch (e) {}
8383			});
8384		}
8385	});
8386
8387	jQuery.extend({
8388		prop: function (elem, name, value) {
8389			var ret,
8390			    hooks,
8391			    nType = elem.nodeType;
8392
8393			// Don't get/set properties on text, comment and attribute nodes
8394			if (nType === 3 || nType === 8 || nType === 2) {
8395				return;
8396			}
8397
8398			if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
8399
8400				// Fix name and attach hooks
8401				name = jQuery.propFix[name] || name;
8402				hooks = jQuery.propHooks[name];
8403			}
8404
8405			if (value !== undefined) {
8406				if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
8407					return ret;
8408				}
8409
8410				return elem[name] = value;
8411			}
8412
8413			if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
8414				return ret;
8415			}
8416
8417			return elem[name];
8418		},
8419
8420		propHooks: {
8421			tabIndex: {
8422				get: function (elem) {
8423
8424					// elem.tabIndex doesn't always return the
8425					// correct value when it hasn't been explicitly set
8426					// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8427					// Use proper attribute retrieval(#12072)
8428					var tabindex = jQuery.find.attr(elem, "tabindex");
8429
8430					return tabindex ? parseInt(tabindex, 10) : rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href ? 0 : -1;
8431				}
8432			}
8433		},
8434
8435		propFix: {
8436			"for": "htmlFor",
8437			"class": "className"
8438		}
8439	});
8440
8441	// Some attributes require a special call on IE
8442	// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8443	if (!support.hrefNormalized) {
8444
8445		// href/src property should get the full normalized URL (#10299/#12915)
8446		jQuery.each(["href", "src"], function (i, name) {
8447			jQuery.propHooks[name] = {
8448				get: function (elem) {
8449					return elem.getAttribute(name, 4);
8450				}
8451			};
8452		});
8453	}
8454
8455	// Support: Safari, IE9+
8456	// Accessing the selectedIndex property
8457	// forces the browser to respect setting selected
8458	// on the option
8459	// The getter ensures a default option is selected
8460	// when in an optgroup
8461	if (!support.optSelected) {
8462		jQuery.propHooks.selected = {
8463			get: function (elem) {
8464				var parent = elem.parentNode;
8465
8466				if (parent) {
8467					parent.selectedIndex;
8468
8469					// Make sure that it also works with optgroups, see #5701
8470					if (parent.parentNode) {
8471						parent.parentNode.selectedIndex;
8472					}
8473				}
8474				return null;
8475			},
8476			set: function (elem) {
8477				var parent = elem.parentNode;
8478				if (parent) {
8479					parent.selectedIndex;
8480
8481					if (parent.parentNode) {
8482						parent.parentNode.selectedIndex;
8483					}
8484				}
8485			}
8486		};
8487	}
8488
8489	jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
8490		jQuery.propFix[this.toLowerCase()] = this;
8491	});
8492
8493	// IE6/7 call enctype encoding
8494	if (!support.enctype) {
8495		jQuery.propFix.enctype = "encoding";
8496	}
8497
8498	var rclass = /[\t\r\n\f]/g;
8499
8500	function getClass(elem) {
8501		return jQuery.attr(elem, "class") || "";
8502	}
8503
8504	jQuery.fn.extend({
8505		addClass: function (value) {
8506			var classes,
8507			    elem,
8508			    cur,
8509			    curValue,
8510			    clazz,
8511			    j,
8512			    finalValue,
8513			    i = 0;
8514
8515			if (jQuery.isFunction(value)) {
8516				return this.each(function (j) {
8517					jQuery(this).addClass(value.call(this, j, getClass(this)));
8518				});
8519			}
8520
8521			if (typeof value === "string" && value) {
8522				classes = value.match(rnotwhite) || [];
8523
8524				while (elem = this[i++]) {
8525					curValue = getClass(elem);
8526					cur = elem.nodeType === 1 && (" " + curValue + " ").replace(rclass, " ");
8527
8528					if (cur) {
8529						j = 0;
8530						while (clazz = classes[j++]) {
8531							if (cur.indexOf(" " + clazz + " ") < 0) {
8532								cur += clazz + " ";
8533							}
8534						}
8535
8536						// only assign if different to avoid unneeded rendering.
8537						finalValue = jQuery.trim(cur);
8538						if (curValue !== finalValue) {
8539							jQuery.attr(elem, "class", finalValue);
8540						}
8541					}
8542				}
8543			}
8544
8545			return this;
8546		},
8547
8548		removeClass: function (value) {
8549			var classes,
8550			    elem,
8551			    cur,
8552			    curValue,
8553			    clazz,
8554			    j,
8555			    finalValue,
8556			    i = 0;
8557
8558			if (jQuery.isFunction(value)) {
8559				return this.each(function (j) {
8560					jQuery(this).removeClass(value.call(this, j, getClass(this)));
8561				});
8562			}
8563
8564			if (!arguments.length) {
8565				return this.attr("class", "");
8566			}
8567
8568			if (typeof value === "string" && value) {
8569				classes = value.match(rnotwhite) || [];
8570
8571				while (elem = this[i++]) {
8572					curValue = getClass(elem);
8573
8574					// This expression is here for better compressibility (see addClass)
8575					cur = elem.nodeType === 1 && (" " + curValue + " ").replace(rclass, " ");
8576
8577					if (cur) {
8578						j = 0;
8579						while (clazz = classes[j++]) {
8580
8581							// Remove *all* instances
8582							while (cur.indexOf(" " + clazz + " ") > -1) {
8583								cur = cur.replace(" " + clazz + " ", " ");
8584							}
8585						}
8586
8587						// Only assign if different to avoid unneeded rendering.
8588						finalValue = jQuery.trim(cur);
8589						if (curValue !== finalValue) {
8590							jQuery.attr(elem, "class", finalValue);
8591						}
8592					}
8593				}
8594			}
8595
8596			return this;
8597		},
8598
8599		toggleClass: function (value, stateVal) {
8600			var type = typeof value;
8601
8602			if (typeof stateVal === "boolean" && type === "string") {
8603				return stateVal ? this.addClass(value) : this.removeClass(value);
8604			}
8605
8606			if (jQuery.isFunction(value)) {
8607				return this.each(function (i) {
8608					jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal);
8609				});
8610			}
8611
8612			return this.each(function () {
8613				var className, i, self, classNames;
8614
8615				if (type === "string") {
8616
8617					// Toggle individual class names
8618					i = 0;
8619					self = jQuery(this);
8620					classNames = value.match(rnotwhite) || [];
8621
8622					while (className = classNames[i++]) {
8623
8624						// Check each className given, space separated list
8625						if (self.hasClass(className)) {
8626							self.removeClass(className);
8627						} else {
8628							self.addClass(className);
8629						}
8630					}
8631
8632					// Toggle whole class name
8633				} else if (value === undefined || type === "boolean") {
8634					className = getClass(this);
8635					if (className) {
8636
8637						// store className if set
8638						jQuery._data(this, "__className__", className);
8639					}
8640
8641					// If the element has a class name or if we're passed "false",
8642					// then remove the whole classname (if there was one, the above saved it).
8643					// Otherwise bring back whatever was previously saved (if anything),
8644					// falling back to the empty string if nothing was stored.
8645					jQuery.attr(this, "class", className || value === false ? "" : jQuery._data(this, "__className__") || "");
8646				}
8647			});
8648		},
8649
8650		hasClass: function (selector) {
8651			var className,
8652			    elem,
8653			    i = 0;
8654
8655			className = " " + selector + " ";
8656			while (elem = this[i++]) {
8657				if (elem.nodeType === 1 && (" " + getClass(elem) + " ").replace(rclass, " ").indexOf(className) > -1) {
8658					return true;
8659				}
8660			}
8661
8662			return false;
8663		}
8664	});
8665
8666	// Return jQuery for attributes-only inclusion
8667
8668
8669	jQuery.each(("blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup error contextmenu").split(" "), function (i, name) {
8670
8671		// Handle event binding
8672		jQuery.fn[name] = function (data, fn) {
8673			return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name);
8674		};
8675	});
8676
8677	jQuery.fn.extend({
8678		hover: function (fnOver, fnOut) {
8679			return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
8680		}
8681	});
8682
8683	var location = window.location;
8684
8685	var nonce = jQuery.now();
8686
8687	var rquery = /\?/;
8688
8689	var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
8690
8691	jQuery.parseJSON = function (data) {
8692
8693		// Attempt to parse using the native JSON parser first
8694		if (window.JSON && window.JSON.parse) {
8695
8696			// Support: Android 2.3
8697			// Workaround failure to string-cast null input
8698			return window.JSON.parse(data + "");
8699		}
8700
8701		var requireNonComma,
8702		    depth = null,
8703		    str = jQuery.trim(data + "");
8704
8705		// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
8706		// after removing valid tokens
8707		return str && !jQuery.trim(str.replace(rvalidtokens, function (token, comma, open, close) {
8708
8709			// Force termination if we see a misplaced comma
8710			if (requireNonComma && comma) {
8711				depth = 0;
8712			}
8713
8714			// Perform no more replacements after returning to outermost depth
8715			if (depth === 0) {
8716				return token;
8717			}
8718
8719			// Commas must not follow "[", "{", or ","
8720			requireNonComma = open || comma;
8721
8722			// Determine new depth
8723			// array/object open ("[" or "{"): depth += true - false (increment)
8724			// array/object close ("]" or "}"): depth += false - true (decrement)
8725			// other cases ("," or primitive): depth += true - true (numeric cast)
8726			depth += !close - !open;
8727
8728			// Remove this token
8729			return "";
8730		})) ? Function("return " + str)() : jQuery.error("Invalid JSON: " + data);
8731	};
8732
8733	// Cross-browser xml parsing
8734	jQuery.parseXML = function (data) {
8735		var xml, tmp;
8736		if (!data || typeof data !== "string") {
8737			return null;
8738		}
8739		try {
8740			if (window.DOMParser) {
8741				// Standard
8742				tmp = new window.DOMParser();
8743				xml = tmp.parseFromString(data, "text/xml");
8744			} else {
8745				// IE
8746				xml = new window.ActiveXObject("Microsoft.XMLDOM");
8747				xml.async = "false";
8748				xml.loadXML(data);
8749			}
8750		} catch (e) {
8751			xml = undefined;
8752		}
8753		if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) {
8754			jQuery.error("Invalid XML: " + data);
8755		}
8756		return xml;
8757	};
8758
8759	var rhash = /#.*$/,
8760	    rts = /([?&])_=[^&]*/,
8761
8762
8763	// IE leaves an \r character at EOL
8764	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
8765
8766
vendor: 13,733 bytes, lines 8767-9311
8767	// #7653, #8125, #8152: local protocol detection
8768	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8769	    rnoContent = /^(?:GET|HEAD)$/,
8770	    rprotocol = /^\/\//,
8771	    rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
8772
8773
8774	/* Prefilters
8775  * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8776  * 2) These are called:
8777  *    - BEFORE asking for a transport
8778  *    - AFTER param serialization (s.data is a string if s.processData is true)
8779  * 3) key is the dataType
8780  * 4) the catchall symbol "*" can be used
8781  * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8782  */
8783	prefilters = {},
8784
8785
8786	/* Transports bindings
8787  * 1) key is the dataType
8788  * 2) the catchall symbol "*" can be used
8789  * 3) selection will start with transport dataType and THEN go to "*" if needed
8790  */
8791	transports = {},
8792
8793
8794	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8795	allTypes = "*/".concat("*"),
8796
8797
8798	// Document location
8799	ajaxLocation = location.href,
8800
8801
8802	// Segment location into parts
8803	ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];
8804
8805	// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8806	function addToPrefiltersOrTransports(structure) {
8807
8808		// dataTypeExpression is optional and defaults to "*"
8809		return function (dataTypeExpression, func) {
8810
8811			if (typeof dataTypeExpression !== "string") {
8812				func = dataTypeExpression;
8813				dataTypeExpression = "*";
8814			}
8815
8816			var dataType,
8817			    i = 0,
8818			    dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || [];
8819
8820			if (jQuery.isFunction(func)) {
8821
8822				// For each dataType in the dataTypeExpression
8823				while (dataType = dataTypes[i++]) {
8824
8825					// Prepend if requested
8826					if (dataType.charAt(0) === "+") {
8827						dataType = dataType.slice(1) || "*";
8828						(structure[dataType] = structure[dataType] || []).unshift(func);
8829
8830						// Otherwise append
8831					} else {
8832						(structure[dataType] = structure[dataType] || []).push(func);
8833					}
8834				}
8835			}
8836		};
8837	}
8838
8839	// Base inspection function for prefilters and transports
8840	function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
8841
8842		var inspected = {},
8843		    seekingTransport = structure === transports;
8844
8845		function inspect(dataType) {
8846			var selected;
8847			inspected[dataType] = true;
8848			jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
8849				var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
8850				if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
8851
8852					options.dataTypes.unshift(dataTypeOrTransport);
8853					inspect(dataTypeOrTransport);
8854					return false;
8855				} else if (seekingTransport) {
8856					return !(selected = dataTypeOrTransport);
8857				}
8858			});
8859			return selected;
8860		}
8861
8862		return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
8863	}
8864
8865	// A special extend for ajax options
8866	// that takes "flat" options (not to be deep extended)
8867	// Fixes #9887
8868	function ajaxExtend(target, src) {
8869		var deep,
8870		    key,
8871		    flatOptions = jQuery.ajaxSettings.flatOptions || {};
8872
8873		for (key in src) {
8874			if (src[key] !== undefined) {
8875				(flatOptions[key] ? target : deep || (deep = {}))[key] = src[key];
8876			}
8877		}
8878		if (deep) {
8879			jQuery.extend(true, target, deep);
8880		}
8881
8882		return target;
8883	}
8884
8885	/* Handles responses to an ajax request:
8886  * - finds the right dataType (mediates between content-type and expected dataType)
8887  * - returns the corresponding response
8888  */
8889	function ajaxHandleResponses(s, jqXHR, responses) {
8890		var firstDataType,
8891		    ct,
8892		    finalDataType,
8893		    type,
8894		    contents = s.contents,
8895		    dataTypes = s.dataTypes;
8896
8897		// Remove auto dataType and get content-type in the process
8898		while (dataTypes[0] === "*") {
8899			dataTypes.shift();
8900			if (ct === undefined) {
8901				ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
8902			}
8903		}
8904
8905		// Check if we're dealing with a known content-type
8906		if (ct) {
8907			for (type in contents) {
8908				if (contents[type] && contents[type].test(ct)) {
8909					dataTypes.unshift(type);
8910					break;
8911				}
8912			}
8913		}
8914
8915		// Check to see if we have a response for the expected dataType
8916		if (dataTypes[0] in responses) {
8917			finalDataType = dataTypes[0];
8918		} else {
8919
8920			// Try convertible dataTypes
8921			for (type in responses) {
8922				if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
8923					finalDataType = type;
8924					break;
8925				}
8926				if (!firstDataType) {
8927					firstDataType = type;
8928				}
8929			}
8930
8931			// Or just use first one
8932			finalDataType = finalDataType || firstDataType;
8933		}
8934
8935		// If we found a dataType
8936		// We add the dataType to the list if needed
8937		// and return the corresponding response
8938		if (finalDataType) {
8939			if (finalDataType !== dataTypes[0]) {
8940				dataTypes.unshift(finalDataType);
8941			}
8942			return responses[finalDataType];
8943		}
8944	}
8945
8946	/* Chain conversions given the request and the original response
8947  * Also sets the responseXXX fields on the jqXHR instance
8948  */
8949	function ajaxConvert(s, response, jqXHR, isSuccess) {
8950		var conv2,
8951		    current,
8952		    conv,
8953		    tmp,
8954		    prev,
8955		    converters = {},
8956
8957
8958		// Work with a copy of dataTypes in case we need to modify it for conversion
8959		dataTypes = s.dataTypes.slice();
8960
8961		// Create converters map with lowercased keys
8962		if (dataTypes[1]) {
8963			for (conv in s.converters) {
8964				converters[conv.toLowerCase()] = s.converters[conv];
8965			}
8966		}
8967
8968		current = dataTypes.shift();
8969
8970		// Convert to each sequential dataType
8971		while (current) {
8972
8973			if (s.responseFields[current]) {
8974				jqXHR[s.responseFields[current]] = response;
8975			}
8976
8977			// Apply the dataFilter if provided
8978			if (!prev && isSuccess && s.dataFilter) {
8979				response = s.dataFilter(response, s.dataType);
8980			}
8981
8982			prev = current;
8983			current = dataTypes.shift();
8984
8985			if (current) {
8986
8987				// There's only work to do if current dataType is non-auto
8988				if (current === "*") {
8989
8990					current = prev;
8991
8992					// Convert response if prev dataType is non-auto and differs from current
8993				} else if (prev !== "*" && prev !== current) {
8994
8995					// Seek a direct converter
8996					conv = converters[prev + " " + current] || converters["* " + current];
8997
8998					// If none found, seek a pair
8999					if (!conv) {
9000						for (conv2 in converters) {
9001
9002							// If conv2 outputs current
9003							tmp = conv2.split(" ");
9004							if (tmp[1] === current) {
9005
9006								// If prev can be converted to accepted input
9007								conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]];
9008								if (conv) {
9009
9010									// Condense equivalence converters
9011									if (conv === true) {
9012										conv = converters[conv2];
9013
9014										// Otherwise, insert the intermediate dataType
9015									} else if (converters[conv2] !== true) {
9016										current = tmp[0];
9017										dataTypes.unshift(tmp[1]);
9018									}
9019									break;
9020								}
9021							}
9022						}
9023					}
9024
9025					// Apply converter (if not an equivalence)
9026					if (conv !== true) {
9027
9028						// Unless errors are allowed to bubble, catch and return them
9029						if (conv && s["throws"]) {
9030							// jscs:ignore requireDotNotation
9031							response = conv(response);
9032						} else {
9033							try {
9034								response = conv(response);
9035							} catch (e) {
9036								return {
9037									state: "parsererror",
9038									error: conv ? e : "No conversion from " + prev + " to " + current
9039								};
9040							}
9041						}
9042					}
9043				}
9044			}
9045		}
9046
9047		return { state: "success", data: response };
9048	}
9049
9050	jQuery.extend({
9051
9052		// Counter for holding the number of active queries
9053		active: 0,
9054
9055		// Last-Modified header cache for next request
9056		lastModified: {},
9057		etag: {},
9058
9059		ajaxSettings: {
9060			url: ajaxLocation,
9061			type: "GET",
9062			isLocal: rlocalProtocol.test(ajaxLocParts[1]),
9063			global: true,
9064			processData: true,
9065			async: true,
9066			contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9067			/*
9068   timeout: 0,
9069   data: null,
9070   dataType: null,
9071   username: null,
9072   password: null,
9073   cache: null,
9074   throws: false,
9075   traditional: false,
9076   headers: {},
9077   */
9078
9079			accepts: {
9080				"*": allTypes,
9081				text: "text/plain",
9082				html: "text/html",
9083				xml: "application/xml, text/xml",
9084				json: "application/json, text/javascript"
9085			},
9086
9087			contents: {
9088				xml: /\bxml\b/,
9089				html: /\bhtml/,
9090				json: /\bjson\b/
9091			},
9092
9093			responseFields: {
9094				xml: "responseXML",
9095				text: "responseText",
9096				json: "responseJSON"
9097			},
9098
9099			// Data converters
9100			// Keys separate source (or catchall "*") and destination types with a single space
9101			converters: {
9102
9103				// Convert anything to text
9104				"* text": String,
9105
9106				// Text to html (true = no transformation)
9107				"text html": true,
9108
9109				// Evaluate text as a json expression
9110				"text json": jQuery.parseJSON,
9111
9112				// Parse text as xml
9113				"text xml": jQuery.parseXML
9114			},
9115
9116			// For options that shouldn't be deep extended:
9117			// you can add your own custom options here if
9118			// and when you create one that shouldn't be
9119			// deep extended (see ajaxExtend)
9120			flatOptions: {
9121				url: true,
9122				context: true
9123			}
9124		},
9125
9126		// Creates a full fledged settings object into target
9127		// with both ajaxSettings and settings fields.
9128		// If target is omitted, writes into ajaxSettings.
9129		ajaxSetup: function (target, settings) {
9130			return settings ?
9131
9132			// Building a settings object
9133			ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
9134
9135			// Extending ajaxSettings
9136			ajaxExtend(jQuery.ajaxSettings, target);
9137		},
9138
9139		ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
9140		ajaxTransport: addToPrefiltersOrTransports(transports),
9141
9142		// Main method
9143		ajax: function (url, options) {
9144
9145			// If url is an object, simulate pre-1.5 signature
9146			if (typeof url === "object") {
9147				options = url;
9148				url = undefined;
9149			}
9150
9151			// Force options to be an object
9152			options = options || {};
9153
9154			var
9155
9156			// Cross-domain detection vars
9157			parts,
9158
9159
9160			// Loop variable
9161			i,
9162
9163
9164			// URL without anti-cache param
9165			cacheURL,
9166
9167
9168			// Response headers as string
9169			responseHeadersString,
9170
9171
9172			// timeout handle
9173			timeoutTimer,
9174
9175
9176			// To know if global events are to be dispatched
9177			fireGlobals,
9178			    transport,
9179
9180
9181			// Response headers
9182			responseHeaders,
9183
9184
9185			// Create the final options object
9186			s = jQuery.ajaxSetup({}, options),
9187
9188
9189			// Callbacks context
9190			callbackContext = s.context || s,
9191
9192
9193			// Context for global events is callbackContext if it is a DOM node or jQuery collection
9194			globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event,
9195
9196
9197			// Deferreds
9198			deferred = jQuery.Deferred(),
9199			    completeDeferred = jQuery.Callbacks("once memory"),
9200
9201
9202			// Status-dependent callbacks
9203			statusCode = s.statusCode || {},
9204
9205
9206			// Headers (they are sent all at once)
9207			requestHeaders = {},
9208			    requestHeadersNames = {},
9209
9210
9211			// The jqXHR state
9212			state = 0,
9213
9214
9215			// Default abort message
9216			strAbort = "canceled",
9217
9218
9219			// Fake xhr
9220			jqXHR = {
9221				readyState: 0,
9222
9223				// Builds headers hashtable if needed
9224				getResponseHeader: function (key) {
9225					var match;
9226					if (state === 2) {
9227						if (!responseHeaders) {
9228							responseHeaders = {};
9229							while (match = rheaders.exec(responseHeadersString)) {
9230								responseHeaders[match[1].toLowerCase()] = match[2];
9231							}
9232						}
9233						match = responseHeaders[key.toLowerCase()];
9234					}
9235					return match == null ? null : match;
9236				},
9237
9238				// Raw string
9239				getAllResponseHeaders: function () {
9240					return state === 2 ? responseHeadersString : null;
9241				},
9242
9243				// Caches the header
9244				setRequestHeader: function (name, value) {
9245					var lname = name.toLowerCase();
9246					if (!state) {
9247						name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;
9248						requestHeaders[name] = value;
9249					}
9250					return this;
9251				},
9252
9253				// Overrides response content-type header
9254				overrideMimeType: function (type) {
9255					if (!state) {
9256						s.mimeType = type;
9257					}
9258					return this;
9259				},
9260
9261				// Status-dependent callbacks
9262				statusCode: function (map) {
9263					var code;
9264					if (map) {
9265						if (state < 2) {
9266							for (code in map) {
9267
9268								// Lazy-add the new callback in a way that preserves old ones
9269								statusCode[code] = [statusCode[code], map[code]];
9270							}
9271						} else {
9272
9273							// Execute the appropriate callbacks
9274							jqXHR.always(map[jqXHR.status]);
9275						}
9276					}
9277					return this;
9278				},
9279
9280				// Cancel the request
9281				abort: function (statusText) {
9282					var finalText = statusText || strAbort;
9283					if (transport) {
9284						transport.abort(finalText);
9285					}
9286					done(0, finalText);
9287					return this;
9288				}
9289			};
9290
9291			// Attach deferreds
9292			deferred.promise(jqXHR).complete = completeDeferred.add;
9293			jqXHR.success = jqXHR.done;
9294			jqXHR.error = jqXHR.fail;
9295
9296			// Remove hash character (#7531: and string promotion)
9297			// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9298			// Handle falsy url in the settings object (#10093: consistency with old signature)
9299			// We also use the url parameter if available
9300			s.url = ((url || s.url || ajaxLocation) + "").replace(rhash, "").replace(rprotocol, ajaxLocParts[1] + "//");
9301
9302			// Alias method option to type as per ticket #12004
9303			s.type = options.method || options.type || s.method || s.type;
9304
9305			// Extract dataTypes list
9306			s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(rnotwhite) || [""];
9307
9308			// A cross-domain request is in order when we have a protocol:host:port mismatch
9309			if (s.crossDomain == null) {
9310				parts = rurl.exec(s.url.toLowerCase());
9311				s.crossDomain = !!(parts && (parts[1] !== ajaxLocParts[1] || parts[2] !== ajaxLocParts[2] || (parts[3] || (parts[1] === "http:" ? "80" : "443")) !== (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? "80" : "443")))
vendor: 9,321 bytes, lines 9311-9682
9311);
9312			}
9313
9314			// Convert data if not already a string
9315			if (s.data && s.processData && typeof s.data !== "string") {
9316				s.data = jQuery.param(s.data, s.traditional);
9317			}
9318
9319			// Apply prefilters
9320			inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
9321
9322			// If request was aborted inside a prefilter, stop there
9323			if (state === 2) {
9324				return jqXHR;
9325			}
9326
9327			// We can fire global events as of now if asked to
9328			// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9329			fireGlobals = jQuery.event && s.global;
9330
9331			// Watch for a new set of requests
9332			if (fireGlobals && jQuery.active++ === 0) {
9333				jQuery.event.trigger("ajaxStart");
9334			}
9335
9336			// Uppercase the type
9337			s.type = s.type.toUpperCase();
9338
9339			// Determine if request has content
9340			s.hasContent = !rnoContent.test(s.type);
9341
9342			// Save the URL in case we're toying with the If-Modified-Since
9343			// and/or If-None-Match header later on
9344			cacheURL = s.url;
9345
9346			// More options handling for requests with no content
9347			if (!s.hasContent) {
9348
9349				// If data is available, append data to url
9350				if (s.data) {
9351					cacheURL = s.url += (rquery.test(cacheURL) ? "&" : "?") + s.data;
9352
9353					// #9682: remove data so that it's not used in an eventual retry
9354					delete s.data;
9355				}
9356
9357				// Add anti-cache in url if needed
9358				if (s.cache === false) {
9359					s.url = rts.test(cacheURL) ?
9360
9361					// If there is already a '_' parameter, set its value
9362					cacheURL.replace(rts, "$1_=" + nonce++) :
9363
9364					// Otherwise add one to the end
9365					cacheURL + (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++;
9366				}
9367			}
9368
9369			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9370			if (s.ifModified) {
9371				if (jQuery.lastModified[cacheURL]) {
9372					jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
9373				}
9374				if (jQuery.etag[cacheURL]) {
9375					jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
9376				}
9377			}
9378
9379			// Set the correct header, if data is being sent
9380			if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
9381				jqXHR.setRequestHeader("Content-Type", s.contentType);
9382			}
9383
9384			// Set the Accepts header for the server, depending on the dataType
9385			jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]);
9386
9387			// Check for headers option
9388			for (i in s.headers) {
9389				jqXHR.setRequestHeader(i, s.headers[i]);
9390			}
9391
9392			// Allow custom headers/mimetypes and early abort
9393			if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) {
9394
9395				// Abort if not done already and return
9396				return jqXHR.abort();
9397			}
9398
9399			// aborting is no longer a cancellation
9400			strAbort = "abort";
9401
9402			// Install callbacks on deferreds
9403			for (i in { success: 1, error: 1, complete: 1 }) {
9404				jqXHR[i](s[i]);
9405			}
9406
9407			// Get transport
9408			transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
9409
9410			// If no transport, we auto-abort
9411			if (!transport) {
9412				done(-1, "No Transport");
9413			} else {
9414				jqXHR.readyState = 1;
9415
9416				// Send global event
9417				if (fireGlobals) {
9418					globalEventContext.trigger("ajaxSend", [jqXHR, s]);
9419				}
9420
9421				// If request was aborted inside ajaxSend, stop there
9422				if (state === 2) {
9423					return jqXHR;
9424				}
9425
9426				// Timeout
9427				if (s.async && s.timeout > 0) {
9428					timeoutTimer = window.setTimeout(function () {
9429						jqXHR.abort("timeout");
9430					}, s.timeout);
9431				}
9432
9433				try {
9434					state = 1;
9435					transport.send(requestHeaders, done);
9436				} catch (e) {
9437
9438					// Propagate exception as error if not done
9439					if (state < 2) {
9440						done(-1, e);
9441
9442						// Simply rethrow otherwise
9443					} else {
9444						throw e;
9445					}
9446				}
9447			}
9448
9449			// Callback for when everything is done
9450			function done(status, nativeStatusText, responses, headers) {
9451				var isSuccess,
9452				    success,
9453				    error,
9454				    response,
9455				    modified,
9456				    statusText = nativeStatusText;
9457
9458				// Called once
9459				if (state === 2) {
9460					return;
9461				}
9462
9463				// State is "done" now
9464				state = 2;
9465
9466				// Clear timeout if it exists
9467				if (timeoutTimer) {
9468					window.clearTimeout(timeoutTimer);
9469				}
9470
9471				// Dereference transport for early garbage collection
9472				// (no matter how long the jqXHR object will be used)
9473				transport = undefined;
9474
9475				// Cache response headers
9476				responseHeadersString = headers || "";
9477
9478				// Set readyState
9479				jqXHR.readyState = status > 0 ? 4 : 0;
9480
9481				// Determine if successful
9482				isSuccess = status >= 200 && status < 300 || status === 304;
9483
9484				// Get response data
9485				if (responses) {
9486					response = ajaxHandleResponses(s, jqXHR, responses);
9487				}
9488
9489				// Convert no matter what (that way responseXXX fields are always set)
9490				response = ajaxConvert(s, response, jqXHR, isSuccess);
9491
9492				// If successful, handle type chaining
9493				if (isSuccess) {
9494
9495					// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9496					if (s.ifModified) {
9497						modified = jqXHR.getResponseHeader("Last-Modified");
9498						if (modified) {
9499							jQuery.lastModified[cacheURL] = modified;
9500						}
9501						modified = jqXHR.getResponseHeader("etag");
9502						if (modified) {
9503							jQuery.etag[cacheURL] = modified;
9504						}
9505					}
9506
9507					// if no content
9508					if (status === 204 || s.type === "HEAD") {
9509						statusText = "nocontent";
9510
9511						// if not modified
9512					} else if (status === 304) {
9513						statusText = "notmodified";
9514
9515						// If we have data, let's convert it
9516					} else {
9517						statusText = response.state;
9518						success = response.data;
9519						error = response.error;
9520						isSuccess = !error;
9521					}
9522				} else {
9523
9524					// We extract error from statusText
9525					// then normalize statusText and status for non-aborts
9526					error = statusText;
9527					if (status || !statusText) {
9528						statusText = "error";
9529						if (status < 0) {
9530							status = 0;
9531						}
9532					}
9533				}
9534
9535				// Set data for the fake xhr object
9536				jqXHR.status = status;
9537				jqXHR.statusText = (nativeStatusText || statusText) + "";
9538
9539				// Success/Error
9540				if (isSuccess) {
9541					deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
9542				} else {
9543					deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
9544				}
9545
9546				// Status-dependent callbacks
9547				jqXHR.statusCode(statusCode);
9548				statusCode = undefined;
9549
9550				if (fireGlobals) {
9551					globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);
9552				}
9553
9554				// Complete
9555				completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
9556
9557				if (fireGlobals) {
9558					globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
9559
9560					// Handle the global AJAX counter
9561					if (! --jQuery.active) {
9562						jQuery.event.trigger("ajaxStop");
9563					}
9564				}
9565			}
9566
9567			return jqXHR;
9568		},
9569
9570		getJSON: function (url, data, callback) {
9571			return jQuery.get(url, data, callback, "json");
9572		},
9573
9574		getScript: function (url, callback) {
9575			return jQuery.get(url, undefined, callback, "script");
9576		}
9577	});
9578
9579	jQuery.each(["get", "post"], function (i, method) {
9580		jQuery[method] = function (url, data, callback, type) {
9581
9582			// shift arguments if data argument was omitted
9583			if (jQuery.isFunction(data)) {
9584				type = type || callback;
9585				callback = data;
9586				data = undefined;
9587			}
9588
9589			// The url can be an options object (which then must have .url)
9590			return jQuery.ajax(jQuery.extend({
9591				url: url,
9592				type: method,
9593				dataType: type,
9594				data: data,
9595				success: callback
9596			}, jQuery.isPlainObject(url) && url));
9597		};
9598	});
9599
9600	jQuery._evalUrl = function (url) {
9601		return jQuery.ajax({
9602			url: url,
9603
9604			// Make this explicit, since user can override this through ajaxSetup (#11264)
9605			type: "GET",
9606			dataType: "script",
9607			cache: true,
9608			async: false,
9609			global: false,
9610			"throws": true
9611		});
9612	};
9613
9614	jQuery.fn.extend({
9615		wrapAll: function (html) {
9616			if (jQuery.isFunction(html)) {
9617				return this.each(function (i) {
9618					jQuery(this).wrapAll(html.call(this, i));
9619				});
9620			}
9621
9622			if (this[0]) {
9623
9624				// The elements to wrap the target around
9625				var wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
9626
9627				if (this[0].parentNode) {
9628					wrap.insertBefore(this[0]);
9629				}
9630
9631				wrap.map(function () {
9632					var elem = this;
9633
9634					while (elem.firstChild && elem.firstChild.nodeType === 1) {
9635						elem = elem.firstChild;
9636					}
9637
9638					return elem;
9639				}).append(this);
9640			}
9641
9642			return this;
9643		},
9644
9645		wrapInner: function (html) {
9646			if (jQuery.isFunction(html)) {
9647				return this.each(function (i) {
9648					jQuery(this).wrapInner(html.call(this, i));
9649				});
9650			}
9651
9652			return this.each(function () {
9653				var self = jQuery(this),
9654				    contents = self.contents();
9655
9656				if (contents.length) {
9657					contents.wrapAll(html);
9658				} else {
9659					self.append(html);
9660				}
9661			});
9662		},
9663
9664		wrap: function (html) {
9665			var isFunction = jQuery.isFunction(html);
9666
9667			return this.each(function (i) {
9668				jQuery(this).wrapAll(isFunction ? html.call(this, i) : html);
9669			});
9670		},
9671
9672		unwrap: function () {
9673			return this.parent().each(function () {
9674				if (!jQuery.nodeName(this, "body")) {
9675					jQuery(this).replaceWith(this.childNodes);
9676				}
9677			}).end();
9678		}
9679	});
9680
9681	function getDisplay(elem) {
9682		return elem.style && elem.style.display || jQuery.css(elem, "dis
9682play");
9683	}
9684
9685	function filterHidden(elem) {
9686
9687		// Disconnected elements are considered hidden
9688		if (!jQuery.contains(elem.ownerDocument || document, elem)) {
9689			return true;
9690		}
9691		while (elem && elem.nodeType === 1) {
9692			if (getDisplay(elem) === "none" || elem.type === "hidden") {
9693				return true;
9694			}
9695			elem = elem.parentNode;
9696		}
9697		return false;
9698	}
9699
9700	jQuery.expr.filters.hidden = function (elem) {
9701
9702		// Support: Opera <= 12.12
9703		// Opera reports offsetWidths and offsetHeights less than zero on some elements
9704		return support.reliableHiddenOffsets() ? elem.offsetWidth <= 0 && elem.offsetHeight <= 0 && !elem.getClientRects().length : filterHidden(elem);
9705	};
9706
9707	jQuery.expr.filters.visible = function (elem) {
9708		return !jQuery.expr.filters.hidden(elem);
9709	};
9710
9711	var r20 = /%20/g,
9712	    rbracket = /\[\]$/,
9713	    rCRLF = /\r?\n/g,
9714	    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
9715	    rsubmittable = /^(?:input|select|textarea|keygen)/i;
9716
9717	function buildParams(prefix, obj, traditional, add) {
9718		var name;
9719
9720		if (jQuery.isArray(obj)) {
9721
9722			// Serialize array item.
9723			jQuery.each(obj, function (i, v) {
9724				if (traditional || rbracket.test(prefix)) {
9725
9726					// Treat each array item as a scalar.
9727					add(prefix, v);
9728				} else {
9729
9730					// Item is non-scalar (array or object), encode its numeric index.
9731					buildParams(prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]", v, traditional, add);
9732				}
9733			});
9734		} else if (!traditional && jQuery.type(obj) === "object") {
9735
9736			// Serialize object item.
9737			for (name in obj) {
9738				buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
9739			}
9740		} else {
9741
9742			// Serialize scalar item.
9743			add(prefix, obj);
9744		}
9745	}
9746
9747	// Serialize an array of form elements or a set of
9748	// key/values into a query string
9749	jQuery.param = function (a, traditional) {
9750		var prefix,
9751		    s = [],
9752		    add = function (key, value) {
9753
9754			// If value is a function, invoke it and return its value
9755			value = jQuery.isFunction(value) ? value() : value == null ? "" : value;
9756			s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
9757		};
9758
9759		// Set traditional to true for jQuery <= 1.3.2 behavior.
9760		if (traditional === undefined) {
9761			traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
9762		}
9763
9764		// If an array was passed in, assume that it is an array of form elements.
9765		if (jQuery.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {
9766
9767			// Serialize the form elements
9768			jQuery.each(a, function () {
9769				add(this.name, this.value);
9770			});
9771		} else {
9772
9773			// If traditional, encode the "old" way (the way 1.3.2 or older
9774			// did it), otherwise encode params recursively.
9775			for (prefix in a) {
9776				buildParams(prefix, a[prefix], traditional, add);
9777			}
9778		}
9779
9780		// Return the resulting serialization
9781		return s.join("&").replace(r20, "+");
9782	};
9783
9784	jQuery.fn.extend({
9785		serialize: function () {
9786			return jQuery.param(this.serializeArray());
9787		},
9788		serializeArray: function () {
9789			return this.map(function () {
9790
9791				// Can add propHook for "elements" to filter or add form elements
9792				var elements = jQuery.prop(this, "elements");
9793				return elements ? jQuery.makeArray(elements) : this;
9794			}).filter(function () {
9795				var type = this.type;
9796
9797				// Use .is(":disabled") so that fieldset[disabled] works
9798				return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type));
9799			}).map(function (i, elem) {
9800				var val = jQuery(this).val();
9801
9802				return val == null ? null : jQuery.isArray(val) ? jQuery.map(val, function (val) {
9803					return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
9804				}) : { name: elem.name, value: val.replace(rCRLF, "\r\n") };
9805			}).get();
9806		}
9807	});
9808
9809	// Create the request object
9810	// (This is still attached to ajaxSettings for backward compatibility)
9811	jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
9812
9813	// Support: IE6-IE8
9814	function () {
9815
9816		// XHR cannot access local files, always use ActiveX for that case
9817		if (this.isLocal) {
9818			return createActiveXHR();
9819		}
9820
9821		// Support: IE 9-11
9822		// IE seems to error on cross-domain PATCH requests when ActiveX XHR
9823		// is used. In IE 9+ always use the native XHR.
9824		// Note: this condition won't catch Edge as it doesn't define
9825		// document.documentMode but it also doesn't support ActiveX so it won't
9826		// reach this code.
9827		if (document.documentMode > 8) {
9828			return createStandardXHR();
9829		}
9830
9831		// Support: IE<9
9832		// oldIE XHR does not support non-RFC2616 methods (#13240)
9833		// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
9834		// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
9835		// Although this check for six methods instead of eight
9836		// since IE also does not support "trace" and "connect"
9837		return (/^(get|post|head|put|delete|options)$/i.test(this.type) && createStandardXHR() || createActiveXHR()
9838		);
9839	} :
9840
9841	// For all other browsers, use the standard XMLHttpRequest object
9842	createStandardXHR;
9843
9844	var xhrId = 0,
9845	    xhrCallbacks = {},
9846	    xhrSupported = jQuery.ajaxSettings.xhr();
9847
9848	// Support: IE<10
9849	// Open requests must be manually aborted on unload (#5280)
9850	// See https://support.microsoft.com/kb/2856746 for more info
9851	if (window.attachEvent) {
9852		window.attachEvent("onunload", function () {
9853			for (var key in xhrCallbacks) {
9854				xhrCallbacks[key](undefined, true);
9855			}
9856		});
9857	}
9858
9859	// Determine support properties
9860	support.cors = !!xhrSupported && "withCredentials" in xhrSupported;
9861	xhrSupported = support.ajax = !!xhrSupported;
9862
9863	// Create transport if the browser can provide an xhr
9864	if (xhrSupported) {
9865
9866		jQuery.ajaxTransport(function (options) {
9867
9868			// Cross domain only allowed if supported through XMLHttpRequest
9869			if (!options.crossDomain || support.cors) {
9870
9871				var callback;
9872
9873				return {
9874					send: function (headers, complete) {
9875						var i,
9876						    xhr = options.xhr(),
9877						    id = ++xhrId;
9878
9879						// Open the socket
9880						xhr.open(options.type, options.url, options.async, options.username, options.password);
9881
9882						// Apply custom fields if provided
9883						if (options.xhrFields) {
9884							for (i in options.xhrFields) {
9885								xhr[i] = options.xhrFields[i];
9886							}
9887						}
9888
9889						// Override mime type if needed
9890						if (options.mimeType && xhr.overrideMimeType) {
9891							xhr.overrideMimeType(options.mimeType);
9892						}
9893
9894						// X-Requested-With header
9895						// For cross-domain requests, seeing as conditions for a preflight are
9896						// akin to a jigsaw puzzle, we simply never set it to be sure.
9897						// (it can always be set on a per-request basis or even using ajaxSetup)
vendor: 8,552 bytes, lines 9898-10207
9898						// For same-domain requests, won't change header if already provided.
9899						if (!options.crossDomain && !headers["X-Requested-With"]) {
9900							headers["X-Requested-With"] = "XMLHttpRequest";
9901						}
9902
9903						// Set headers
9904						for (i in headers) {
9905
9906							// Support: IE<9
9907							// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
9908							// request header to a null-value.
9909							//
9910							// To keep consistent with other XHR implementations, cast the value
9911							// to string and ignore `undefined`.
9912							if (headers[i] !== undefined) {
9913								xhr.setRequestHeader(i, headers[i] + "");
9914							}
9915						}
9916
9917						// Do send the request
9918						// This may raise an exception which is actually
9919						// handled in jQuery.ajax (so no try/catch here)
9920						xhr.send(options.hasContent && options.data || null);
9921
9922						// Listener
9923						callback = function (_, isAbort) {
9924							var status, statusText, responses;
9925
9926							// Was never called and is aborted or complete
9927							if (callback && (isAbort || xhr.readyState === 4)) {
9928
9929								// Clean up
9930								delete xhrCallbacks[id];
9931								callback = undefined;
9932								xhr.onreadystatechange = jQuery.noop;
9933
9934								// Abort manually if needed
9935								if (isAbort) {
9936									if (xhr.readyState !== 4) {
9937										xhr.abort();
9938									}
9939								} else {
9940									responses = {};
9941									status = xhr.status;
9942
9943									// Support: IE<10
9944									// Accessing binary-data responseText throws an exception
9945									// (#11426)
9946									if (typeof xhr.responseText === "string") {
9947										responses.text = xhr.responseText;
9948									}
9949
9950									// Firefox throws an exception when accessing
9951									// statusText for faulty cross-domain requests
9952									try {
9953										statusText = xhr.statusText;
9954									} catch (e) {
9955
9956										// We normalize with Webkit giving an empty statusText
9957										statusText = "";
9958									}
9959
9960									// Filter status for non standard behaviors
9961
9962									// If the request is local and we have data: assume a success
9963									// (success with no data won't get notified, that's the best we
9964									// can do given current implementations)
9965									if (!status && options.isLocal && !options.crossDomain) {
9966										status = responses.text ? 200 : 404;
9967
9968										// IE - #1450: sometimes returns 1223 when it should be 204
9969									} else if (status === 1223) {
9970										status = 204;
9971									}
9972								}
9973							}
9974
9975							// Call complete if needed
9976							if (responses) {
9977								complete(status, statusText, responses, xhr.getAllResponseHeaders());
9978							}
9979						};
9980
9981						// Do send the request
9982						// `xhr.send` may raise an exception, but it will be
9983						// handled in jQuery.ajax (so no try/catch here)
9984						if (!options.async) {
9985
9986							// If we're in sync mode we fire the callback
9987							callback();
9988						} else if (xhr.readyState === 4) {
9989
9990							// (IE6 & IE7) if it's in cache and has been
9991							// retrieved directly we need to fire the callback
9992							window.setTimeout(callback);
9993						} else {
9994
9995							// Register the callback, but delay it in case `xhr.send` throws
9996							// Add to the list of active xhr callbacks
9997							xhr.onreadystatechange = xhrCallbacks[id] = callback;
9998						}
9999					},
10000
10001					abort: function () {
10002						if (callback) {
10003							callback(undefined, true);
10004						}
10005					}
10006				};
10007			}
10008		});
10009	}
10010
10011	// Functions to create xhrs
10012	function createStandardXHR() {
10013		try {
10014			return new window.XMLHttpRequest();
10015		} catch (e) {}
10016	}
10017
10018	function createActiveXHR() {
10019		try {
10020			return new window.ActiveXObject("Microsoft.XMLHTTP");
10021		} catch (e) {}
10022	}
10023
10024	// Install script dataType
10025	jQuery.ajaxSetup({
10026		accepts: {
10027			script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript"
10028		},
10029		contents: {
10030			script: /\b(?:java|ecma)script\b/
10031		},
10032		converters: {
10033			"text script": function (text) {
10034				jQuery.globalEval(text);
10035				return text;
10036			}
10037		}
10038	});
10039
10040	// Handle cache's special case and global
10041	jQuery.ajaxPrefilter("script", function (s) {
10042		if (s.cache === undefined) {
10043			s.cache = false;
10044		}
10045		if (s.crossDomain) {
10046			s.type = "GET";
10047			s.global = false;
10048		}
10049	});
10050
10051	// Bind script tag hack transport
10052	jQuery.ajaxTransport("script", function (s) {
10053
10054		// This transport only deals with cross domain requests
10055		if (s.crossDomain) {
10056
10057			var script,
10058			    head = document.head || jQuery("head")[0] || document.documentElement;
10059
10060			return {
10061
10062				send: function (_, callback) {
10063
10064					script = document.createElement("script");
10065
10066					script.async = true;
10067
10068					if (s.scriptCharset) {
10069						script.charset = s.scriptCharset;
10070					}
10071
10072					script.src = s.url;
10073
10074					// Attach handlers for all browsers
10075					script.onload = script.onreadystatechange = function (_, isAbort) {
10076
10077						if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {
10078
10079							// Handle memory leak in IE
10080							script.onload = script.onreadystatechange = null;
10081
10082							// Remove the script
10083							if (script.parentNode) {
10084								script.parentNode.removeChild(script);
10085							}
10086
10087							// Dereference the script
10088							script = null;
10089
10090							// Callback if not abort
10091							if (!isAbort) {
10092								callback(200, "success");
10093							}
10094						}
10095					};
10096
10097					// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
10098					// Use native DOM manipulation to avoid our domManip AJAX trickery
10099					head.insertBefore(script, head.firstChild);
10100				},
10101
10102				abort: function () {
10103					if (script) {
10104						script.onload(undefined, true);
10105					}
10106				}
10107			};
10108		}
10109	});
10110
10111	var oldCallbacks = [],
10112	    rjsonp = /(=)\?(?=&|$)|\?\?/;
10113
10114	// Default jsonp settings
10115	jQuery.ajaxSetup({
10116		jsonp: "callback",
10117		jsonpCallback: function () {
10118			var callback = oldCallbacks.pop() || jQuery.expando + "_" + nonce++;
10119			this[callback] = true;
10120			return callback;
10121		}
10122	});
10123
10124	// Detect, normalize options and install callbacks for jsonp requests
10125	jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {
10126
10127		var callbackName,
10128		    overwritten,
10129		    responseContainer,
10130		    jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url" : typeof s.data === "string" && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0 && rjsonp.test(s.data) && "data");
10131
10132		// Handle iff the expected data type is "jsonp" or we have a parameter to set
10133		if (jsonProp || s.dataTypes[0] === "jsonp") {
10134
10135			// Get callback name, remembering preexisting value associated with it
10136			callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback;
10137
10138			// Insert callback into url or form data
10139			if (jsonProp) {
10140				s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
10141			} else if (s.jsonp !== false) {
10142				s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
10143			}
10144
10145			// Use data converter to retrieve json after script execution
10146			s.converters["script json"] = function () {
10147				if (!responseContainer) {
10148					jQuery.error(callbackName + " was not called");
10149				}
10150				return responseContainer[0];
10151			};
10152
10153			// force json dataType
10154			s.dataTypes[0] = "json";
10155
10156			// Install callback
10157			overwritten = window[callbackName];
10158			window[callbackName] = function () {
10159				responseContainer = arguments;
10160			};
10161
10162			// Clean-up function (fires after converters)
10163			jqXHR.always(function () {
10164
10165				// If previous value didn't exist - remove it
10166				if (overwritten === undefined) {
10167					jQuery(window).removeProp(callbackName);
10168
10169					// Otherwise restore preexisting value
10170				} else {
10171					window[callbackName] = overwritten;
10172				}
10173
10174				// Save back as free
10175				if (s[callbackName]) {
10176
10177					// make sure that re-using the options doesn't screw things around
10178					s.jsonpCallback = originalSettings.jsonpCallback;
10179
10180					// save the callback name for future use
10181					oldCallbacks.push(callbackName);
10182				}
10183
10184				// Call if it was a function and we have a response
10185				if (responseContainer && jQuery.isFunction(overwritten)) {
10186					overwritten(responseContainer[0]);
10187				}
10188
10189				responseContainer = overwritten = undefined;
10190			});
10191
10192			// Delegate to script
10193			return "script";
10194		}
10195	});
10196
10197	// data: string of html
10198	// context (optional): If specified, the fragment will be created in this context,
10199	// defaults to document
10200	// keepScripts (optional): If true, will include scripts passed in the html string
10201	jQuery.parseHTML = function (data, context, keepScripts) {
10202		if (!data || typeof data !== "string") {
10203			return null;
10204		}
10205		if (typeof context === "boolean") {
10206			keepScripts = context;
10207			context = false;
10208		}
10209		context = context || document;
10210
10211		var parsed = rsingleTag.exec(data),
10212		    scripts = !keepScripts && [];
10213
10214		// Single tag
10215		if (parsed) {
10216			return [context.createElement(parsed[1])];
10217		}
10218
10219		parsed = buildFragment([data], context, scripts);
10220
10221		if (scripts && scripts.length) {
10222			jQuery(scripts).remove();
10223		}
10224
10225		return jQuery.merge([], parsed.childNodes);
10226	};
10227
10228	// Keep a copy of the old load method
10229	var _load = jQuery.fn.load;
10230
10231	/**
10232  * Load a url into a page
10233  */
10234	jQuery.fn.load = function (url, params, callback) {
10235		if (typeof url !== "string" && _load) {
10236			return _load.apply(this, arguments);
10237		}
10238
10239		var selector,
10240		    type,
10241		    response,
10242		    self = this,
10243		    off = url.indexOf(" ");
10244
10245		if (off > -1) {
10246			selector = jQuery.trim(url.slice(off, url.length));
10247			url = url.slice(0, off);
10248		}
10249
10250		// If it's a function
10251		if (jQuery.isFunction(params)) {
10252
10253			// We assume that it's the callback
10254			callback = params;
10255			params = undefined;
10256
10257			// Otherwise, build a param string
10258		} else if (params && typeof params === "object") {
10259			type = "POST";
10260		}
10261
10262		// If we have elements to modify, make the request
10263		if (self.length > 0) {
10264			jQuery.ajax({
10265				url: url,
10266
10267				// If "type" variable is undefined, then "GET" method will be used.
10268				// Make value of this field explicit since
10269				// user can override it through ajaxSetup method
10270				type: type || "GET",
10271				dataType: "html",
10272				data: params
10273			}).done(function (responseText) {
10274
10275				// Save response for use in complete callback
10276				response = arguments;
10277
10278				self.html(selector ?
10279
10280				// If a selector was specified, locate the right elements in a dummy div
10281				// Exclude scripts to avoid IE 'Permission Denied' errors
10282				jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
10283
10284				// Otherwise use the full result
10285				responseText);
10286
10287				// If the request succeeds, this function gets "data", "status", "jqXHR"
10288				// but they are ignored because response was set above.
10289				// If it fails, this function gets "jqXHR", "status", "error"
10290			}).always(callback && function (jqXHR, status) {
10291				self.each(function () {
10292					callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
10293				});
10294			});
10295		}
10296
10297		return this;
10298	};
10299
10300	// Attach a bunch of functions for handling common AJAX events
10301	jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (i, type) {
10302		jQuery.fn[type] = function (fn) {
10303			return this.on(type, fn);
10304		};
10305	});
10306
10307	jQuery.expr.filters.animated = function (elem) {
10308		return jQuery.grep(jQuery.timers, function (fn) {
10309			return elem === fn.elem;
10310		}).length;
10311	};
10312
10313	/**
10314  * Gets a window from an element
10315  */
10316	function getWindow(elem) {
10317		return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 ? elem.defaultView || elem.parentWindow : false;
10318	}
10319
10320	jQuery.offset = {
10321		setOffset: function (elem, options, i) {
10322			var curPosition,
10323			    curLeft,
10324			    curCSSTop,
10325			    curTop,
10326			    curOffset,
10327			    curCSSLeft,
10328			    calculatePosition,
10329			    position = jQuery.css(elem, "position"),
10330			    curElem = jQuery(elem),
10331			    props = {};
10332
10333			// set position first, in-case top/left are set even on static elem
10334			if (position === "static") {
10335				elem.style.position = "relative";
10336			}
10337
10338			curOffset = curElem.offset();
10339			curCSSTop = jQuery.css(elem, "top");
10340			curCSSLeft = jQuery.css(elem, "left");
10341			calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1;
10342
10343			// need to be able to calculate position if either top or left
10344			// is auto and position is either absolute or fixed
10345			if (calculatePosition) {
10346				curPosition = curElem.position();
10347				curTop = curPosition.top;
10348				curLeft = curPosition.left;
10349			} else {
10350				curTop = parseFloat(curCSSTop) || 0;
10351				curLeft = parseFloat(curCSSLeft) || 0;
10352			}
10353
10354			if (jQuery.isFunction(options)) {
10355
10356				// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10357				options = options.call(elem, i, jQuery.extend({}, curOffset));
10358			}
10359
10360			if (options.top != null) {
10361				props.top = options.top - curOffset.top + curTop;
10362			}
10363			if (options.left != null) {
10364				props.left = options.left - curOffset.left + curLeft;
10365			}
10366
10367			if ("using" in options) {
10368				options.using.call(elem, props);
10369			} else {
10370				curElem.css(props);
10371			}
10372		}
10373	};
10374
10375	jQuery.fn.extend({
10376		offset: function (options) {
10377			if (arguments.length) {
vendor: 8,365 bytes, lines 10378-10632
10378				return options === undefined ? this : this.each(function (i) {
10379					jQuery.offset.setOffset(this, options, i);
10380				});
10381			}
10382
10383			var docElem,
10384			    win,
10385			    box = { top: 0, left: 0 },
10386			    elem = this[0],
10387			    doc = elem && elem.ownerDocument;
10388
10389			if (!doc) {
10390				return;
10391			}
10392
10393			docElem = doc.documentElement;
10394
10395			// Make sure it's not a disconnected DOM node
10396			if (!jQuery.contains(docElem, elem)) {
10397				return box;
10398			}
10399
10400			// If we don't have gBCR, just use 0,0 rather than error
10401			// BlackBerry 5, iOS 3 (original iPhone)
10402			if (typeof elem.getBoundingClientRect !== "undefined") {
10403				box = elem.getBoundingClientRect();
10404			}
10405			win = getWindow(doc);
10406			return {
10407				top: box.top + (win.pageYOffset || docElem.scrollTop) - (docElem.clientTop || 0),
10408				left: box.left + (win.pageXOffset || docElem.scrollLeft) - (docElem.clientLeft || 0)
10409			};
10410		},
10411
10412		position: function () {
10413			if (!this[0]) {
10414				return;
10415			}
10416
10417			var offsetParent,
10418			    offset,
10419			    parentOffset = { top: 0, left: 0 },
10420			    elem = this[0];
10421
10422			// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
10423			// because it is its only offset parent
10424			if (jQuery.css(elem, "position") === "fixed") {
10425
10426				// we assume that getBoundingClientRect is available when computed position is fixed
10427				offset = elem.getBoundingClientRect();
10428			} else {
10429
10430				// Get *real* offsetParent
10431				offsetParent = this.offsetParent();
10432
10433				// Get correct offsets
10434				offset = this.offset();
10435				if (!jQuery.nodeName(offsetParent[0], "html")) {
10436					parentOffset = offsetParent.offset();
10437				}
10438
10439				// Add offsetParent borders
10440				parentOffset.top += jQuery.css(offsetParent[0], "borderTopWidth", true);
10441				parentOffset.left += jQuery.css(offsetParent[0], "borderLeftWidth", true);
10442			}
10443
10444			// Subtract parent offsets and element margins
10445			// note: when an element has margin: auto the offsetLeft and marginLeft
10446			// are the same in Safari causing offset.left to incorrectly be 0
10447			return {
10448				top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
10449				left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
10450			};
10451		},
10452
10453		offsetParent: function () {
10454			return this.map(function () {
10455				var offsetParent = this.offsetParent;
10456
10457				while (offsetParent && !jQuery.nodeName(offsetParent, "html") && jQuery.css(offsetParent, "position") === "static") {
10458					offsetParent = offsetParent.offsetParent;
10459				}
10460				return offsetParent || documentElement;
10461			});
10462		}
10463	});
10464
10465	// Create scrollLeft and scrollTop methods
10466	jQuery.each({ scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function (method, prop) {
10467		var top = /Y/.test(prop);
10468
10469		jQuery.fn[method] = function (val) {
10470			return access(this, function (elem, method, val) {
10471				var win = getWindow(elem);
10472
10473				if (val === undefined) {
10474					return win ? prop in win ? win[prop] : win.document.documentElement[method] : elem[method];
10475				}
10476
10477				if (win) {
10478					win.scrollTo(!top ? val : jQuery(win).scrollLeft(), top ? val : jQuery(win).scrollTop());
10479				} else {
10480					elem[method] = val;
10481				}
10482			}, method, val, arguments.length, null);
10483		};
10484	});
10485
10486	// Support: Safari<7-8+, Chrome<37-44+
10487	// Add the top/left cssHooks using jQuery.fn.position
10488	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10489	// getComputedStyle returns percent when specified for top/left/bottom/right
10490	// rather than make the css module depend on the offset module, we just check for it here
10491	jQuery.each(["top", "left"], function (i, prop) {
10492		jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, function (elem, computed) {
10493			if (computed) {
10494				computed = curCSS(elem, prop);
10495
10496				// if curCSS returns percentage, fallback to offset
10497				return rnumnonpx.test(computed) ? jQuery(elem).position()[prop] + "px" : computed;
10498			}
10499		});
10500	});
10501
10502	// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10503	jQuery.each({ Height: "height", Width: "width" }, function (name, type) {
10504		jQuery.each({ padding: "inner" + name, content: type, "": "outer" + name }, function (defaultExtra, funcName) {
10505
10506			// margin is only for outerHeight, outerWidth
10507			jQuery.fn[funcName] = function (margin, value) {
10508				var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
10509				    extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
10510
10511				return access(this, function (elem, type, value) {
10512					var doc;
10513
10514					if (jQuery.isWindow(elem)) {
10515
10516						// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10517						// isn't a whole lot we can do. See pull request at this URL for discussion:
10518						// https://github.com/jquery/jquery/pull/764
10519						return elem.document.documentElement["client" + name];
10520					}
10521
10522					// Get document width or height
10523					if (elem.nodeType === 9) {
10524						doc = elem.documentElement;
10525
10526						// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10527						// whichever is greatest
10528						// unfortunately, this causes bug #3838 in IE6/8 only,
10529						// but there is currently no good, small way to fix it.
10530						return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name]);
10531					}
10532
10533					return value === undefined ?
10534
10535					// Get width or height on the element, requesting but not forcing parseFloat
10536					jQuery.css(elem, type, extra) :
10537
10538					// Set width or height on the element
10539					jQuery.style(elem, type, value, extra);
10540				}, type, chainable ? margin : undefined, chainable, null);
10541			};
10542		});
10543	});
10544
10545	jQuery.fn.extend({
10546
10547		bind: function (types, data, fn) {
10548			return this.on(types, null, data, fn);
10549		},
10550		unbind: function (types, fn) {
10551			return this.off(types, null, fn);
10552		},
10553
10554		delegate: function (selector, types, data, fn) {
10555			return this.on(types, selector, data, fn);
10556		},
10557		undelegate: function (selector, types, fn) {
10558
10559			// ( namespace ) or ( selector, types [, fn] )
10560			return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);
10561		}
10562	});
10563
10564	// The number of elements contained in the matched element set
10565	jQuery.fn.size = function () {
10566		return this.length;
10567	};
10568
10569	jQuery.fn.andSelf = jQuery.fn.addBack;
10570
10571	// Register as a named AMD module, since jQuery can be concatenated with other
10572	// files that may use define, but not via a proper concatenation script that
10573	// understands anonymous AMD modules. A named AMD is safest and most robust
10574	// way to register. Lowercase jquery is used because AMD module names are
10575	// derived from file names, and jQuery is normally delivered in a lowercase
10576	// file name. Do this after creating the global so that if an AMD module wants
10577	// to call noConflict to hide this version of jQuery, it will work.
10578
10579	// Note that for maximum portability, libraries that are not jQuery should
10580	// declare themselves as anonymous modules, and avoid setting a global if an
10581	// AMD loader is present. jQuery is a special case. For more information, see
10582	// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10583
10584	if (true) {
10585		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
10586			return jQuery;
10587		}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
10588				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
10589	}
10590
10591	var
10592
10593	// Map over jQuery in case of overwrite
10594	_jQuery = window.jQuery,
10595
10596
10597	// Map over the $ in case of overwrite
10598	_$ = window.$;
10599
10600	jQuery.noConflict = function (deep) {
10601		if (window.$ === jQuery) {
10602			window.$ = _$;
10603		}
10604
10605		if (deep && window.jQuery === jQuery) {
10606			window.jQuery = _jQuery;
10607		}
10608
10609		return jQuery;
10610	};
10611
10612	// Expose jQuery and $ identifiers, even in
10613	// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10614	// and CommonJS for browser emulators (#13566)
10615	if (!noGlobal) {
10616		window.jQuery = window.$ = jQuery;
10617	}
10618
10619	return jQuery;
10620});
10621
10622/***/ }),
10623/* 1 */
10624/***/ (function(module, exports, __webpack_require__) {
10625
10626/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
10627 * VERSION: 1.20.3
10628 * DATE: 2017-10-02
10629 * UPDATES AND DOCS AT: http://greensock.com
10630 *
10631 * @license Copyright (c) 2008-2017, GreenSock. All rights reserved.
10632 * This work is subject to the terms at http://greensock.com/standard-license or for
10633 * Club GreenSock members, the software agreement that was issued with your membership.
10634 * 
10635 * @author: Jack Doyle, [email protected]
10636 */
10637(function (window, moduleName) {
10638
10639	"use strict";
10640
10641	var _exports = {},
10642	    _doc = window.document,
10643	    _globals = window.GreenSockGlobals = window.GreenSockGlobals || window;
10644	if (_globals.TweenLite) {
10645		return; //in case the core set of classes is already loaded, don't instantiate twice.
10646	}
10647	var _namespace = function (ns) {
10648		var a = ns.split("."),
10649		    p = _globals,
10650		    i;
10651		for (i = 0; i < a.length; i++) {
10652			p[a[i]] = p = p[a[i]] || {};
10653		}
10654		return p;
10655	},
10656	    gs = _namespace("com.greensock"),
10657	    _tinyNum = 0.0000000001,
10658	    _slice = function (a) {
10659		//don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
10660		var b = [],
10661		    l = a.length,
10662		    i;
10663		for (i = 0; i !== l; b.push(a[i++])) {}
10664		return b;
10665	},
10666	    _emptyFunc = function () {},
10667	    _isArray = function () {
10668		//works around issues in iframe environments where the Array global isn't shared, thus if the object originates in a different window/iframe, "(obj instanceof Array)" will evaluate false. We added some speed optimizations to avoid Object.prototype.toString.call() unless it's absolutely necessary because it's VERY slow (like 20x slower)
10669		var toString = Object.prototype.toString,
10670		    array = toString.call([]);
10671		return function (obj) {
10672			return obj != null && (obj instanceof Array || typeof obj === "object" && !!obj.push && toString.call(obj) === array);
10673		};
10674	}(),
10675	    a,
10676	    i,
10677	    p,
10678	    _ticker,
10679	    _tickerActive,
10680	    _defLookup = {},
10681
10682
10683	/**
10684  * @constructor
10685  * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition.
10686  * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is
10687  * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin
10688  * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally.
10689  *
10690  * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found,
10691  * it will go there as of v1.7). For example, TweenLite will be found at window.com.greensock.TweenLite and since it's a global class that should be available anywhere,
10692  * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so
10693  * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything
10694  * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock
10695  * files and put them into distinct objects (imagine a banner ad uses a newer version but the main site uses an older one). In that case, you could
10696  * sandbox the banner one like:
10697  *
10698  * <script>
10699  *     var gs = window.GreenSockGlobals = {}; //the newer version we're about to load could now be referenced in a "gs" object, like gs.TweenLite.to(...). Use whatever alias you want as long as it's unique, "gs" or "banner" or whatever.
10700  * </script>
10701  * <script src="js/greensock/v1.7/TweenMax.js"></script>
10702  * <script>
10703  *     window.GreenSockGlobals = window._gsQueue = window._gsDefine = null; //reset it back to null (along with the special _gsQueue variable) so that the next load of TweenMax affects the window and we can reference things directly like TweenLite.to(...)
10704  * </script>
10705  * <script src="js/greensock/v1.6/TweenMax.js"></script>
10706  * <script>
10707  *     gs.TweenLite.to(...); //would use v1.7
10708  *     TweenLite.to(...); //would use v1.6
10709  * </script>
10710  *
10711  * @param {!string} ns The namespace of the class definition, leaving off "com.greensock." as that's assumed. For example, "TweenLite" or "plugins.CSSPlugin" or "easing.Back".
10712  * @param {!Array.<string>}
10712 dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"]
10713  * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition.
10714  * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object)
10715  */
10716	Definition = function (ns, dependencies, func, global) {
10717		this.sc = _defLookup[ns] ? _defLookup[ns].sc : []; //subclasses
10718		_defLookup[ns] = this;
10719		this.gsClass = null;
10720		this.func = func;
10721		var _classes = [];
10722		this.check = function (init) {
10723			var i = dependencies.length,
10724			    missing = i,
10725			    cur,
10726			    a,
10727			    n,
10728			    cl;
10729			while (--i > -1) {
10730				if ((cur = _defLookup[dependencies[i]] || new Definition(dependencies[i], [])).gsClass) {
10731					_classes[i] = cur.gsClass;
10732					missing--;
10733				} else if (init) {
10734					cur.sc.push(this);
10735				}
10736			}
10737			if (missing === 0 && func) {
10738				a = ("com.greensock." + ns).split(".");
10739				n = a.pop();
10740				cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes);
10741
10742				//exports to multiple environments
10743				if (global) {
10744					_globals[n] = _exports[n] = cl; //provides a way to avoid global namespace pollution. By default, the main classes like TweenLite, Power1, Strong, etc. are added to window unless a GreenSockGlobals is defined. So if you want to have things added to a custom object instead, just do something like window.GreenSockGlobals = {} before loading any GreenSock files. You can even set up an alias like window.GreenSockGlobals = windows.gs = {} so that you can access everything like gs.TweenLite. Also remember that ALL classes are added to the window.com.greensock object (in their respective packages, like com.greensock.easing.Power1, com.greensock.TweenLite, etc.)
10745					if (typeof module !== "undefined" && module.exports) {
10746						//node
10747						if (ns === moduleName) {
10748							module.exports = _exports[moduleName] = cl;
10749							for (i in _exports) {
10750								cl[i] = _exports[i];
10751							}
10752						} else if (_exports[moduleName]) {
10753							_exports[moduleName][n] = cl;
10754						}
10755					} else if (true) {
10756						//AMD
10757						!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
10758							return cl;
10759						}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
10760				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
10761					}
10762				}
10763				for (i = 0; i < this.sc.length; i++) {
10764					this.sc[i].check();
10765				}
10766			}
10767		};
10768		this.check(true);
10769	},
10770
10771
10772	//used to create Definition instances (which basically registers a class that has dependencies).
10773	_gsDefine = window._gsDefine = function (ns, dependencies, func, global) {
10774		return new Definition(ns, dependencies, func, global);
10775	},
10776
10777
10778	//a quick way to create a class that doesn't have any dependencies. Returns the class, but first registers it in the GreenSock namespace so that other classes can grab it (other classes might be dependent on the class).
10779	_class = gs._class = function (ns, func, global) {
10780		func = func || function () {};
10781		_gsDefine(ns, [], function () {
10782			return func;
10783		}, global);
10784		return func;
10785	};
10786
10787	_gsDefine.globals = _globals;
10788
10789	/*
10790  * ----------------------------------------------------------------
10791  * Ease
10792  * ----------------------------------------------------------------
10793  */
10794	var _baseParams = [0, 0, 1, 1],
10795	    Ease = _class("easing.Ease", function (func, extraParams, type, power) {
10796		this._func = func;
10797		this._type = type || 0;
10798		this._power = power || 0;
10799		this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams;
10800	}, true),
10801	    _easeMap = Ease.map = {},
10802	    _easeReg = Ease.register = function (ease, names, types, create) {
10803		var na = names.split(","),
10804		    i = na.length,
10805		    ta = (types || "easeIn,easeOut,easeInOut").split(","),
10806		    e,
10807		    name,
10808		    j,
10809		    type;
10810		while (--i > -1) {
10811			name = na[i];
10812			e = create ? _class("easing." + name, null, true) : gs.easing[name] || {};
10813			j = ta.length;
10814			while (--j > -1) {
10815				type = ta[j];
10816				_easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease();
10817			}
10818		}
10819	};
10820
10821	p = Ease.prototype;
10822	p._calcEnd = false;
10823	p.getRatio = function (p) {
10824		if (this._func) {
10825			this._params[0] = p;
10826			return this._func.apply(null, this._params);
10827		}
10828		var t = this._type,
10829		    pw = this._power,
10830		    r = t === 1 ? 1 - p : t === 2 ? p : p < 0.5 ? p * 2 : (1 - p) * 2;
10831		if (pw === 1) {
10832			r *= r;
10833		} else if (pw === 2) {
10834			r *= r * r;
10835		} else if (pw === 3) {
10836			r *= r * r * r;
10837		} else if (pw === 4) {
10838			r *= r * r * r * r;
10839		}
10840		return t === 1 ? 1 - r : t === 2 ? r : p < 0.5 ? r / 2 : 1 - r / 2;
10841	};
10842
10843	//create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut)
10844	a = ["Linear", "Quad", "Cubic", "Quart", "Quint,Strong"];
10845	i = a.length;
10846	while (--i > -1) {
10847		p = a[i] + ",Power" + i;
10848		_easeReg(new Ease(null, null, 1, i), p, "easeOut", true);
10849		_easeReg(new Ease(null, null, 2, i), p, "easeIn" + (i === 0 ? ",easeNone" : ""));
10850		_easeReg(new Ease(null, null, 3, i), p, "easeInOut");
10851	}
10852	_easeMap.linear = gs.easing.Linear.easeIn;
10853	_easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks
10854
10855
10856	/*
10857  * ----------------------------------------------------------------
10858  * EventDispatcher
10859  * ----------------------------------------------------------------
10860  */
10861	var EventDispatcher = _class("events.EventDispatcher", function (target) {
10862		this._listeners = {};
10863		this._eventTarget = target || this;
10864	});
10865	p = EventDispatcher.prototype;
10866
10867	p.addEventListener = function (type, callback, scope, useParam, priority) {
10868		priority = priority || 0;
10869		var list = this._listeners[type],
10870		    index = 0,
10871		    listener,
10872		    i;
10873		if (this === _ticker && !_tickerActive) {
10874			_ticker.wake();
10875		}
10876		if (list == null) {
10877			this._listeners[type] = list = [];
10878		}
10879		i = list.length;
10880		while (--i > -1) {
10881			listener = list[i];
10882			if (listener.c === callback && listener.s === scope) {
10883				list.splice(i, 1);
10884			} else if (index === 0 && listener.pr < priority) {
10885				index = i + 1;
10886			}
10887		}
10888		list.splice(index, 0, { c: callback, s: scope, up: useParam, pr: priority });
10889	};
10890
10891	p.removeEventListener = function (type, callback) {
10892		var list = this._listeners[type],
10893		    i;
10894		if (list) {
10895			i = list.length;
10896			while (--i > -1) {
10897				if (list[i].c === callback) {
10898					list.splice(i, 1);
10899					return;
10900				}
10901			}
10902		}
10903	};
10904
10905	p.dispatchEvent = function (type) {
10906		var list = this._listeners[type],
10907		    i,
10908		    t,
10909		    listener;
10910		if (list) {
10911			i = list.length;
10912			if (i > 1) {
10913				list = list.slice(0); //in case addEventListener() is called from within a listener/callback (otherwise the index could change, resulting in a skip)
10914			}
10915			t = this._eventTarget;
10916			while (--i > -1) {
10917				listener = list[i];
10918				if (listener) {
10919					if (listener.up) {
10920						listener.c.call(listener.s || t, { type: type, target: t });
10921					} else {
10922						listener.c.call(listener.s || t);
10923					}
10924				}
10925			}
10926		}
10927	};
10928
10929	/*
10930  * ----------------------------------------------------------------
10931  * Ticker
10932  * ----------------------------------------------------------------
10933  */
10934	var _reqAnimFrame = window.requestAnimationFrame,
10935	    _cancelAnimFrame = window.cancelAnimationFrame,
10936	    _getTime = Date.now || function () {
10937		return new Date().getTime();
10938	},
10939	    _lastUpdate = _getTime();
10940
10941	//now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill.
10942	a = ["ms", "moz", "webkit", "o"];
10943	i = a.length;
10944	while (--i > -1 && !_reqAnimFrame) {
10945		_reqAnimFrame = window[a[i] + "RequestAnimationFrame"];
10946		_cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"];
10947	}
10948
10949	_class("Ticker", function (fps, useRAF) {
10950		var _self = this,
10951		    _startTime = _getTime(),
10952		    _useRAF = useRAF !== false && _reqAnimFrame ? "auto" : false,
10953		    _lagThreshold = 500,
10954		    _adjustedLag = 33,
10955		    _tickWord = "tick",
10956		    //helps reduce gc burden
10957		_fps,
10958		    _req,
10959		    _id,
10960		    _gap,
10961		    _nextTime,
10962		    _tick = function (manual) {
10963			var elapsed = _getTime() - _lastUpdate,
10964			    overlap,
10965			    dispatch;
10966			if (elapsed > _lagThreshold) {
10967				_startTime += elapsed - _adjustedLag;
10968			}
10969			_lastUpdate += elapsed;
10970			_self.time = (_lastUpdate - _startTime) / 1000;
10971			overlap = _self.time - _nextTime;
10972			if (!_fps || overlap > 0 || manual === true) {
10973				_self.frame++;
10974				_nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap);
10975				dispatch = true;
10976			}
10977			if (manual !== true) {
10978				//make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise.
10979				_id = _req(_tick);
10980			}
10981			if (dispatch) {
10982				_self.dispatchEvent(_tickWord);
10983			}
10984		};
10985
10986		EventDispatcher.call(_self);
10987		_self.time = _self.frame = 0;
10988		_self.tick = function () {
10989			_tick(true);
10990		};
10991
10992		_self.lagSmoothing = function (threshold, adjustedLag) {
10993			if (!arguments.length) {
10994				//if lagSmoothing() is called with no arguments, treat it like a getter that returns a boolean indicating if it's enabled or not. This is purposely undocumented and is for internal use.
10995				return _lagThreshold < 1 / _tinyNum;
10996			}
10997			_lagThreshold = threshold || 1 / _tinyNum; //zero should be interpreted as basically unlimited
10998			_adjustedLag = Math.min(adjustedLag, _lagThreshold, 0);
10999		};
11000
11001		_self.sleep = function () {
11002			if (_id == null) {
11003				return;
11004			}
11005			if (!_useRAF || !_cancelAnimFrame) {
11006				clearTimeout(_id);
11007			} else {
11008				_cancelAnimFrame(_id);
11009			}
11010			_req = _emptyFunc;
11011			_id = null;
11012			if (_self === _ticker) {
11013				_tickerActive = false;
11014			}
11015		};
11016
11017		_self.wake = function (seamless) {
11018			if (_id !== null) {
11019				_self.sleep();
11020			} else if (seamless) {
11021				_startTime += -_lastUpdate + (_lastUpdate = _getTime());
11022			} else if (_self.frame > 10) {
11023				//don't trigger lagSmoothing if we're just waking up, and make sure that at least 10 frames have elapsed because of the iOS bug that we work around below with the 1.5-second setTimout().
11024				_lastUpdate = _getTime() - _lagThreshold + 5;
11025			}
11026			_req = _fps === 0 ? _emptyFunc : !_useRAF || !_reqAnimFrame ? function (f) {
11027				return setTimeout(f, (_nextTime - _self.time) * 1000 + 1 | 0);
11028			} : _reqAnimFrame;
11029			if (_self === _ticker) {
11030				_tickerActive = true;
11031			}
11032			_tick(2);
11033		};
11034
11035		_self.fps = function (value) {
11036			if (!arguments.length) {
11037				return _fps;
11038			}
11039			_fps = value;
11040			_gap = 1 / (_fps || 60);
11041			_nextTime = this.time + _gap;
11042			_self.wake();
11043		};
11044
11045		_self.useRAF = function (value) {
11046			if (!arguments.length) {
11047				return _useRAF;
11048			}
11049			_self.sleep();
11050			_useRAF = value;
11051			_self.fps(_fps);
11052		};
11053		_self.fps(fps);
11054
11055		//a bug in iOS 6 Safari occasionally prevents the requestAnimationFrame from working initially, so we use a 1.5-second timeout that automatically falls back to setTimeout() if it senses this condition.
11056		setTimeout(function () {
11057			if (_useRAF === "auto" && _self.frame < 5 && _doc.visibilityState !== "hidden") {
11058				_self.useRAF(false);
11059			}
11060		}, 1500);
11061	});
11062
11063	p = gs.Ticker.prototype = new gs.events.EventDispatcher();
11064	p.constructor = gs.Ticker;
11065
11066	/*
11067  * ----------------------------------------------------------------
11068  * Animation
11069  * ----------------------------------------------------------------
11070  */
11071	var Animation = _class("core.Animation", function (duration, vars) {
11072		this.vars = vars = vars || {};
11073		this._duration = this._totalDuration = duration || 0;
11074		this._delay = Number(vars.delay) || 0;
11075		this._timeScale = 1;
11076		this._active = vars.immediateRender === true;
11077		this.data = vars.data;
11078		this._reversed = vars.reversed === true;
11079
11080		if (!_rootTimeline) {
11081			return;
11082		}
11083		if (!_tickerActive) {
11084			//some browsers (like iOS 6 Safari) shut down JavaScript execution when the tab is disabled and they [occasionally] neglect to start up requestAnimationFrame again when returning - this code ensures that the engine starts up again properly.
11085			_ticker.wake();
11086		}
11087
11088		var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline;
11089		tl.add(this, tl._time);
11090
11091		if (this.vars.paused) {
11092			this.paused(true);
11093		}
11094	});
11095
11096	_ticker = Animation.ticker = new gs.Ticker();
11097	p = Animation.prototype;
11098	p._dirty = p._gc = p._initted = p._paused = false;
11099	p._totalTime = p._time = 0;
11100	p._rawPrevTime = -1;
11101	p._next = p._last = p._onUpdate = p._timeline = p.timeline = null;
11102	p._paused = false;
11103
11104	//some browsers (like iOS) occasionally drop the requestAnimationFrame event when the user switches to a different tab and then comes back again, so we use a 2-second setTimeout() to sense if/when that condition occurs and then wake() the ticker.
11105	var _checkTimeout = function () {
11106		if (_tickerActive && _getTime() - _lastUpdate > 2000 && (_doc.visibilityState !== "hidden" || !_ticker.lagSmoothing())) {
11107			//note: if the tab is hidden, we should still wake if lagSmoothing has been disabled.
11108			_ticker.wake();
11109		}
11110		var t = setTimeout(_checkTimeout, 2000);
11111		if (t.unref) {
11112			// allows a node process to exit even if the timeout’s callback hasn't been invoked. Without it, the node process could hang as this function is called every two seconds.
11113			t.unref();
11114		}
11115	};
11116	_checkTimeout();
11117
11118	p.play = function (from, suppressEvents) {
11119		if (from != null) {
11120			this.seek(from, suppressEvents);
11121		}
11122		return this.reversed(false).paused(false);
11123	};
11124
11125	p.pause = function (atTime, suppressEvents) {
11126		if (atTime != null) {
11127			this.seek(atTime, suppressEvents);
11128		}
11129		return this.paused(true);
11130	};
11131
11132	p.resume = function (from, suppressEvents) {
11133		if (from != null) {
11134			this.seek(from, suppressEvents);
11135		}
11136		return this.paused(false);
11137	};
11138
11139	p.seek = function (time, suppressEvents) {
11140		return this.totalTime(Number(time), suppressEvents !== false);
11141	};
11142
11143	p.restart = function (includeDelay, suppressEvents) {
11144		return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, suppressEvents !== false, true);
11145	};
11146
11147	p.reverse = function (from, suppressEvents) {
11148		if (from != null) {
11149			this.seek(from || this.totalDuration(), suppressEvents);
11150		}
11151		return this.reversed(true).paused(false);
11152	};
11153
11154	p.render = function (time, suppressEvents, force) {
11155		//stub - we override this method in subclasses.
11156	};
11157
11158	p.invalidate = function () {
11159		this._time = this._totalTime = 0;
11160		this._initted = this._gc = false;
11161		this._rawPrevTime = -1;
11162		if (this._gc || !this.timeline) {
11163			this._enabled(true);
11164		}
11165		return this;
11166	};
11167
11168	p.isActive = function () {
11169		var tl = this._timeline,
11170		    //the 2 root timelines won't have a _timeline; they're always active.
11171		startTime = this._startTime,
11172		    rawTime;
11173		return !tl || !this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime(true)) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale - 0.0000001;
11174	};
11175
11176	p._enabled = function (enabled, ignoreTimeline) {
11177		if (!_tickerActive) {
11178			_ticker.wake();
11179		}
11180		this._gc = !enabled;
11181		this._active = this.isActive();
11182		if (ignoreTimeline !== true) {
11183			if (enabled && !this.timeline) {
11184				this._timeline.add(this, this._startTime - this._delay);
11185			} else if (!enabled && this.timeline) {
11186				this._timeline._remove(this, true);
11187			}
11188		}
11189		return false;
11190	};
11191
11192	p._kill = function (vars, target) {
11193		return this._enabled(false, false);
11194	};
11195
11196	p.kill = function (vars, target) {
11197		this._kill(vars, target);
11198		return this;
11199	};
11200
11201	p._uncache = function (includeSelf) {
11202		var tween = includeSelf ? this : this.timeline;
11203		while (tween) {
11204			tween._dirty = true;
11205			tween = tween.timeline;
11206		}
11207		return this;
11208	};
11209
11210	p._swapSelfInParams = function (params) {
11211		var i = params.length,
11212		    copy = params.concat();
11213		while (--i > -1) {
11214			if (params[i] === "{self}") {
11215				copy[i] = this;
11216			}
11217		}
11218		return copy;
11219	};
11220
11221	p._callback = function (type) {
11222		var v = this.vars,
11223		    callback = v[type],
11224		    params = v[type + "Params"],
11225		    scope = v[type + "Scope"] || v.callbackScope || this,
11226		    l = params ? params.length : 0;
11227		switch (l) {//speed optimization; call() is faster than apply() so use it when there are only a few parameters (which is by far most common). Previously we simply did var v = this.vars; v[type].apply(v[type + "Scope"] || v.callbackScope || this, v[type + "Params"] || _blankArray);
11228			case 0:
11229				callback.call(scope);break;
11230			case 1:
11231				callback.call(scope, params[0]);break;
11232			case 2:
11233				callback.call(scope, params[0], params[1]);break;
11234			default:
11235				callback.apply(scope, params);
11236		}
11237	};
11238
11239	//----Animation getters/setters --------------------------------------------------------
11240
11241	p.eventCallback = function (type, callback, params, scope) {
11242		if ((type || "").substr(0, 2) === "on") {
11243			var v = this.vars;
11244			if (arguments.length === 1) {
11245				return v[type];
11246			}
11247			if (callback == null) {
11248				delete v[type];
11249			} else {
11250				v[type] = callback;
11251				v[type + "Params"] = _isArray(params) && params.join("").indexOf("{self}") !== -1 ? this._swapSelfInParams(params) : params;
11252				v[type + "Scope"] = scope;
11253			}
11254			if (type === "onUpdate") {
11255				this._onUpdate = callback;
11256			}
11257		}
11258		return this;
11259	};
11260
11261	p.delay = function (value) {
11262		if (!arguments.length) {
11263			return this._delay;
11264		}
11265		if (this._timeline.smoothChildTiming) {
11266			this.startTime(this._startTime + value - this._delay);
11267		}
11268		this._delay = value;
11269		return this;
11270	};
11271
11272	p.duration = function (value) {
11273		if (!arguments.length) {
11274			this._dirty = false;
11275			return this._duration;
11276		}
11277		this._duration = this._totalDuration = value;
11278		this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration.
11279		if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) {
11280			this.totalTime(this._totalTime * (value / this._duration), true);
11281		}
11282		return this;
11283	};
11284
11285	p.totalDuration = function (value) {
11286		this._dirty = false;
11287		return !arguments.length ? this._totalDuration : this.duration(value);
11288	};
11289
11290	p.time = function (value, suppressEvents) {
11291		if (!arguments.length) {
11292			return this._time;
11293		}
11294		if (this._dirty) {
11295			this.totalDuration();
11296		}
11297		return this.totalTime(value > this._duration ? this._duration : value, suppressEvents);
11298	};
11299
11300	p.totalTime = function (time, suppressEvents, uncapped) {
11301		if (!_tickerActive) {
11302			_ticker.wake();
11303		}
11304		if (!arguments.length) {
11305			return this._totalTime;
11306		}
11307		if (this._timeline) {
11308			if (time < 0 && !uncapped) {
11309				time += this.totalDuration();
11310			}
11311			if (this._timeline.smoothChildTiming) {
11312				if (this._dirty) {
11313					this.totalDuration();
11314				}
11315				var totalDuration = this._totalDuration,
11316				    tl = this._timeline;
11317				if (time > totalDuration && !uncapped) {
11318					time = totalDuration;
11319				}
11320				this._startTime = (this._paused ? this._pauseTime : tl._time) - (!this._reversed ? time : totalDuration - time) / this._timeScale;
11321				if (!tl._dirty) {
11322					//for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here.
11323					this._uncache(false);
11324				}
11325				//in case any of the ancestor timelines had completed but should now be enabled, we should reset the
11325ir totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed.
11326				if (tl._timeline) {
11327					while (tl._timeline) {
11328						if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) {
11329							tl.totalTime(tl._totalTime, true);
11330						}
11331						tl = tl._timeline;
11332					}
11333				}
11334			}
11335			if (this._gc) {
11336				this._enabled(true, false);
11337			}
11338			if (this._totalTime !== time || this._duration === 0) {
11339				if (_lazyTweens.length) {
11340					_lazyRender();
11341				}
11342				this.render(time, suppressEvents, false);
11343				if (_lazyTweens.length) {
11344					//in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render.
11345					_lazyRender();
11346				}
11347			}
11348		}
11349		return this;
11350	};
11351
11352	p.progress = p.totalProgress = function (value, suppressEvents) {
11353		var duration = this.duration();
11354		return !arguments.length ? duration ? this._time / duration : this.ratio : this.totalTime(duration * value, suppressEvents);
11355	};
11356
11357	p.startTime = function (value) {
11358		if (!arguments.length) {
11359			return this._startTime;
11360		}
11361		if (value !== this._startTime) {
11362			this._startTime = value;
11363			if (this.timeline) if (this.timeline._sortChildren) {
11364				this.timeline.add(this, value - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct.
11365			}
11366		}
11367		return this;
11368	};
11369
11370	p.endTime = function (includeRepeats) {
11371		return this._startTime + (includeRepeats != false ? this.totalDuration() : this.duration()) / this._timeScale;
11372	};
11373
11374	p.timeScale = function (value) {
11375		if (!arguments.length) {
11376			return this._timeScale;
11377		}
11378		var pauseTime, t;
11379		value = value || _tinyNum; //can't allow zero because it'll throw the math off
11380		if (this._timeline && this._timeline.smoothChildTiming) {
11381			pauseTime = this._pauseTime;
11382			t = pauseTime || pauseTime === 0 ? pauseTime : this._timeline.totalTime();
11383			this._startTime = t - (t - this._startTime) * this._timeScale / value;
11384		}
11385		this._timeScale = value;
11386		t = this.timeline;
11387		while (t && t.timeline) {
11388			//must update the duration/totalDuration of all ancestor timelines immediately in case in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though.
11389			t._dirty = true;
11390			t.totalDuration();
11391			t = t.timeline;
11392		}
11393		return this;
11394	};
11395
11396	p.reversed = function (value) {
11397		if (!arguments.length) {
11398			return this._reversed;
11399		}
11400		if (value != this._reversed) {
11401			this._reversed = value;
11402			this.totalTime(this._timeline && !this._timeline.smoothChildTiming ? this.totalDuration() - this._totalTime : this._totalTime, true);
11403		}
11404		return this;
11405	};
11406
11407	p.paused = function (value) {
11408		if (!arguments.length) {
11409			return this._paused;
11410		}
11411		var tl = this._timeline,
11412		    raw,
11413		    elapsed;
11414		if (value != this._paused) if (tl) {
11415			if (!_tickerActive && !value) {
11416				_ticker.wake();
11417			}
11418			raw = tl.rawTime();
11419			elapsed = raw - this._pauseTime;
11420			if (!value && tl.smoothChildTiming) {
11421				this._startTime += elapsed;
11422				this._uncache(false);
11423			}
11424			this._pauseTime = value ? raw : null;
11425			this._paused = value;
11426			this._active = this.isActive();
11427			if (!value && elapsed !== 0 && this._initted && this.duration()) {
11428				raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale;
11429				this.render(raw, raw === this._totalTime, true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render.
11430			}
11431		}
11432		if (this._gc && !value) {
11433			this._enabled(true, false);
11434		}
11435		return this;
11436	};
11437
11438	/*
11439  * ----------------------------------------------------------------
11440  * SimpleTimeline
11441  * ----------------------------------------------------------------
11442  */
11443	var SimpleTimeline = _class("core.SimpleTimeline", function (vars) {
11444		Animation.call(this, 0, vars);
11445		this.autoRemoveChildren = this.smoothChildTiming = true;
11446	});
11447
11448	p = SimpleTimeline.prototype = new Animation();
11449	p.constructor = SimpleTimeline;
11450	p.kill()._gc = false;
11451	p._first = p._last = p._recent = null;
11452	p._sortChildren = false;
11453
11454	p.add = p.insert = function (child, position, align, stagger) {
11455		var prevTween, st;
11456		child._startTime = Number(position || 0) + child._delay;
11457		if (child._paused) if (this !== child._timeline) {
11458			//we only adjust the _pauseTime if it wasn't in this timeline already. Remember, sometimes a tween will be inserted again into the same timeline when its startTime is changed so that the tweens in the TimelineLite/Max are re-ordered properly in the linked list (so everything renders in the proper order).
11459			child._pauseTime = child._startTime + (this.rawTime() - child._startTime) / child._timeScale;
11460		}
11461		if (child.timeline) {
11462			child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one.
11463		}
11464		child.timeline = child._timeline = this;
11465		if (child._gc) {
11466			child._enabled(true, true);
11467		}
11468		prevTween = this._last;
11469		if (this._sortChildren) {
11470			st = child._startTime;
11471			while (prevTween && prevTween._startTime > st) {
11472				prevTween = prevTween._prev;
11473			}
11474		}
11475		if (prevTween) {
11476			child._next = prevTween._next;
11477			prevTween._next = child;
11478		} else {
11479			child._next = this._first;
11480			this._first = child;
11481		}
11482		if (child._next) {
11483			child._next._prev = child;
11484		} else {
11485			this._last = child;
11486		}
11487		child._prev = prevTween;
11488		this._recent = child;
11489		if (this._timeline) {
11490			this._uncache(true);
11491		}
11492		return this;
11493	};
11494
11495	p._remove = function (tween, skipDisable) {
11496		if (tween.timeline === this) {
11497			if (!skipDisable) {
11498				tween._enabled(false, true);
11499			}
11500
11501			if (tween._prev) {
11502				tween._prev._next = tween._next;
11503			} else if (this._first === tween) {
11504				this._first = tween._next;
11505			}
11506			if (tween._next) {
11507				tween._next._prev = tween._prev;
11508			} else if (this._last === tween) {
11509				this._last = tween._prev;
11510			}
11511			tween._next = tween._prev = tween.timeline = null;
11512			if (tween === this._recent) {
11513				this._recent = this._last;
11514			}
11515
11516			if (this._timeline) {
11517				this._uncache(true);
11518			}
11519		}
11520		return this;
11521	};
11522
11523	p.render = function (time, suppressEvents, force) {
11524		var tween = this._first,
11525		    next;
11526		this._totalTime = this._time = this._rawPrevTime = time;
11527		while (tween) {
11528			next = tween._next; //record it here because the value could change after rendering...
11529			if (tween._active || time >= tween._startTime && !tween._paused && !tween._gc) {
11530				if (!tween._reversed) {
11531					tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
11532				} else {
11533					tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
11534				}
11535			}
11536			tween = next;
11537		}
11538	};
11539
11540	p.rawTime = function () {
11541		if (!_tickerActive) {
11542			_ticker.wake();
11543		}
11544		return this._totalTime;
11545	};
11546
11547	/*
11548  * ----------------------------------------------------------------
11549  * TweenLite
11550  * ----------------------------------------------------------------
11551  */
11552	var TweenLite = _class("TweenLite", function (target, duration, vars) {
11553		Animation.call(this, duration, vars);
11554		this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
11555
11556		if (target == null) {
11557			throw "Cannot tween a null target.";
11558		}
11559
11560		this.target = target = typeof target !== "string" ? target : TweenLite.selector(target) || target;
11561
11562		var isSelector = target.jquery || target.length && target !== window && target[0] && (target[0] === window || target[0].nodeType && target[0].style && !target.nodeType),
11563		    overwrite = this.vars.overwrite,
11564		    i,
11565		    targ,
11566		    targets;
11567
11568		this._overwrite = overwrite = overwrite == null ? _overwriteLookup[TweenLite.defaultOverwrite] : typeof overwrite === "number" ? overwrite >> 0 : _overwriteLookup[overwrite];
11569
11570		if ((isSelector || target instanceof Array || target.push && _isArray(target)) && typeof target[0] !== "number") {
11571			this._targets = targets = _slice(target); //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
11572			this._propLookup = [];
11573			this._siblings = [];
11574			for (i = 0; i < targets.length; i++) {
11575				targ = targets[i];
11576				if (!targ) {
11577					targets.splice(i--, 1);
11578					continue;
11579				} else if (typeof targ === "string") {
11580					targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings
11581					if (typeof targ === "string") {
11582						targets.splice(i + 1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case)
11583					}
11584					continue;
11585				} else if (targ.length && targ !== window && targ[0] && (targ[0] === window || targ[0].nodeType && targ[0].style && !targ.nodeType)) {
11586					//in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that <select> elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself.
11587					targets.splice(i--, 1);
11588					this._targets = targets = targets.concat(_slice(targ));
11589					continue;
11590				}
11591				this._siblings[i] = _register(targ, this, false);
11592				if (overwrite === 1) if (this._siblings[i].length > 1) {
11593					_applyOverwrite(targ, this, null, 1, this._siblings[i]);
11594				}
11595			}
11596		} else {
11597			this._propLookup = {};
11598			this._siblings = _register(target, this, false);
11599			if (overwrite === 1) if (this._siblings.length > 1) {
11600				_applyOverwrite(target, this, null, 1, this._siblings);
11601			}
11602		}
11603		if (this.vars.immediateRender || duration === 0 && this._delay === 0 && this.vars.immediateRender !== false) {
11604			this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render)
11605			this.render(Math.min(0, -this._delay)); //in case delay is negative
11606		}
11607	}, true),
11608	    _isSelector = function (v) {
11609		return v && v.length && v !== window && v[0] && (v[0] === window || v[0].nodeType && v[0].style && !v.nodeType); //we cannot check "nodeType" if the target is window from within an iframe, otherwise it will trigger a security error in some browsers like Firefox.
11610	},
11611	    _autoCSS = function (vars, target) {
11612		var css = {},
11613		    p;
11614		for (p in vars) {
11615			if (!_reservedProps[p] && (!(p in target) || p === "transform" || p === "x" || p === "y" || p === "width" || p === "height" || p === "className" || p === "border") && (!_plugins[p] || _plugins[p] && _plugins[p]._autoCSS)) {
11616				//note: <img> elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties.
11617				css[p] = vars[p];
11618				delete vars[p];
11619			}
11620		}
11621		vars.css = css;
11622	};
11623
11624	p = TweenLite.prototype = new Animation();
11625	p.constructor = TweenLite;
11626	p.kill()._gc = false;
11627
11628	//----TweenLite defaults, overwrite management, and root updates ----------------------------------------------------
11629
11630	p.ratio = 0;
11631	p._firstPT = p._targets = p._overwrittenProps = p._startAt = null;
11632	p._notifyPluginsOfEnabled = p._lazy = false;
11633
11634	TweenLite.version = "1.20.3";
11635	TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1);
11636	TweenLite.defaultOverwrite = "auto";
11637	TweenLite.ticker = _ticker;
11638	TweenLite.autoSleep = 120;
11639	TweenLite.lagSmoothing = function (threshold, adjustedLag) {
11640		_ticker.lagSmoothing(threshold, adjustedLag);
11641	};
11642
11643	TweenLite.selector = window.$ || window.jQuery || function (e) {
11644		var selector = window.$ || window.jQuery;
11645		if (selector) {
11646			TweenLite.selector = selector;
11647			return selector(e);
11648		}
11649		return typeof _doc === "undefined" ? e : _doc.querySelectorAll ? _doc.querySelectorAll(e) : _doc.getElementById(e.charAt(0) === "#" ? e.substr(1) : e);
11650	};
11651
11652	var _lazyTweens = [],
11653	    _lazyLookup = {},
11654	    _numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
11655	    _relExp = /[\+-]=-?[\.\d]/,
11656
11657	//_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig,
11658	_setRatio = function (v) {
11659		var pt = this._firstPT,
11660		    min = 0.000001,
11661		    val;
11662		while (pt) {
11663			val = !pt.blob ? pt.c * v + pt.s : v === 1 && this.end != null ? this.end : v ? this.join("") : this.start;
11664			if (pt.m) {
11665				val = pt.m(val, this._target || pt.t);
11666			} else if (val < min) if (val > -min && !pt.blob) {
11667				//prevents issues with converting very small numbers to strings in the browser
11668				val = 0;
11669			}
11670			if (!pt.f) {
11671				pt.t[pt.p] = val;
11672			} else if (pt.fp) {
11673				pt.t[pt.p](pt.fp, val);
11674			} else {
11675				pt.t[pt.p](val);
11676			}
11677			pt = pt._next;
11678		}
11679	},
11680
11681	//compares two strings (start/end), finds the numbers that are different and spits back an array representing the whole value but with the changing values isolated as elements. For example, "rgb(0,0,0)" and "rgb(100,50,0)" would become ["rgb(", 0, ",", 50, ",0)"]. Notice it merges the parts that are identical (performance optimization). The array also has a linked list of PropTweens attached starting with _firstPT that contain the tweening data (t, p, s, c, f, etc.). It also stores the starting value as a "start" property so that we can revert to it if/when necessary, like when a tween rewinds fully. If the quantity of numbers differs between the start and end, it will always prioritize the end value(s). The pt parameter is optional - it's for a PropTween that will be appended to the end of the linked list and is typically for actually setting the value after all of the elements have been updated (with array.join("")).
11682	_blobDif = function (start, end, filter, pt) {
11683		var a = [],
11684		    charIndex = 0,
11685		    s = "",
11686		    color = 0,
11687		    startNums,
11688		    endNums,
11689		    num,
11690		    i,
11691		    l,
11692		    nonNumbers,
11693		    currentNum;
11694		a.start = start;
11695		a.end = end;
11696		start = a[0] = start + ""; //ensure values are strings
11697		end = a[1] = end + "";
11698		if (filter) {
11699			filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.
11700			start = a[0];
11701			end = a[1];
11702		}
11703		a.length = 0;
11704		startNums = start.match(_numbersExp) || [];
11705		endNums = end.match(_numbersExp) || [];
11706		if (pt) {
11707			pt._next = null;
11708			pt.blob = 1;
11709			a._firstPT = a._applyPT = pt; //apply last in the linked list (which means inserting it first)
11710		}
11711		l = endNums.length;
11712		for (i = 0; i < l; i++) {
11713			currentNum = endNums[i];
11714			nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex) - charIndex);
11715			s += nonNumbers || !i ? nonNumbers : ","; //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case.
11716			charIndex += nonNumbers.length;
11717			if (color) {
11718				//sense rgba() values and round them.
11719				color = (color + 1) % 5;
11720			} else if (nonNumbers.substr(-5) === "rgba(") {
11721				color = 1;
11722			}
11723			if (currentNum === startNums[i] || startNums.length <= i) {
11724				s += currentNum;
11725			} else {
11726				if (s) {
11727					a.push(s);
11728					s = "";
11729				}
11730				num = parseFloat(startNums[i]);
11731				a.push(num);
11732				a._firstPT = { _next: a._firstPT, t: a, p: a.length - 1, s: num, c: (currentNum.charAt(1) === "=" ? parseInt(currentNum.charAt(0) + "1", 10) * parseFloat(currentNum.substr(2)) : parseFloat(currentNum) - num) || 0, f: 0, m: color && color < 4 ? Math.round : 0 };
11733				//note: we don't set _prev because we'll never need to remove individual PropTweens from this list.
11734			}
11735			charIndex += currentNum.length;
11736		}
11737		s += end.substr(charIndex);
11738		if (s) {
11739			a.push(s);
11740		}
11741		a.setRatio = _setRatio;
11742		if (_relExp.test(end)) {
11743			//if the end string contains relative values, delete it so that on the final render (in _setRatio()), we don't actually set it to the string with += or -= characters (forces it to use the calculated value).
11744			a.end = null;
11745		}
11746		return a;
11747	},
11748
11749	//note: "funcParam" is only necessary for function-based getters/setters that require an extra parameter like getAttribute("width") and setAttribute("width", value). In this example, funcParam would be "width". Used by AttrPlugin for example.
11750	_addPropTween = function (target, prop, start, end, overwriteProp, mod, funcParam, stringFilter, index) {
11751		if (typeof end === "function") {
11752			end = end(index || 0, target);
11753		}
11754		var type = typeof target[prop],
11755		    getterName = type !== "function" ? "" : prop.indexOf("set") || typeof target["get" + prop.substr(3)] !== "function" ? prop : "get" + prop.substr(3),
11756		    s = start !== "get" ? start : !getterName ? target[prop] : funcParam ? target[getterName](funcParam) : target[getterName](),
11757		    isRelative = typeof end === "string" && end.charAt(1) === "=",
11758		    pt = { t: target, p: prop, s: s, f: type === "function", pg: 0, n: overwriteProp || prop, m: !mod ? 0 : typeof mod === "function" ? mod : Math.round, pr: 0, c: isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : parseFloat(end) - s || 0 },
11759		    blob;
11760
11761		if (typeof s !== "number" || typeof end !== "number" && !isRelative) {
11762			if (funcParam || isNaN(s) || !isRelative && isNaN(end) || typeof s === "boolean" || typeof end === "boolean") {
11763				//a blob (string that has multiple numbers in it)
11764				pt.fp = funcParam;
11765				blob = _blobDif(s, isRelative ? parseFloat(pt.s) + pt.c : end, stringFilter || TweenLite.defaultStringFilter, pt);
11766				pt = { t: blob, p: "setRatio", s: 0, c: 1, f: 2, pg: 0, n: overwriteProp || prop, pr: 0, m: 0 }; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example.
11767			} else {
11768				pt.s = parseFloat(s);
11769				if (!isRelative) {
11770					pt.c = parseFloat(end) - pt.s || 0;
11771				}
11772			}
11773		}
11774		if (pt.c) {
11775			//only add it to the linked list if there's a change.
11776			if (pt._next = this._firstPT) {
11777				pt._next._prev = pt;
11778			}
11779			this._firstPT = pt;
11780			return pt;
11781		}
11782	},
11783	    _internals = TweenLite._internals = { isArray: _isArray, isSelector: _isSelector, lazyTweens: _lazyTweens, blobDif: _blobDif },
11784	    //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object.
11785	_plugins = TweenLite._plugins = {},
11786	    _tweenLookup = _internals.tweenLookup = {},
11787	    _tweenLookupNum = 0,
11788	    _reservedProps = _internals.reservedProps = { ease: 1, delay: 1, overwrite: 1, onComplete: 1, onCompleteParams: 1, onCompleteScope: 1, useFrames: 1, runBackwards: 1, startAt: 1, onUpdate: 1, onUpdateParams: 1, onUpdateScope: 1, onStart: 1, onStartParams: 1, onStartScope: 1, onReverseComplete: 1, onReverseCompleteParams: 1, onReverseCompleteScope: 1, onRepeat: 1, onRepeatParams: 1, onRepeatScope: 1, easeParams: 1, yoyo: 1, immediateRender: 1, repeat: 1, repeatDelay: 1, data: 1, paused: 1, reversed: 1, autoCSS: 1, lazy: 1, onOverwrite: 1, callbackScope: 1, str
11788ingFilter: 1, id: 1, yoyoEase: 1 },
11789	    _overwriteLookup = { none: 0, all: 1, auto: 2, concurrent: 3, allOnStart: 4, preexisting: 5, "true": 1, "false": 0 },
11790	    _rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(),
11791	    _rootTimeline = Animation._rootTimeline = new SimpleTimeline(),
11792	    _nextGCFrame = 30,
11793	    _lazyRender = _internals.lazyRender = function () {
11794		var i = _lazyTweens.length,
11795		    tween;
11796		_lazyLookup = {};
11797		while (--i > -1) {
11798			tween = _lazyTweens[i];
11799			if (tween && tween._lazy !== false) {
11800				tween.render(tween._lazy[0], tween._lazy[1], true);
11801				tween._lazy = false;
11802			}
11803		}
11804		_lazyTweens.length = 0;
11805	};
11806
11807	_rootTimeline._startTime = _ticker.time;
11808	_rootFramesTimeline._startTime = _ticker.frame;
11809	_rootTimeline._active = _rootFramesTimeline._active = true;
11810	setTimeout(_lazyRender, 1); //on some mobile devices, there isn't a "tick" before code runs which means any lazy renders wouldn't run before the next official "tick".
11811
11812	Animation._updateRoot = TweenLite.render = function () {
11813		var i, a, p;
11814		if (_lazyTweens.length) {
11815			//if code is run outside of the requestAnimationFrame loop, there may be tweens queued AFTER the engine refreshed, so we need to ensure any pending renders occur before we refresh again.
11816			_lazyRender();
11817		}
11818		_rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false);
11819		_rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false);
11820		if (_lazyTweens.length) {
11821			_lazyRender();
11822		}
11823		if (_ticker.frame >= _nextGCFrame) {
11824			//dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to
11825			_nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120);
11826			for (p in _tweenLookup) {
11827				a = _tweenLookup[p].tweens;
11828				i = a.length;
11829				while (--i > -1) {
11830					if (a[i]._gc) {
11831						a.splice(i, 1);
11832					}
11833				}
11834				if (a.length === 0) {
11835					delete _tweenLookup[p];
11836				}
11837			}
11838			//if there are no more tweens in the root timelines, or if they're all paused, make the _timer sleep to reduce load on the CPU slightly
11839			p = _rootTimeline._first;
11840			if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) {
11841				while (p && p._paused) {
11842					p = p._next;
11843				}
11844				if (!p) {
11845					_ticker.sleep();
11846				}
11847			}
11848		}
11849	};
11850
11851	_ticker.addEventListener("tick", Animation._updateRoot);
11852
11853	var _register = function (target, tween, scrub) {
11854		var id = target._gsTweenID,
11855		    a,
11856		    i;
11857		if (!_tweenLookup[id || (target._gsTweenID = id = "t" + _tweenLookupNum++)]) {
11858			_tweenLookup[id] = { target: target, tweens: [] };
11859		}
11860		if (tween) {
11861			a = _tweenLookup[id].tweens;
11862			a[i = a.length] = tween;
11863			if (scrub) {
11864				while (--i > -1) {
11865					if (a[i] === tween) {
11866						a.splice(i, 1);
11867					}
11868				}
11869			}
11870		}
11871		return _tweenLookup[id].tweens;
11872	},
11873	    _onOverwrite = function (overwrittenTween, overwritingTween, target, killedProps) {
11874		var func = overwrittenTween.vars.onOverwrite,
11875		    r1,
11876		    r2;
11877		if (func) {
11878			r1 = func(overwrittenTween, overwritingTween, target, killedProps);
11879		}
11880		func = TweenLite.onOverwrite;
11881		if (func) {
11882			r2 = func(overwrittenTween, overwritingTween, target, killedProps);
11883		}
11884		return r1 !== false && r2 !== false;
11885	},
11886	    _applyOverwrite = function (target, tween, props, mode, siblings) {
11887		var i, changed, curTween, l;
11888		if (mode === 1 || mode >= 4) {
11889			l = siblings.length;
11890			for (i = 0; i < l; i++) {
11891				if ((curTween = siblings[i]) !== tween) {
11892					if (!curTween._gc) {
11893						if (curTween._kill(null, target, tween)) {
11894							changed = true;
11895						}
11896					}
11897				} else if (mode === 5) {
11898					break;
11899				}
11900			}
11901			return changed;
11902		}
11903		//NOTE: Add 0.0000000001 to overcome floating point errors that can cause the startTime to be VERY slightly off (when a tween's time() is set for example)
11904		var startTime = tween._startTime + _tinyNum,
11905		    overlaps = [],
11906		    oCount = 0,
11907		    zeroDur = tween._duration === 0,
11908		    globalStart;
11909		i = siblings.length;
11910		while (--i > -1) {
11911			if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) {
11912				//ignore
11913			} else if (curTween._timeline !== tween._timeline) {
11914				globalStart = globalStart || _checkOverlap(tween, 0, zeroDur);
11915				if (_checkOverlap(curTween, globalStart, zeroDur) === 0) {
11916					overlaps[oCount++] = curTween;
11917				}
11918			} else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) {
11919				overlaps[oCount++] = curTween;
11920			}
11921		}
11922
11923		i = oCount;
11924		while (--i > -1) {
11925			curTween = overlaps[i];
11926			if (mode === 2) if (curTween._kill(props, target, tween)) {
11927				changed = true;
11928			}
11929			if (mode !== 2 || !curTween._firstPT && curTween._initted) {
11930				if (mode !== 2 && !_onOverwrite(curTween, tween)) {
11931					continue;
11932				}
11933				if (curTween._enabled(false, false)) {
11934					//if all property tweens have been overwritten, kill the tween.
11935					changed = true;
11936				}
11937			}
11938		}
11939		return changed;
11940	},
11941	    _checkOverlap = function (tween, reference, zeroDur) {
11942		var tl = tween._timeline,
11943		    ts = tl._timeScale,
11944		    t = tween._startTime;
11945		while (tl._timeline) {
11946			t += tl._startTime;
11947			ts *= tl._timeScale;
11948			if (tl._paused) {
11949				return -100;
11950			}
11951			tl = tl._timeline;
11952		}
11953		t /= ts;
11954		return t > reference ? t - reference : zeroDur && t === reference || !tween._initted && t - reference < 2 * _tinyNum ? _tinyNum : (t += tween.totalDuration() / tween._timeScale / ts) > reference + _tinyNum ? 0 : t - reference - _tinyNum;
11955	};
11956
11957	//---- TweenLite instance methods -----------------------------------------------------------------------------
11958
11959	p._init = function () {
11960		var v = this.vars,
11961		    op = this._overwrittenProps,
11962		    dur = this._duration,
11963		    immediate = !!v.immediateRender,
11964		    ease = v.ease,
11965		    i,
11966		    initPlugins,
11967		    pt,
11968		    p,
11969		    startVars,
11970		    l;
11971		if (v.startAt) {
11972			if (this._startAt) {
11973				this._startAt.render(-1, true); //if we've run a startAt previously (when the tween instantiated), we should revert it so that the values re-instantiate correctly particularly for relative tweens. Without this, a TweenLite.fromTo(obj, 1, {x:"+=100"}, {x:"-=100"}), for example, would actually jump to +=200 because the startAt would run twice, doubling the relative change.
11974				this._startAt.kill();
11975			}
11976			startVars = {};
11977			for (p in v.startAt) {
11978				//copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, 1, from, to).fromTo(e, 1, to, from);
11979				startVars[p] = v.startAt[p];
11980			}
11981			startVars.data = "isStart";
11982			startVars.overwrite = false;
11983			startVars.immediateRender = true;
11984			startVars.lazy = immediate && v.lazy !== false;
11985			startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop).
11986			startVars.onUpdate = v.onUpdate;
11987			startVars.onUpdateParams = v.onUpdateParams;
11988			startVars.onUpdateScope = v.onUpdateScope || v.callbackScope || this;
11989			this._startAt = TweenLite.to(this.target, 0, startVars);
11990			if (immediate) {
11991				if (this._time > 0) {
11992					this._startAt = null; //tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in TimelineLite/Max instances where immediateRender was false (which is the default in the convenience methods like from()).
11993				} else if (dur !== 0) {
11994					return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a TimelineLite or TimelineMax, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting.
11995				}
11996			}
11997		} else if (v.runBackwards && dur !== 0) {
11998			//from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards)
11999			if (this._startAt) {
12000				this._startAt.render(-1, true);
12001				this._startAt.kill();
12002				this._startAt = null;
12003			} else {
12004				if (this._time !== 0) {
12005					//in rare cases (like if a from() tween runs and then is invalidate()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0
12006					immediate = false;
12007				}
12008				pt = {};
12009				for (p in v) {
12010					//copy props into a new object and skip any reserved props, otherwise onComplete or onUpdate or onStart could fire. We should, however, permit autoCSS to go through.
12011					if (!_reservedProps[p] || p === "autoCSS") {
12012						pt[p] = v[p];
12013					}
12014				}
12015				pt.overwrite = 0;
12016				pt.data = "isFromStart"; //we tag the tween with as "isFromStart" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a "from()" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in.
12017				pt.lazy = immediate && v.lazy !== false;
12018				pt.immediateRender = immediate; //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after)
12019				this._startAt = TweenLite.to(this.target, 0, pt);
12020				if (!immediate) {
12021					this._startAt._init(); //ensures that the initial values are recorded
12022					this._startAt._enabled(false); //no need to have the tween render on the next cycle. Disable it because we'll always manually control the renders of the _startAt tween.
12023					if (this.vars.immediateRender) {
12024						this._startAt = null;
12025					}
12026				} else if (this._time === 0) {
12027					return;
12028				}
12029			}
12030		}
12031		this._ease = ease = !ease ? TweenLite.defaultEase : ease instanceof Ease ? ease : typeof ease === "function" ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase;
12032		if (v.easeParams instanceof Array && ease.config) {
12033			this._ease = ease.config.apply(ease, v.easeParams);
12034		}
12035		this._easeType = this._ease._type;
12036		this._easePower = this._ease._power;
12037		this._firstPT = null;
12038
12039		if (this._targets) {
12040			l = this._targets.length;
12041			for (i = 0; i < l; i++) {
12042				if (this._initProps(this._targets[i], this._propLookup[i] = {}, this._siblings[i], op ? op[i] : null, i)) {
12043					initPlugins = true;
12044				}
12045			}
12046		} else {
12047			initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op, 0);
12048		}
12049
12050		if (initPlugins) {
12051			TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite
12052		}
12053		if (op) if (!this._firstPT) if (typeof this.target !== "function") {
12054			//if all tweening properties have been overwritten, kill the tween. If the target is a function, it's probably a delayedCall so let it live.
12055			this._enabled(false, false);
12056		}
12057		if (v.runBackwards) {
12058			pt = this._firstPT;
12059			while (pt) {
12060				pt.s += pt.c;
12061				pt.c = -pt.c;
12062				pt = pt._next;
12063			}
12064		}
12065		this._onUpdate = v.onUpdate;
12066		this._initted = true;
12067	};
12068
12069	p._initProps = function (target, propLookup, siblings, overwrittenProps, index) {
12070		var p, i, initPlugins, plugin, pt, v;
12071		if (target == null) {
12072			return false;
12073		}
12074
12075		if (_lazyLookup[target._gsTweenID]) {
12076			_lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end)
12077		}
12078
12079		if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) {
12080			//it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity). Note: we cannot check "nodeType" on the window inside an iframe.
12081			_autoCSS(this.vars, target);
12082		}
12083		for (p in this.vars) {
12084			v = this.vars[p];
12085			if (_reservedProps[p]) {
12086				if (v) if (v instanceof Array || v.push && _isArray(v)) if (v.join("").indexOf("{self}") !== -1) {
12087					this.vars[p] = v = this._swapSelfInParams(v, this);
12088				}
12089			} else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this, index)) {
12090
12091				//t - target 		[object]
12092				//p - property 		[string]
12093				//s - start			[number]
12094				//c - change		[number]
12095				//f - isFunction	[boolean]
12096				//n - name			[string]
12097				//pg - isPlugin 	[boolean]
12098				//pr - priority		[number]
12099				//m - mod           [function | 0]
12100				this._firstPT = pt = { _next: this._firstPT, t: plugin, p: "setRatio", s: 0, c: 1, f: 1, n: p, pg: 1, pr: plugin._priority, m: 0 };
12101				i = plugin._overwriteProps.length;
12102				while (--i > -1) {
12103					propLookup[plugin._overwriteProps[i]] = this._firstPT;
12104				}
12105				if (plugin._priority || plugin._onInitAllProps) {
12106					initPlugins = true;
12107				}
12108				if (plugin._onDisable || plugin._onEnable) {
12109					this._notifyPluginsOfEnabled = true;
12110				}
12111				if (pt._next) {
12112					pt._next._prev = pt;
12113				}
12114			} else {
12115				propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter, index);
12116			}
12117		}
12118
12119		if (overwrittenProps) if (this._kill(overwrittenProps, target)) {
12120			//another tween may have tried to overwrite properties of this tween before init() was called (like if two tweens start at the same time, the one created second will run first)
12121			return this._initProps(target, propLookup, siblings, overwrittenProps, index);
12122		}
12123		if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) {
12124			this._kill(propLookup, target);
12125			return this._initProps(target, propLookup, siblings, overwrittenProps, index);
12126		}
12127		if (this._firstPT) if (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration) {
12128			//zero duration tweens don't lazy render by default; everything else does.
12129			_lazyLookup[target._gsTweenID] = true;
12130		}
12131		return initPlugins;
12132	};
12133
12134	p.render = function (time, suppressEvents, force) {
12135		var prevTime = this._time,
12136		    duration = this._duration,
12137		    prevRawPrevTime = this._rawPrevTime,
12138		    isComplete,
12139		    callback,
12140		    pt,
12141		    rawPrevTime;
12142		if (time >= duration - 0.0000001 && time >= 0) {
12143			//to work around occasional floating point math artifacts.
12144			this._totalTime = this._time = duration;
12145			this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
12146			if (!this._reversed) {
12147				isComplete = true;
12148				callback = "onComplete";
12149				force = force || this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
12150			}
12151			if (duration === 0) if (this._initted || !this.vars.lazy || force) {
12152				//zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
12153				if (this._startTime === this._timeline._duration) {
12154					//if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent roun
12154ding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate.
12155					time = 0;
12156				}
12157				if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) {
12158					//note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause.
12159					force = true;
12160					if (prevRawPrevTime > _tinyNum) {
12161						callback = "onReverseComplete";
12162					}
12163				}
12164				this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
12165			}
12166		} else if (time < 0.0000001) {
12167			//to work around occasional floating point math artifacts, round super small values to 0.
12168			this._totalTime = this._time = 0;
12169			this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
12170			if (prevTime !== 0 || duration === 0 && prevRawPrevTime > 0) {
12171				callback = "onReverseComplete";
12172				isComplete = this._reversed;
12173			}
12174			if (time < 0) {
12175				this._active = false;
12176				if (duration === 0) if (this._initted || !this.vars.lazy || force) {
12177					//zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
12178					if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) {
12179						force = true;
12180					}
12181					this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
12182				}
12183			}
12184			if (!this._initted || this._startAt && this._startAt.progress()) {
12185				//if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. Also, we check progress() because if startAt has already rendered at its end, we should force a render at its beginning. Otherwise, if you put the playhead directly on top of where a fromTo({immediateRender:false}) starts, and then move it backwards, the from() won't revert its values.
12186				force = true;
12187			}
12188		} else {
12189			this._totalTime = this._time = time;
12190
12191			if (this._easeType) {
12192				var r = time / duration,
12193				    type = this._easeType,
12194				    pow = this._easePower;
12195				if (type === 1 || type === 3 && r >= 0.5) {
12196					r = 1 - r;
12197				}
12198				if (type === 3) {
12199					r *= 2;
12200				}
12201				if (pow === 1) {
12202					r *= r;
12203				} else if (pow === 2) {
12204					r *= r * r;
12205				} else if (pow === 3) {
12206					r *= r * r * r;
12207				} else if (pow === 4) {
12208					r *= r * r * r * r;
12209				}
12210
12211				if (type === 1) {
12212					this.ratio = 1 - r;
12213				} else if (type === 2) {
12214					this.ratio = r;
12215				} else if (time / duration < 0.5) {
12216					this.ratio = r / 2;
12217				} else {
12218					this.ratio = 1 - r / 2;
12219				}
12220			} else {
12221				this.ratio = this._ease.getRatio(time / duration);
12222			}
12223		}
12224
12225		if (this._time === prevTime && !force) {
12226			return;
12227		} else if (!this._initted) {
12228			this._init();
12229			if (!this._initted || this._gc) {
12230				//immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that over
12230writing occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example.
12231				return;
12232			} else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) {
12233				this._time = this._totalTime = prevTime;
12234				this._rawPrevTime = prevRawPrevTime;
12235				_lazyTweens.push(this);
12236				this._lazy = [time, suppressEvents];
12237				return;
12238			}
12239			//_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently.
12240			if (this._time && !isComplete) {
12241				this.ratio = this._ease.getRatio(this._time / duration);
12242			} else if (isComplete && this._ease._calcEnd) {
12243				this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1);
12244			}
12245		}
12246		if (this._lazy !== false) {
12247			//in case a lazy render is pending, we should flush it because the new render is occurring now (imagine a lazy tween instantiating and then immediately the user calls tween.seek(tween.duration()), skipping to the end - the end render would be forced, and then if we didn't flush the lazy render, it'd fire AFTER the seek(), rendering it at the wrong time.
12248			this._lazy = false;
12249		}
12250		if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
12251			this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
12252		}
12253		if (prevTime === 0) {
12254			if (this._startAt) {
12255				if (time >= 0) {
12256					this._startAt.render(time, true, force);
12257				} else if (!callback) {
12258					callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area.
12259				}
12260			}
12261			if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) {
12262				this._callback("onStart");
12263			}
12264		}
12265		pt = this._firstPT;
12266		while (pt) {
12267			if (pt.f) {
12268				pt.t[pt.p](pt.c * this.ratio + pt.s);
12269			} else {
12270				pt.t[pt.p] = pt.c * this.ratio + pt.s;
12271			}
12272			pt = pt._next;
12273		}
12274
12275		if (this._onUpdate) {
12276			if (time < 0) if (this._startAt && time !== -0.0001) {
12277				//if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
12278				this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete.
12279			}
12280			if (!suppressEvents) if (this._time !== prevTime || isComplete || force) {
12281				this._callback("onUpdate");
12282			}
12283		}
12284		if (callback) if (!this._gc || force) {
12285			//check _gc because there's a chance that kill() could be called in an onUpdate
12286			if (time < 0 && this._startAt && !this._onUpdate && time !== -0.0001) {
12287				//-0.0001 is a special value that we use when looping back to the beginning of a repeated TimelineMax, in which case we shouldn't render the _startAt values.
12288				this._startAt.render(time, true, force);
12289			}
12290			if (isComplete) {
12291				if (this._timeline.autoRemoveChildren) {
12292					this._enabled(false, false);
12293				}
12294				this._active = false;
12295			}
12296			if (!suppressEvents && this.vars[callback]) {
12297				this._callback(callback);
12298			}
12299			if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) {
12300				//the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon sce
12300nario, but possible nonetheless.
12301				this._rawPrevTime = 0;
12302			}
12303		}
12304	};
12305
12306	p._kill = function (vars, target, overwritingTween) {
12307		if (vars === "all") {
12308			vars = null;
12309		}
12310		if (vars == null) if (target == null || target === this.target) {
12311			this._lazy = false;
12312			return this._enabled(false, false);
12313		}
12314		target = typeof target !== "string" ? target || this._targets || this.target : TweenLite.selector(target) || target;
12315		var simultaneousOverwrite = overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline,
12316		    i,
12317		    overwrittenProps,
12318		    p,
12319		    pt,
12320		    propLookup,
12321		    changed,
12322		    killProps,
12323		    record,
12324		    killed;
12325		if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") {
12326			i = target.length;
12327			while (--i > -1) {
12328				if (this._kill(vars, target[i], overwritingTween)) {
12329					changed = true;
12330				}
12331			}
12332		} else {
12333			if (this._targets) {
12334				i = this._targets.length;
12335				while (--i > -1) {
12336					if (target === this._targets[i]) {
12337						propLookup = this._propLookup[i] || {};
12338						this._overwrittenProps = this._overwrittenProps || [];
12339						overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all";
12340						break;
12341					}
12342				}
12343			} else if (target !== this.target) {
12344				return false;
12345			} else {
12346				propLookup = this._propLookup;
12347				overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all";
12348			}
12349
12350			if (propLookup) {
12351				killProps = vars || propLookup;
12352				record = vars !== overwrittenProps && overwrittenProps !== "all" && vars !== propLookup && (typeof vars !== "object" || !vars._tempKill); //_tempKill is a super-secret way to delete a particular tweening property but NOT have it remembered as an official overwritten property (like in BezierPlugin)
12353				if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) {
12354					for (p in killProps) {
12355						if (propLookup[p]) {
12356							if (!killed) {
12357								killed = [];
12358							}
12359							killed.push(p);
12360						}
12361					}
12362					if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) {
12363						//if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it).
12364						return false;
12365					}
12366				}
12367
12368				for (p in killProps) {
12369					if (pt = propLookup[p]) {
12370						if (simultaneousOverwrite) {
12371							//if another tween overwrites this one and they both start at exactly the same time, yet this tween has already rendered once (for example, at 0.001) because it's first in the queue, we should revert the values to where they were at 0 so that the starting values aren't contaminated on the overwriting tween.
12372							if (pt.f) {
12373								pt.t[pt.p](pt.s);
12374							} else {
12375								pt.t[pt.p] = pt.s;
12376							}
12377							changed = true;
12378						}
12379						if (pt.pg && pt.t._kill(killProps)) {
12380							changed = true; //some plugins need to be notified so they can perform cleanup tasks first
12381						}
12382						if (!pt.pg || pt.t._overwriteProps.length === 0) {
12383							if (pt._prev) {
12384								pt._prev._next = pt._next;
12385							} else if (pt === this._firstPT) {
12386								this._firstPT = pt._next;
12387							}
12388							if (pt._next) {
12389								pt._next._prev = pt._prev;
12390							}
12391							pt._next = pt._prev = null;
12392						}
12393						delete propLookup[p];
12394					}
12395					if (record) {
12396						overwrittenProps[p] = 1;
12397					}
12398				}
12399				if (!this._firstPT && this._initted) {
12400					//if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening.
12401					this._enabled(false, false);
12402				}
12403			}
12404		}
12405		return changed;
12406	};
12407
12408	p.invalidate = function () {
12409		if (this._notifyPluginsOfEnabled) {
12410			TweenLite._onPluginEvent("_onDisable", this);
12411		}
12412		this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null;
12413		this._notifyPluginsOfEnabled = this._active = this._lazy = false;
12414		this._propLookup = this._targets ? {} : [];
12415		Animation.prototype.invalidate.call(this);
12416		if (this.vars.immediateRender) {
12417			this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render)
12418			this.render(Math.min(0, -this._delay)); //in case delay is negative.
12419		}
12420		return this;
12421	};
12422
12423	p._enabled = function (enabled, ignoreTimeline) {
12424		if (!_tickerActive) {
12425			_ticker.wake();
12426		}
12427		if (enabled && this._gc) {
12428			var targets = this._targets,
12429			    i;
12430			if (targets) {
12431				i = targets.length;
12432				while (--i > -1) {
12433					this._siblings[i] = _register(targets[i], this, true);
12434				}
12435			} else {
12436				this._siblings = _register(this.target, this, true);
12437			}
12438		}
12439		Animation.prototype._enabled.call(this, enabled, ignoreTimeline);
12440		if (this._notifyPluginsOfEnabled) if (this._firstPT) {
12441			return TweenLite._onPluginEvent(enabled ? "_onEnable" : "_onDisable", this);
12442		}
12443		return false;
12444	};
12445
12446	//----TweenLite static methods -----------------------------------------------------
12447
12448	TweenLite.to = function (target, duration, vars) {
12449		return new TweenLite(target, duration, vars);
12450	};
12451
12452	TweenLite.from = function (target, duration, vars) {
12453		vars.runBackwards = true;
12454		vars.immediateRender = vars.immediateRender != false;
12455		return new TweenLite(target, duration, vars);
12456	};
12457
12458	TweenLite.fromTo = function (target, duration, fromVars, toVars) {
12459		toVars.startAt = fromVars;
12460		toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
12461		return new TweenLite(target, duration, toVars);
12462	};
12463
12464	TweenLite.delayedCall = function (delay, callback, params, scope, useFrames) {
12465		return new TweenLite(callback, 0, { delay: delay, onComplete: callback, onCompleteParams: params, callbackScope: scope, onReverseComplete: callback, onReverseCompleteParams: params, immediateRender: false, lazy: false, useFrames: useFrames, overwrite: 0 });
12466	};
12467
12468	TweenLite.set = function (target, vars) {
12469		return new TweenLite(target, 0, vars);
12470	};
12471
12472	TweenLite.getTweensOf = function (target, onlyActive) {
12473		if (target == null) {
12474			return [];
12475		}
12476		target = typeof target !== "string" ? target : TweenLite.selector(target) || target;
12477		var i, a, j, t;
12478		if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") {
12479			i = target.length;
12480			a = [];
12481			while (--i > -1) {
12482				a = a.concat(TweenLite.getTweensOf(target[i], onlyActive));
12483			}
12484			i = a.length;
12485			//now get rid of any duplicates (tweens of arrays of objects could cause duplicates)
12486			while (--i > -1) {
12487				t = a[i];
12488				j = i;
12489				while (--j > -1) {
12490					if (t === a[j]) {
12491						a.splice(i, 1);
12492					}
12493				}
12494			}
12495		} else if (target._gsTweenID) {
12496			a = _register(target).concat();
12497			i = a.length;
12498			while (--i > -1) {
12499				if (a[i]._gc || onlyActive && !a[i].isActive()) {
12500					a.splice(i, 1);
12501				}
12502			}
12503		}
12504		return a || [];
12505	};
12506
12507	TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function (target, onlyActive, vars) {
12508		if (typeof onlyActive === "object") {
12509			vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted)
12510			onlyActive = false;
12511		}
12512		var a = TweenLite.getTweensOf(target, onlyActive),
12513		    i = a.length;
12514		while (--i > -1) {
12515			a[i]._kill(vars, target);
12516		}
12517	};
12518
12519	/*
12520  * ----------------------------------------------------------------
12521  * TweenPlugin   (could easily be split out as a separate file/class, but included for ease of use (so that people don't need to include another script call before loading plugins which is easy to forget)
12522  * ----------------------------------------------------------------
12523  */
12524	var TweenPlugin = _class("plugins.TweenPlugin", function (props, priority) {
12525		this._overwriteProps = (props || "").split(",");
12526		this._propName = this._overwriteProps[0];
12527		this._priority = priority || 0;
12528		this._super = TweenPlugin.prototype;
12529	}, true);
12530
12531	p = TweenPlugin.prototype;
12532	TweenPlugin.version = "1.19.0";
12533	TweenPlugin.API = 2;
12534	p._firstPT = null;
12535	p._addTween = _addPropTween;
12536	p.setRatio = _setRatio;
12537
12538	p._kill = function (lookup) {
12539		var a = this._overwriteProps,
12540		    pt = this._firstPT,
12541		    i;
12542		if (lookup[this._propName] != null) {
12543			this._overwriteProps = [];
12544		} else {
12545			i = a.length;
12546			while (--i > -1) {
12547				if (lookup[a[i]] != null) {
12548					a.splice(i, 1);
12549				}
12550			}
12551		}
12552		while (pt) {
12553			if (lookup[pt.n] != null) {
12554				if (pt._next) {
12555					pt._next._prev = pt._prev;
12556				}
12557				if (pt._prev) {
12558					pt._prev._next = pt._next;
12559					pt._prev = null;
12560				} else if (this._firstPT === pt) {
12561					this._firstPT = pt._next;
12562				}
12563			}
12564			pt = pt._next;
12565		}
12566		return false;
12567	};
12568
12569	p._mod = p._roundProps = function (lookup) {
12570		var pt = this._firstPT,
12571		    val;
12572		while (pt) {
12573			val = lookup[this._propName] || pt.n != null && lookup[pt.n.split(this._propName + "_").join("")];
12574			if (val && typeof val === "function") {
12575				//some properties that are very plugin-specific add a prefix named after the _propName plus an underscore, so we need to ignore that extra stuff here.
12576				if (pt.f === 2) {
12577					pt.t._applyPT.m = val;
12578				} else {
12579					pt.m = val;
12580				}
12581			}
12582			pt = pt._next;
12583		}
12584	};
12585
12586	TweenLite._onPluginEvent = function (type, tween) {
12587		var pt = tween._firstPT,
12588		    changed,
12589		    pt2,
12590		    first,
12591		    last,
12592		    next;
12593		if (type === "_onInitAllProps") {
12594			//sorts the PropTween linked list in order of priority because some plugins need to render earlier/later than others, like MotionBlurPlugin applies its effects after all x/y/alpha tweens have rendered on each frame.
12595			while (pt) {
12596				next = pt._next;
12597				pt2 = first;
12598				while (pt2 && pt2.pr > pt.pr) {
12599					pt2 = pt2._next;
12600				}
12601				if (pt._prev = pt2 ? pt2._prev : last) {
12602					pt._prev._next = pt;
12603				} else {
12604					first = pt;
12605				}
12606				if (pt._next = pt2) {
12607					pt2._prev = pt;
12608				} else {
12609					last = pt;
12610				}
12611				pt = next;
12612			}
12613			pt = tween._firstPT = first;
12614		}
12615		while (pt) {
12616			if (pt.pg) if (typeof pt.t[type] === "function") if (pt.t[type]()) {
12617				changed = true;
12618			}
12619			pt = pt._next;
12620		}
12621		return changed;
12622	};
12623
12624	TweenPlugin.activate = function (plugins) {
12625		var i = plugins.length;
12626		while (--i > -1) {
12627			if (plugins[i].API === TweenPlugin.API) {
12628				_plugins[new plugins[i]()._propName] = plugins[i];
12629			}
12630		}
12631		return true;
12632	};
12633
12634	//provides a more concise way to define plugins that have no dependencies besides TweenPlugin and TweenLite, wrapping common boilerplate stuff into one function (added in 1.9.0). You don't NEED to use this to define a plugin - the old way still works and can be useful in certain (rare) situations.
12635	_gsDefine.plugin = function (config) {
12636		if (!config || !config.propName || !config.init || !config.API) {
12637			throw "illegal plugin definition.";
12638		}
12639		var propName = config.propName,
12640		    priority = config.priority || 0,
12641		    overwriteProps = config.overwriteProps,
12642		    map = { init: "_onInitTween", set: "setRatio", kill: "_kill", round: "_mod", mod: "_mod", initAll: "_onInitAllProps" },
12643		    Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin", function () {
12644			TweenPlugin.call(this, propName, priority);
12645			this._overwriteProps = overwriteProps || [];
12646		}, config.global === true),
12647		    p = Plugin.prototype = new TweenPlugin(propName),
12648		    prop;
12649		p.constructor = Plugin;
12650		Plugin.API = config.API;
12651		for (prop in map) {
12652			if (typeof config[prop] === "function") {
12653				p[map[prop]] = config[prop];
12654			}
12655		}
12656		Plugin.version = config.version;
12657		TweenPlugin.activate([Plugin]);
12658		return Plugin;
12659	};
12660
12661	//now run through all the dependencies discovered and if any are missing, log that to the console as a warning. This is why it's best to have TweenLite load last - it can check all the dependencies for you.
12662	a = window._gsQueue;
12663	if (a) {
12664		for (i = 0; i < a.length; i++) {
12665			a[i]();
12666		}
12667		for (p in _defLookup) {
12668			if (!_defLookup[p].func) {
12669				window.console.log("GSAP encountered missing dependency: " + p);
12670			}
12671		}
12672	}
12673
12674	_tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated
12675})(typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window, "TweenLite");
12676/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5)))
12677
12678/***/ }),
12679/* 2 */
12680/***/ (function(module, exports, __webpack_require__) {
12681
12682var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
12683 * ScrollMagic v2.0.5 (2015-04-29)
12684 * The javascript library for magical scroll interactions.
12685 * (c) 2015 Jan Paepke (@janpaepke)
12686 * Project Website: http://scrollmagic.io
12687 * 
12688 * @version 2.0.5
12689 * @license Dual licensed under MIT license and GPL.
12690 * @author Jan Paepke - [email protected]
12691 *
12692 * @file ScrollMagic main library.
12693 */
12694/**
12695 * @namespace ScrollMagic
12696 */
12697(function (root, factory) {
12698	if (true) {
12699		// AMD. Register as an anonymous module.
12700		!(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
12701				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
12702				(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
12703				__WEBPACK_AMD_DEFINE_FACTORY__),
12704				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
12705	} else if (typeof exports === 'object') {
12706		// CommonJS
12707		module.exports = factory();
12708	} else {
12709		// Browser global
12710		root.ScrollMagic = factory();
12711	}
12712})(this, function () {
12713	"use strict";
12714
12715	var ScrollMagic = function () {
12716		_util.log(2, '(COMPATIBILITY NOTICE) -> As of ScrollMagic 2.0.0 you need to use \'new ScrollMagic.Controller()\' to create a new controller instance. Use \'new ScrollMagic.Scene()\' to instance a scene.');
12717	};
12718
12719	ScrollMagic.version = "2.0.5";
12720
12721	// TODO: temporary workaround for chrome's scroll jitter bug
12722	window.addEventListener("mousewheel", function () {});
12723
12724	// global const
12725	var PIN_SPACER_ATTRIBUTE = "data-scrollmagic-pin-spacer";
12726
12727	/**
12728  * The main class that is needed once per scroll container.
12729  *
12730  * @class
12731  *
12732  * @example
12733  * // basic initialization
12734  * var controller = new ScrollMagic.Controller();
12735  *
12736  * // passing options
12737  * var controller = new ScrollMagic.Controller({container: "#myContainer", loglevel: 3});
12738  *
12739  * @param {object} [options] - An object containing one or more options for the controller.
12740  * @param {(string|object)} [options.container=window] - A selector, DOM object that references the main container for scrolling.
12741  * @param {boolean} [options.vertical=true] - Sets the scroll mode to vertical (`true`) or horizontal (`false`) scrolling.
12742  * @param {object} [options.globalSceneOptions={}] - These options will be passed to every Scene that is added to the controller using the addScene method. For more information on Scene options see {@link ScrollMagic.Scene}.
12743  * @param {number} [options.loglevel=2] Loglevel for debugging. Note that logging is disabled in the minified version of ScrollMagic.
12744  ** `0` => silent
12745  ** `1` => errors
12746  ** `2` => errors, warnings
12747  ** `3` => errors, warnings, debuginfo
12748  * @param {boolean} [options.refreshInterval=100] - Some changes don't call events by default, like changing the container size or moving a scene trigger element.  
12749  This interval polls these parameters to fire the necessary events.  
12750  If you don't use custom containers, trigger elements or have static layouts, where the positions of the trigger elements don't change, you can set this to 0 disable interval checking and improve performance.
12751  *
12752  */
12753	ScrollMagic.Controller = function (options) {
12754		/*
12755  	 * ----------------------------------------------------------------
12756  	 * settings
12757  	 * ----------------------------------------------------------------
12758  	 */
12759		var NAMESPACE = 'ScrollMagic.Controller',
12760		    SCROLL_DIRECTION_FORWARD = 'FORWARD',
12761		    SCROLL_DIRECTION_REVERSE = 'REVERSE',
12762		    SCROLL_DIRECTION_PAUSED = 'PAUSED',
12763		    DEFAULT_OPTIONS = CONTROLLER_OPTIONS.defaults;
12764
12765		/*
12766  	 * ----------------------------------------------------------------
12767  	 * private vars
12768  	 * ----------------------------------------------------------------
12769  	 */
12770		var Controller = this,
12771		    _options = _util.extend({}, DEFAULT_OPTIONS, options),
12772		    _sceneObjects = [],
12773		    _updateScenesOnNextCycle = false,
12774
12775		// can be boolean (true => all scenes) or an array of scenes to be updated
12776		_scrollPos = 0,
12777		    _scrollDirection = SCROLL_DIRECTION_PAUSED,
12778		    _isDocument = true,
12779		    _viewPortSize = 0,
12780		    _enabled = true,
12781		    _updateTimeout,
12782		    _refreshTimeout;
12783
12784		/*
12785  	 * ----------------------------------------------------------------
12786  	 * private functions
12787  	 * ----------------------------------------------------------------
12788  	 */
12789
12790		/**
12791   * Internal constructor function of the ScrollMagic Controller
12792   * @private
12793   */
12794		var construct = function () {
12795			for (var key in _options) {
12796				if (!DEFAULT_OPTIONS.hasOwnProperty(key)) {
12797					log(2, "WARNING: Unknown option \"" + key + "\"");
12798					delete _options[key];
12799				}
12800			}
12801			_options.container = _util.get.elements(_options.container)[0];
12802			// check ScrollContainer
12803			if (!_options.container) {
12804				log(1, "ERROR creating object " + NAMESPACE + ": No valid scroll container supplied");
12805				throw NAMESPACE + " init failed."; // cancel
12806			}
12807			_isDocument = _options.container === window || _options.container === document.body || !document.body.contains(_options.container);
12808			// normalize to window
12809			if (_isDocument) {
12810				_options.container = window;
12811			}
12812			// update container size immediately
12813			_viewPortSize = getViewportSize();
12814			// set event handlers
12815			_options.container.addEventListener("resize", onChange);
12816			_options.container.addEventListener("scroll", onChange);
12817
12818			_options.refreshInterval = parseInt(_options.refreshInterval) || DEFAULT_OPTIONS.refreshInterval;
12819			scheduleRefresh();
12820
12821			log(3, "added new " + NAMESPACE + " controller (v" + ScrollMagic.version + ")");
12822		};
12823
12824		/**
12825   * Schedule the next execution of the refresh function
12826   * @private
12827   */
12828		var scheduleRefresh = function () {
12829			if (_options.refreshInterval > 0) {
12830				_refreshTimeout = window.setTimeout(refresh, _options.refreshInterval);
12831			}
12832		};
12833
12834		/**
12835   * Default function to get scroll pos - overwriteable using `Controller.scrollPos(newFunction)`
12836   * @private
12837   */
12838		var getScrollPos = function () {
12839			return _options.vertical ? _util.get.scrollTop(_options.container) : _util.get.scrollLeft(_options.container);
12840		};
12841
12842		/**
12843   * Returns the current viewport Size (width vor horizontal, height for vertical)
12844   * @private
12845   */
12846		var getViewportSize = function () {
12847			return _options.vertical ? _util.get.height(_options.container) : _util.get.width(_options.container);
12848		};
12849
12850		/**
12851   * Default function to set scroll pos - overwriteable using `Controller.scrollTo(newFunction)`
12852   * Make available publicly for pinned mousewheel workaround.
12853   * @private
12854   */
12855		var setScrollPos = this._setScrollPos = function (pos) {
12856			if (_options.vertical) {
12857				if (_isDocument) {
12858					window.scrollTo(_util.get.scrollLeft(), pos);
12859				} else {
12860					_options.container.scrollTop = pos;
12861				}
12862			} else {
12863				if (_isDocument) {
12864					window.scrollTo(pos, _util.get.scrollTop());
12865				} else {
12866					_options.container.scrollLeft = pos;
12867				}
12868			}
12869		};
12870
12871		/**
12872   * Handle updates in cycles instead of on scroll (performance)
12873   * @private
12874   */
12875		var updateScenes = function () {
12876			if (_enabled && _updateScenesOnNextCycle) {
12877				// determine scenes to update
12878				var scenesToUpdate = _util.type.Array(_updateScenesOnNextCycle) ? _updateScenesOnNextCycle : _sceneObjects.slice(0);
12879				// reset scenes
12880				_updateScenesOnNextCycle = false;
12881				var oldScrollPos = _scrollPos;
12882				// update scroll pos now instead of onChange, as it might have changed since scheduling (i.e. in-browser smooth scroll)
12883				_scrollPos = Controller.scrollPos();
12884				var deltaScroll = _scrollPos - oldScrollPos;
12885				if (deltaScroll !== 0) {
12886					// scroll position changed?
12887					_scrollDirection = deltaScroll > 0 ? SCROLL_DIRECTION_FORWARD : SCROLL_DIRECTION_REVERSE;
12888				}
12889				// reverse order of scenes if scrolling reverse
12890				if (_scrollDirection === SCROLL_DIRECTION_REVERSE) {
12891					scenesToUpdate.reverse();
12892				}
12893				// update scenes
12894				scenesToUpdate.forEach(function (scene, index) {
12895					log(3, "updating Scene " + (index + 1) + "/" + scenesToUpdate.length + " (" + _sceneObjects.length + " total)");
12896					scene.update(true);
12897				});
12898				if (scenesToUpdate.length === 0 && _options.loglevel >= 3) {
12899					log(3, "updating 0 Scenes (nothing added to controller)");
12900				}
12901			}
12902		};
12903
12904		/**
12905   * Initializes rAF callback
12906   * @private
12907   */
12908		var debounceUpdate = function () {
12909			_updateTimeout = _util.rAF(updateScenes);
12910		};
12911
12912		/**
12913   * Handles Container changes
12914   * @private
12915   */
12916		var onChange = function (e) {
12917			log(3, "event fired causing an update:", e.type);
12918			if (e.type == "resize") {
12919				// resize
12920				_viewPortSize = getViewportSize();
12921				_scrollDirection = SCROLL_DIRECTION_PAUSED;
12922			}
12923			// schedule update
12924			if (_updateScenesOnNextCycle !== true) {
12925				_updateScenesOnNextCycle = true;
12926				debounceUpdate();
12927			}
12928		};
12929
12930		var refresh = function () {
12931			if (!_isDocument) {
12932				// simulate resize event. Only works for viewport relevant param (performance)
12933				if (_viewPortSize != getViewportSize()) {
12934					var resizeEvent;
12935					try {
12936						resizeEvent = new Event('resize', {
12937							bubbles: false,
12938							cancelable: false
12939						});
12940					} catch (e) {
12941						// stupid IE
12942						resizeEvent = document.createEvent("Event");
12943						resizeEvent.initEvent("resize", false, false);
12944					}
12945					_options.container.dispatchEvent(resizeEvent);
12946				}
12947			}
12948			_sceneObjects.forEach(function (scene, index) {
12949				// refresh all scenes
12950				scene.refresh();
12951			});
12952			scheduleRefresh();
12953		};
12954
12955		/**
12956   * Send a debug message to the console.
12957   * provided publicly with _log for plugins
12958   * @private
12959   *
12960   * @param {number} loglevel - The loglevel required to initiate output for the message.
12961   * @param {...mixed} output - One or more variables that should be passed to the console.
12962   */
12963		var log = this._log = function (loglevel, output) {
12964			if (_options.loglevel >= loglevel) {
12965				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ") ->");
12966				_util.log.apply(window, arguments);
12967			}
12968		};
12969		// for scenes we have getters for each option, but for the controller we don't, so we need to make it available externally for plugins
12970		this._options = _options;
12971
12972		/**
12973   * Sort scenes in ascending order of their start offset.
12974   * @private
12975   *
12976   * @param {array} ScenesArray - an array of ScrollMagic Scenes that should be sorted
12977   * @return {array} The sorted array of Scenes.
12978   */
12979		var sortScenes = function (ScenesArray) {
12980			if (ScenesArray.length <= 1) {
12981				return ScenesArray;
12982			} else {
12983				var scenes = ScenesArray.slice(0);
12984				scenes.sort(function (a, b) {
12985					return a.scrollOffset() > b.scrollOffset() ? 1 : -1;
12986				});
12987				return scenes;
12988			}
12989		};
12990
12991		/**
12992   * ----------------------------------------------------------------
12993   * public functions
12994   * ----------------------------------------------------------------
12995   */
12996
12997		/**
12998   * Add one ore more scene(s) to the controller.  
12999   * This is the equivalent to `Scene.addTo(controller)`.
13000   * @public
13001   * @example
13002   * // with a previously defined scene
13003   * controller.addScene(scene);
13004   *
13005   * // with a newly created scene.
13006   * controller.addScene(new ScrollMagic.Scene({duration : 0}));
13007   *
13008   * // adding multiple scenes
13009   * controller.addScene([scene, scene2, new ScrollMagic.Scene({duration : 0})]);
13010   *
13011   * @param {(ScrollMagic.Scene|array)} newScene - ScrollMagic Scene or Array of Scenes to be added to the controller.
13012   * @return {Controller} Parent object for chaining.
13013   */
13014		this.addScene = function (newScene) {
13015			if (_util.type.Array(newScene)) {
13016				newScene.forEach(function (scene, index) {
13017					Controller.addScene(scene);
13018				});
13019			} else if (newScene instanceof ScrollMagic.Scene) {
13020				if (newScene.controller() !== Controller) {
13021					newScene.addTo(Controller);
13022				} else if (_sceneObjects.indexOf(newScene) < 0) {
13023					// new scene
13024					_sceneObjects.push(newScene); // add to array
13025					_sceneObjects = sortScenes(_sceneObjects); // sort
13026					newScene.on("shift.controller_sort", function () {
13027						// resort whenever scene moves
13028						_sceneObjects = sortScenes(_sceneObjects);
13029					});
13030					// insert Global defaults.
13031					for (var key in _options.globalSceneOptions) {
13032						if (newScene[key]) {
13033							newScene[key].call(newScene, _options.globalSceneOptions[key]);
13034						}
13035					}
13036					log(3, "adding Scene (now " + _sceneObjects.length + " total)");
13037				}
13038			} else {
13039				log(1, "ERROR: invalid argument supplied for '.addScene()'");
13040			}
13041			return Controller;
13042		};
13043
13044		/**
13045   * Remove one ore more scene(s) from the controller.  
13046   * This is the equivalent to `Scene.remove()`.
13047   * @public
13048   * @example
13049   * // remove a scene from the controller
13050   * controller.removeScene(scene);
13051   *
13052   * // remove multiple scenes from the controller
13053   * controller.removeScene([scene, scene2, scene3]);
13054   *
13055   * @param {(ScrollMagic.Scene|array)} Scene - ScrollMagic Scene or Array of Scenes to be removed from the controller.
13056   * @returns {Controller} Parent object for chaining.
13057   */
13058		this.removeScene = function (Scene) {
13059			if (_util.type.Array(Scene)) {
13060				Scene.forEach(function (scene, index) {
13061					Controller.removeScene(scene);
13062				});
13063			} else {
13064				var index = _sceneObjects.indexOf(Scene);
13065				if (index > -1) {
13066					Scene.off("shift.controller_sort");
13067					_sceneObjects.splice(index, 1);
13068					log(3, "removing Scene (now " + _sceneObjects.length + " left)");
13069					Scene.remove();
13070				}
13071			}
13072			return Controller;
13073		};
13074
13075		/**
13076   * Update one ore more scene(s) according to the scroll position of the container.  
13077   * This is the equivalent to `Scene.update()`.  
13078   * The update method calculates the scene's start and end position (based on the trigger element, trigger hook, duration and offset) and checks it against the current scroll position of the container.  
13079   * It then updates the current scene state accordingly (or does nothing, if the state is already correct) – Pins will be set to their correct position and tweens will be updated to their correct progress.  
13080   * _**Note:** This method gets called constantly whenever Controller detects a change. The only application for you is if you change something outside of the realm of ScrollMagic, like moving the trigger or changing tween parameters._
13081   * @public
13082   * @example
13083   * // update a specific scene on next cycle
13084   * controller.updateScene(scene);
13085   *
13086   * // update a specific scene immediately
13087   * controller.updateScene(scene, true);
13088   *
13089   * // update multiple scenes scene on next cycle
13090   * controller.updateScene([scene1, scene2, scene3]);
13091   *
13092   * @param {ScrollMagic.Scene} Scene - ScrollMagic Scene or Array of Scenes that is/are supposed to be updated.
13093   * @param {boolean} [immediately=false] - If `true` the update will be instant, if `false` it will wait until next update cycle.  
13094   This is useful when changing multiple properties of the scene - this way it will only be updated once all new properties are set (updateScenes).
13095   * @return {Controller} Parent object for chaining.
13096   */
13097		this.updateScene = function (Scene, immediately) {
13098			if (_util.type.Array(Scene)) {
13099				Scene.forEach(function (scene, index) {
13100					Controller.updateScene(scene, immediately);
13101				});
13102			} else {
13103				if (immediately) {
13104					Scene.update(true);
13105				} else if (_updateScenesOnNextCycle !== true && Scene instanceof ScrollMagic.Scene) {
13106					// if _updateScenesOnNextCycle is true, all connected scenes are already scheduled for update
13107					// prep array for next update cycle
13108					_updateScenesOnNextCycle = _updateScenesOnNextCycle || [];
13109					if (_updateScenesOnNextCycle.indexOf(Scene) == -1) {
13110						_updateScenesOnNextCycle.push(Scene);
13111					}
13112					_updateScenesOnNextCycle = sortScenes(_updateScenesOnNextCycle); // sort
13113					debounceUpdate();
13114				}
13115			}
13116			return Controller;
13117		};
13118
13119		/**
13120   * Updates the controller params and calls updateScene on every scene, that is attached to the controller.  
13121   * See `Controller.updateScene()` for more information about what this means.  
13122   * In most cases you will not need this function, as it is called constantly, whenever ScrollMagic detects a state change event, like resize or scroll.  
13123   * The only application for this method is when ScrollMagic fails to detect these events.  
13124   * One application is with some external scroll libraries (like iScroll) that move an internal container to a negative offset instead of actually scrolling. In this case the update on the controller needs to be called whenever the child container's position changes.
13125   * For this case there will also be the need to provide a custom function to calculate the correct scroll position. See `Controller.scrollPos()` for details.
13126   * @public
13127   * @example
13128   * // update the controller on next cycle (saves performance due to elimination of redundant updates)
13129   * controller.update();
13130   *
13131   * // update the controller immediately
13132   * controller.update(true);
13133   *
13134   * @param {boolean} [immediately=false] - If `true` the update will be instant, if `false` it will wait until next update cycle (better performance)
13135   * @return {Controller} Parent object for chaining.
13136   */
13137		this.update = function (immediately) {
13138			onChange({
13139				type: "resize"
13140			}); // will update size and set _updateScenesOnNextCycle to true
13141			if (immediately) {
13142				updateScenes();
13143			}
13144			return Controller;
13145		};
13146
13147		/**
13148   * Scroll to a numeric scroll offset, a DOM element, the start of a scene or provide an alternate method for scrolling.  
13149   * For vertical controllers it will change the top scroll offset and for horizontal applications it will change the left offset.
13150   * @public
13151   *
13152   * @since 1.1.0
13153   * @example
13154   * // scroll to an offset of 100
13155   * controller.scrollTo(100);
13156   *
13157   * // scroll to a DOM element
13158   * controller.scrollTo("#anchor");
13159   *
13160   * // scroll to the beginning of a scene
13161   * var scene = new ScrollMagic.Scene({offset: 200});
13162   * controller.scrollTo(scene);
13163   *
13164   * // define a new scroll position modification function (jQuery animate instead of jump)
13165   * controller.scrollTo(function (newScrollPos) {
13166   *	$("html, body").animate({scrollTop: newScrollPos});
13167   * });
13168   * controller.scrollTo(100); // call as usual, but the new function will be used instead
13169   *
13170   * // define a new scroll function with an additional parameter
13171   * controller.scrollTo(function (newScrollPos, message) {
13172   *  console.log(message);
13173   *	$(this).animate({scrollTop: newScrollPos});
13174   * });
13175   * // call as usual, but supply an extra parameter to the defined custom function
13176   * controller.scrollTo(100, "my message");
13177   *
13178   * // define a new scroll function with an additional parameter containing multiple variables
13179   * controller.scrollTo(function (newScrollPos, options) {
13180   *  someGlobalVar = options.a + options.b;
13181   *	$(this).animate({scrollTop: newScrollPos});
13182   * });
13183   * // call as usual, but supply an extra parameter containing multiple options
13184   * controller.scrollTo(100, {a: 1, b: 2});
13185   *
13186   * // define a new scroll function with a callback supplied as an additional parameter
13187   * controller.scrollTo(function (newScrollPos, callback) {
13188   *	$(this).animate({scrollTop: newScrollPos}, 400, "swing", callback);
13189   * });
13190   * // call as usual, but supply an extra parameter, which is used as a callback in the previously defined custom scroll function
13191   * controller.scrollTo(100, function() {
13192   *	console.log("scroll has finished.");
13193   * });
13194   *
13195   * @param {mixed} scrollTarget - The supplied argument can be one of these types:
13196   * 1. `number` -> The container will scroll to this new scroll offset.
13197   * 2. `string` or `object` -> Can be a selector or a DOM object.  
13198   *  The container will scroll to the position of this element.
13199   * 3. `ScrollMagic Scene` -> The container will scroll to the start of this scene.
13200   * 4. `function` -> This function will be used for future scroll position modifications.  
13201   *  This provides a way for you to change the behaviour of scrolling and adding new behaviour like animation. The function receives the new scroll position as a parameter and a reference to the container element using `this`.  
13202   *  It may also optionally receive an optional additional parameter (see below)  
13203   *  _**NOTE:**  
13204   *  All other options will still work as expected, using the new function to scroll._
13205   * @param {mixed} [additionalParameter] - If a custom scroll function was defined (see above 4.), you may want to supply additional parameters to it, when calling it. You can do this using this parameter – see examples for details. Please note, that this parameter will have no effect, if you use the default scrolling function.
13206   * @returns {Controller} Parent object for chaining.
13207   */
13208		this.scrollTo = function (scrollTarget, additionalParameter) {
13209			if (_util.type.Number(scrollTarget)) {
13210				// excecute
13211				setScrollPos.call(_options.container, scrollTarget, additionalParameter);
13212			} else if (scrollTarget instanceof ScrollMagic.Scene) {
13213				// scroll to scene
13214				if (scrollTarget.controller() === Controller) {
13215					// check if the controller is associated with this scene
13216					Controller.scrollTo(scrollTarget.scrollOffset(), additionalParameter);
13217				} else {
13218					log(2, "scrollTo(): The supplied scene does not belong to this controller. Scroll cancelled.", scrollTarget);
13219				}
13220			} else if (_util.type.Function(scrollTarget)) {
13221				// assign new scroll function
13222				setScrollPos = scrollTarget;
13223			} else {
13224				// scroll to element
13225				var elem = _util.get.elements(scrollTarget)[0];
13226				if (elem) {
13227					// if parent is pin spacer, use spacer position instead so correct start position is returned for pinned elements.
13228					while (elem.parentNode.hasAttribute(PIN_SPACER_ATTRIBUTE)) {
13229						elem = elem.parentNode;
13230					}
13231
13232					var param = _options.vertical ? "top" : "left",
13233
13234					// which param is of interest ?
13235					containerOffset = _util.get.offset(_options.container),
13236
13237					// container position is needed because element offset is returned in relation to document, not in relation to container.
13238					elementOffset = _util.get.offset(elem);
13239
13240					if (!_isDocument) {
13241						// container is not the document root, so substract scroll Position to get correct trigger element position relative to scrollcontent
13242						containerOffset[param] -= Controller.scrollPos();
13243					}
13244
13245					Controller.scrollTo(elementOffset[param] - containerOffset[param], additionalParameter);
13246				} else {
13247					log(2, "scrollTo(): The supplied argument is invalid. Scroll cancelled.", scrollTarget);
13248				}
13249			}
13250			return Controller;
13251		};
13252
13253		/**
13254   * **Get** the current scrollPosition or **Set** a new method to calculate it.  
13255   * -> **GET**:
13256   * When used as a getter this function will return the current scroll position.  
13257   * To get a cached value use Controller.info("scrollPos"), which will be updated in the update cycle.  
13258   * For vertical controllers it will return the top scroll offset and for horizontal applications it will return the left offset.
13259   *
13260   * -> **SET**:
13261   * When used as a setter this method prodes a way to permanently overwrite the controller's scroll position calculation.  
13262   * A typical usecase is when the scroll position is not reflected by the containers scrollTop or scrollLeft values, but for example by the inner offset of a child container.  
13263   * Moving a child container inside a parent is a commonly used method for several scrolling frameworks, including iScroll.  
13264   * By providing an alternate calculation function you can make sure ScrollMagic receives the correct scroll position.  
13265   * Please also bear in mind that your function should return y values for vertical scrolls an x for horizontals.
13266   *
13267   * To change the current scroll position please use `Controller.scrollTo()`.
13268   * @public
13269   *
13270   * @example
13271   * // get the current scroll Position
13272   * var scrollPos = controller.scrollPos();
13273   *
13274   * // set a new scroll position calculation method
13275   * controller.scrollPos(function () {
13276   *	return this.info("vertical") ? -mychildcontainer.y : -mychildcontainer.x
13277   * });
13278   *
13279   * @param {function} [scrollPosMethod] - The function to be used for the scroll position calculation of the container.
13280   * @returns {(number|Controller)} Current scroll position or parent object for chaining.
13281   */
13282		this.scrollPos = function (scrollPosMethod) {
13283			if (!arguments.length) {
13284				// get
13285				return getScrollPos.call(Controller);
13286			} else {
13287				// set
13288				if (_util.type.Function(scrollPosMethod)) {
13289					getScrollPos = scrollPosMethod;
13290				} else {
13291					log(2, "Provided value for method 'scrollPos' is not a function. To change the current scroll position use 'scrollTo()'.");
13292				}
13293			}
13294			return Controller;
13295		};
13296
13297		/**
13298   * **Get** all infos or one in particular about the controller.
13299   * @public
13300   * @example
13301   * // returns the current scroll position (number)
13302   * var scrollPos = controller.info("scrollPos");
13303   *
13304   * // returns all infos as an object
13305   * var infos = controller.info();
13306   *
13307   * @param {string} [about] - If passed only this info will be returned instead of an object c
13307ontaining all.  
13308   Valid options are:
13309   ** `"size"` => the current viewport size of the container
13310   ** `"vertical"` => true if vertical scrolling, otherwise false
13311   ** `"scrollPos"` => the current scroll position
13312   ** `"scrollDirection"` => the last known direction of the scroll
13313   ** `"container"` => the container element
13314   ** `"isDocument"` => true if container element is the document.
13315   * @returns {(mixed|object)} The requested info(s).
13316   */
13317		this.info = function (about) {
13318			var values = {
13319				size: _viewPortSize,
13320				// contains height or width (in regard to orientation);
13321				vertical: _options.vertical,
13322				scrollPos: _scrollPos,
13323				scrollDirection: _scrollDirection,
13324				container: _options.container,
13325				isDocument: _isDocument
13326			};
13327			if (!arguments.length) {
13328				// get all as an object
13329				return values;
13330			} else if (values[about] !== undefined) {
13331				return values[about];
13332			} else {
13333				log(1, "ERROR: option \"" + about + "\" is not available");
13334				return;
13335			}
13336		};
13337
13338		/**
13339   * **Get** or **Set** the current loglevel option value.
13340   * @public
13341   *
13342   * @example
13343   * // get the current value
13344   * var loglevel = controller.loglevel();
13345   *
13346   * // set a new value
13347   * controller.loglevel(3);
13348   *
13349   * @param {number} [newLoglevel] - The new loglevel setting of the Controller. `[0-3]`
13350   * @returns {(number|Controller)} Current loglevel or parent object for chaining.
13351   */
13352		this.loglevel = function (newLoglevel) {
13353			if (!arguments.length) {
13354				// get
13355				return _options.loglevel;
13356			} else if (_options.loglevel != newLoglevel) {
13357				// set
13358				_options.loglevel = newLoglevel;
13359			}
13360			return Controller;
13361		};
13362
13363		/**
13364   * **Get** or **Set** the current enabled state of the controller.  
13365   * This can be used to disable all Scenes connected to the controller without destroying or removing them.
13366   * @public
13367   *
13368   * @example
13369   * // get the current value
13370   * var enabled = controller.enabled();
13371   *
13372   * // disable the controller
13373   * controller.enabled(false);
13374   *
13375   * @param {boolean} [newState] - The new enabled state of the controller `true` or `false`.
13376   * @returns {(boolean|Controller)} Current enabled state or parent object for chaining.
13377   */
13378		this.enabled = function (newState) {
13379			if (!arguments.length) {
13380				// get
13381				return _enabled;
13382			} else if (_enabled != newState) {
13383				// set
13384				_enabled = !!newState;
13385				Controller.updateScene(_sceneObjects, true);
13386			}
13387			return Controller;
13388		};
13389
13390		/**
13391   * Destroy the Controller, all Scenes and everything.
13392   * @public
13393   *
13394   * @example
13395   * // without resetting the scenes
13396   * controller = controller.destroy();
13397   *
13398   * // with scene reset
13399   * controller = controller.destroy(true);
13400   *
13401   * @param {boolean} [resetScenes=false] - If `true` the pins and tweens (if existent) of all scenes will be reset.
13402   * @returns {null} Null to unset handler variables.
13403   */
13404		this.destroy = function (resetScenes) {
13405			window.clearTimeout(_refreshTimeout);
13406			var i = _sceneObjects.length;
13407			while (i--) {
13408				_sceneObjects[i].destroy(resetScenes);
13409			}
13410			_options.container.removeEventListener("resize", onChange);
13411			_options.container.removeEventListener("scroll", onChange);
13412			_util.cAF(_updateTimeout);
13413			log(3, "destroyed " + NAMESPACE + " (reset: " + (resetScenes ? "true" : "false") + ")");
13414			return null;
13415		};
13416
13417		// INIT
13418		construct();
13419		return Controller;
13420	};
13421
13422	// store pagewide controller options
13423	var CONTROLLER_OPTIONS = {
13424		defaults: {
13425			container: window,
13426			vertical: true,
13427			globalSceneOptions: {},
13428			loglevel: 2,
13429			refreshInterval: 100
13430		}
13431	};
13432	/*
13433  * method used to add an option to ScrollMagic Scenes.
13434  */
13435	ScrollMagic.Controller.addOption = function (name, defaultValue) {
13436		CONTROLLER_OPTIONS.defaults[name] = defaultValue;
13437	};
13438	// instance extension function for plugins
13439	ScrollMagic.Controller.extend = function (extension) {
13440		var oldClass = this;
13441		ScrollMagic.Controller = function () {
13442			oldClass.apply(this, arguments);
13443			this.$super = _util.extend({}, this); // copy parent state
13444			return extension.apply(this, arguments) || this;
13445		};
13446		_util.extend(ScrollMagic.Controller, oldClass); // copy properties
13447		ScrollMagic.Controller.prototype = oldClass.prototype; // copy prototype
13448		ScrollMagic.Controller.prototype.constructor = ScrollMagic.Controller; // restore constructor
13449	};
13450
13451	/**
13452  * A Scene defines where the controller should react and how.
13453  *
13454  * @class
13455  *
13456  * @example
13457  * // create a standard scene and add it to a controller
13458  * new ScrollMagic.Scene()
13459  *		.addTo(controller);
13460  *
13461  * // create a scene with custom options and assign a handler to it.
13462  * var scene = new ScrollMagic.Scene({
13463  * 		duration: 100,
13464  *		offset: 200,
13465  *		triggerHook: "onEnter",
13466  *		reverse: false
13467  * });
13468  *
13469  * @param {object} [options] - Options for the Scene. The options can be updated at any time.  
13470  Instead of setting the options for each scene individually you can also set them globally in the controller as the controllers `globalSceneOptions` option. The object accepts the same properties as the ones below.  
13471  When a scene is added to the controller the options defined using the Scene constructor will be overwritten by those set in `globalSceneOptions`.
13472  * @param {(number|function)} [options.duration=0] - The duration of the scene. 
13473  If `0` tweens will auto-play when reaching the scene start point, pins will be pinned indefinetly starting at the start position.  
13474  A function retuning the duration value is also supported. Please see `Scene.duration()` for details.
13475  * @param {number} [options.offset=0] - Offset Value for the Trigger Position. If no triggerElement is defined this will be the scroll distance from the start of the page, after which the scene will start.
13476  * @param {(string|object)} [options.triggerElement=null] - Selector or DOM object that defines the start of the scene. If undefined the scene will start right at the start of the page (unless an offset is set).
13477  * @param {(number|string)} [options.triggerHook="onCenter"] - Can be a number between 0 and 1 defining the position of the trigger Hook in relation to the viewport.  
13478  Can also be defined using a string:
13479  ** `"onEnter"` => `1`
13480  ** `"onCenter"` => `0.5`
13481  ** `"onLeave"` => `0`
13482  * @param {boolean} [options.reverse=true] - Should the scene reverse, when scrolling up?
13483  * @param {number} [options.loglevel=2] - Loglevel for debugging. Note that logging is disabled in the minified version of ScrollMagic.
13484  ** `0` => silent
13485  ** `1` => errors
13486  ** `2` => errors, warnings
13487  ** `3` => errors, warnings, debuginfo
13488  * 
13489  */
13490	ScrollMagic.Scene = function (options) {
13491
13492		/*
13493  	 * ----------------------------------------------------------------
13494  	 * settings
13495  	 * ----------------------------------------------------------------
13496  	 */
13497
13498		var NAMESPACE = 'ScrollMagic.Scene',
13499		    SCENE_STATE_BEFORE = 'BEFORE',
13500		    SCENE_STATE_DURING = 'DURING',
13501		    SCENE_STATE_AFTER = 'AFTER',
13502		    DEFAULT_OPTIONS = SCENE_OPTIONS.defaults;
13503
13504		/*
13505  	 * ----------------------------------------------------------------
13506  	 * private vars
13507  	 * ----------------------------------------------------------------
13508  	 */
13509
13510		var Scene = this,
13511		    _options = _util.extend({}, DEFAULT_OPTIONS, options),
13512		    _state = SCENE_STATE_BEFORE,
13513		    _progress = 0,
13514		    _scrollOffset = {
13515			start: 0,
13516			end: 0
13517		},
13518
13519		// reflects the controllers's scroll position for the start and end of the scene respectively
13520		_triggerPos = 0,
13521		    _enabled = true,
13522		    _durationUpdateMethod,
13523		    _controller;
13524
13525		/**
13526   * Internal constructor function of the ScrollMagic Scene
13527   * @private
13528   */
13529		var construct = function () {
13530			for (var key in _options) {
13531				// check supplied options
13532				if (!DEFAULT_OPTIONS.hasOwnProperty(key)) {
13533					log(2, "WARNING: Unknown option \"" + key + "\"");
13534					delete _options[key];
13535				}
13536			}
13537			// add getters/setters for all possible options
13538			for (var optionName in DEFAULT_OPTIONS) {
13539				addSceneOption(optionName);
13540			}
13541			// validate all options
13542			validateOption();
13543		};
13544
13545		/*
13546   * ----------------------------------------------------------------
13547   * Event Management
13548   * ----------------------------------------------------------------
13549   */
13550
13551		var _listeners = {};
13552		/**
13553   * Scene start event.  
13554   * Fires whenever the scroll position its the starting point of the scene.  
13555   * It will also fire when scrolling back up going over the start position of the scene. If you want something to happen only when scrolling down/right, use the scrollDirection parameter passed to the callback.
13556   *
13557   * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method.
13558   *
13559   * @event ScrollMagic.Scene#start
13560   *
13561   * @example
13562   * scene.on("start", function (event) {
13563   * 	console.log("Hit start point of scene.");
13564   * });
13565   *
13566   * @property {object} event - The event Object passed to each callback
13567   * @property {string} event.type - The name of the event
13568   * @property {Scene} event.target - The Scene object that triggered this event
13569   * @property {number} event.progress - Reflects the current progress of the scene
13570   * @property {string} event.state - The current state of the scene `"BEFORE"` or `"DURING"`
13571   * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"`
13572   */
13573		/**
13574   * Scene end event.  
13575   * Fires whenever the scroll position its the ending point of the scene.  
13576   * It will also fire when scrolling back up from after the scene and going over its end position. If you want something to happen only when scrolling down/right, use the scrollDirection parameter passed to the callback.
13577   *
13578   * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method.
13579   *
13580   * @event ScrollMagic.Scene#end
13581   *
13582   * @example
13583   * scene.on("end", function (event) {
13584   * 	console.log("Hit end point of scene.");
13585   * });
13586   *
13587   * @property {object} event - The event Object passed to each callback
13588   * @property {string} event.type - The name of the event
13589   * @property {Scene} event.target - The Scene object that triggered this event
13590   * @property {number} event.progress - Reflects the current progress of the scene
13591   * @property {string} event.state - The current state of the scene `"DURING"` or `"AFTER"`
13592   * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"`
13593   */
13594		/**
13595   * Scene enter event.  
13596   * Fires whenever the scene enters the "DURING" state.  
13597   * Keep in mind that it doesn't matter if the scene plays forward or backward: This event always fires when the scene enters its active scroll timeframe, regardless of the scroll-direction.
13598   *
13599   * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method.
13600   *
13601   * @event ScrollMagic.Scene#enter
13602   *
13603   * @example
13604   * scene.on("enter", function (event) {
13605   * 	console.log("Scene entered.");
13606   * });
13607   *
13608   * @property {object} event - The event Object passed to each callback
13609   * @property {string} event.type - The name of the event
13610   * @property {Scene} event.target - The Scene object that triggered this event
13611   * @property {number} event.progress - Reflects the current progress of the scene
13612   * @property {string} event.state - The current state of the scene - always `"DURING"`
13613   * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"`
13614   */
13615		/**
13616   * Scene leave event.  
13617   * Fires whenever the scene's state goes from "DURING" to either "BEFORE" or "AFTER".  
13618   * Keep in mind that it doesn't matter if the scene plays forward or backward: This event al
13618ways fires when the scene leaves its active scroll timeframe, regardless of the scroll-direction.
13619   *
13620   * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method.
13621   *
13622   * @event ScrollMagic.Scene#leave
13623   *
13624   * @example
13625   * scene.on("leave", function (event) {
13626   * 	console.log("Scene left.");
13627   * });
13628   *
13629   * @property {object} event - The event Object passed to each callback
13630   * @property {string} event.type - The name of the event
13631   * @property {Scene} event.target - The Scene object that triggered this event
13632   * @property {number} event.progress - Reflects the current progress of the scene
13633   * @property {string} event.state - The current state of the scene `"BEFORE"` or `"AFTER"`
13634   * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"`
13635   */
13636		/**
13637   * Scene update event.  
13638   * Fires whenever the scene is updated (but not necessarily changes the progress).
13639   *
13640   * @event ScrollMagic.Scene#update
13641   *
13642   * @example
13643   * scene.on("update", function (event) {
13644   * 	console.log("Scene updated.");
13645   * });
13646   *
13647   * @property {object} event - The event Object passed to each callback
13648   * @property {string} event.type - The name of the event
13649   * @property {Scene} event.target - The Scene object that triggered this event
13650   * @property {number} event.startPos - The starting position of the scene (in relation to the conainer)
13651   * @property {number} event.endPos - The ending position of the scene (in relation to the conainer)
13652   * @property {number} event.scrollPos - The current scroll position of the container
13653   */
13654		/**
13655   * Scene progress event.  
13656   * Fires whenever the progress of the scene changes.
13657   *
13658   * For details on this event and the order in which it is fired, please review the {@link Scene.progress} method.
13659   *
13660   * @event ScrollMagic.Scene#progress
13661   *
13662   * @example
13663   * scene.on("progress", function (event) {
13664   * 	console.log("Scene progress changed to " + event.progress);
13665   * });
13666   *
13667   * @property {object} event - The event Object passed to each callback
13668   * @property {string} event.type - The name of the event
13669   * @property {Scene} event.target - The Scene object that triggered this event
13670   * @property {number} event.progress - Reflects the current progress of the scene
13671   * @property {string} event.state - The current state of the scene `"BEFORE"`, `"DURING"` or `"AFTER"`
13672   * @property {string} event.scrollDirection - Indicates which way we are scrolling `"PAUSED"`, `"FORWARD"` or `"REVERSE"`
13673   */
13674		/**
13675   * Scene change event.  
13676   * Fires whenvever a property of the scene is changed.
13677   *
13678   * @event ScrollMagic.Scene#change
13679   *
13680   * @example
13681   * scene.on("change", function (event) {
13682   * 	console.log("Scene Property \"" + event.what + "\" changed to " + event.newval);
13683   * });
13684   *
13685   * @property {object} event - The event Object passed to each callback
13686   * @property {string} event.type - The name of the event
13687   * @property {Scene} event.target - The Scene object that triggered this event
13688   * @property {string} event.what - Indicates what value has been changed
13689   * @property {mixed} event.newval - The new value of the changed property
13690   */
13691		/**
13692   * Scene shift event.  
13693   * Fires whenvever the start or end **scroll offset** of the scene change.
13694   * This happens explicitely, when one of these values change: `offset`, `duration` or `triggerHook`.
13695   * It will fire implicitly when the `triggerElement` changes, if the new element has a different position (most cases).
13696   * It will also fire implicitly when the size of the container changes and the triggerHook is anything other than `onLeave`.
13697   *
13698   * @event ScrollMagic.Scene#shift
13699   * @since 1.1.0
13700   *
13701   * @example
13702   * scene.on("shift", function (event) {
13703   * 	console.log("Scene moved, because the " + event.reason + " has changed.)");
13704   * });
13705   *
13706   * @property {object} event - The event Object passed to each callback
13707   * @property {string} event.type - The name of the event
13708   * @property {Scene} event.target - The Scene object that triggered this event
13709   * @property {string} event.reason - Indicates why the scene has shifted
13710   */
13711		/**
13712   * Scene destroy event.  
13713   * Fires whenvever the scene is destroyed.
13714   * This can be used to tidy up custom behaviour used in events.
13715   *
13716   * @event ScrollMagic.Scene#destroy
13717   * @since 1.1.0
13718   *
13719   * @example
13720   * scene.on("enter", function (event) {
13721   *        // add custom action
13722   *        $("#my-elem").left("200");
13723   *      })
13724   *      .on("destroy", function (event) {
13725   *        // reset my element to start position
13726   *        if (event.reset) {
13727   *          $("#my-elem").left("0");
13728   *        }
13729   *      });
13730   *
13731   * @property {object} event - The event Object passed to each callback
13732   * @property {string} event.type - The name of the event
13733   * @property {Scene} event.target - The Scene object that triggered this event
13734   * @property {boolean} event.reset - Indicates if the destroy method was called with reset `true` or `false`.
13735   */
13736		/**
13737   * Scene add event.  
13738   * Fires when the scene is added to a controller.
13739   * This is mostly used by plugins to know that change might be due.
13740   *
13741   * @event ScrollMagic.Scene#add
13742   * @since 2.0.0
13743   *
13744   * @example
13745   * scene.on("add", function (event) {
13746   * 	console.log('Scene was added to a new controller.');
13747   * });
13748   *
13749   * @property {object} event - The event Object passed to each callback
13750   * @property {string} event.type - The name of the event
13751   * @property {Scene} event.target - The Scene object that triggered this event
13752   * @property {boolean} event.controller - The controller object the scene was added to.
13753   */
13754		/**
13755   * Scene remove event.  
13756   * Fires when the scene is removed from a controller.
13757   * This is mostly used by plugins to know that change might be due.
13758   *
13759   * @event ScrollMagic.Scene#remove
13760   * @since 2.0.0
13761   *
13762   * @example
13763   * scene.on("remove", function (event) {
13764   * 	console.log('Scene was removed from its controller.');
13765   * });
13766   *
13767   * @property {object} event - The event Object passed to each callback
13768   * @property {string} event.type - The name of the event
13769   * @property {Scene} event.target - The Scene object that triggered this event
13770   */
13771
13772		/**
13773   * Add one ore more event listener.  
13774   * The callback function will be fired at the respective event, and an object c
13774ontaining relevant data will be passed to the callback.
13775   * @method ScrollMagic.Scene#on
13776   *
13777   * @example
13778   * function callback (event) {
13779   * 		console.log("Event fired! (" + event.type + ")");
13780   * }
13781   * // add listeners
13782   * scene.on("change update progress start end enter leave", callback);
13783   *
13784   * @param {string} names - The name or names of the event the callback should be attached to.
13785   * @param {function} callback - A function that should be executed, when the event is dispatched. An event object will be passed to the callback.
13786   * @returns {Scene} Parent object for chaining.
13787   */
13788		this.on = function (names, callback) {
13789			if (_util.type.Function(callback)) {
13790				names = names.trim().split(' ');
13791				names.forEach(function (fullname) {
13792					var nameparts = fullname.split('.'),
13793					    eventname = nameparts[0],
13794					    namespace = nameparts[1];
13795					if (eventname != "*") {
13796						// disallow wildcards
13797						if (!_listeners[eventname]) {
13798							_listeners[eventname] = [];
13799						}
13800						_listeners[eventname].push({
13801							namespace: namespace || '',
13802							callback: callback
13803						});
13804					}
13805				});
13806			} else {
13807				log(1, "ERROR when calling '.on()': Supplied callback for '" + names + "' is not a valid function!");
13808			}
13809			return Scene;
13810		};
13811
13812		/**
13813   * Remove one or more event listener.
13814   * @method ScrollMagic.Scene#off
13815   *
13816   * @example
13817   * function callback (event) {
13818   * 		console.log("Event fired! (" + event.type + ")");
13819   * }
13820   * // add listeners
13821   * scene.on("change update", callback);
13822   * // remove listeners
13823   * scene.off("change update", callback);
13824   *
13825   * @param {string} names - The name or names of the event that should be removed.
13826   * @param {function} [callback] - A specific callback function that should be removed. If none is passed all callbacks to the event listener will be removed.
13827   * @returns {Scene} Parent object for chaining.
13828   */
13829		this.off = function (names, callback) {
13830			if (!names) {
13831				log(1, "ERROR: Invalid event name supplied.");
13832				return Scene;
13833			}
13834			names = names.trim().split(' ');
13835			names.forEach(function (fullname, key) {
13836				var nameparts = fullname.split('.'),
13837				    eventname = nameparts[0],
13838				    namespace = nameparts[1] || '',
13839				    removeList = eventname === '*' ? Object.keys(_listeners) : [eventname];
13840				removeList.forEach(function (remove) {
13841					var list = _listeners[remove] || [],
13842					    i = list.length;
13843					while (i--) {
13844						var listener = list[i];
13845						if (listener && (namespace === listener.namespace || namespace === '*') && (!callback || callback == listener.callback)) {
13846							list.splice(i, 1);
13847						}
13848					}
13849					if (!list.length) {
13850						delete _listeners[remove];
13851					}
13852				});
13853			});
13854			return Scene;
13855		};
13856
13857		/**
13858   * Trigger an event.
13859   * @method ScrollMagic.Scene#trigger
13860   *
13861   * @example
13862   * this.trigger("change");
13863   *
13864   * @param {string} name - The name of the event that should be triggered.
13865   * @param {object} [vars] - An object containing info that should be passed to the callback.
13866   * @returns {Scene} Parent object for chaining.
13867   */
13868		this.trigger = function (name, vars) {
13869			if (name) {
13870				var nameparts = name.trim().split('.'),
13871				    eventname = nameparts[0],
13872				    namespace = nameparts[1],
13873				    listeners = _listeners[eventname];
13874				log(3, 'event fired:', eventname, vars ? "->" : '', vars || '');
13875				if (listeners) {
13876					listeners.forEach(function (listener, key) {
13877						if (!namespace || namespace === listener.namespace) {
13878							listener.callback.call(Scene, new ScrollMagic.Event(eventname, listener.namespace, Scene, vars));
13879						}
13880					});
13881				}
13882			} else {
13883				log(1, "ERROR: Invalid event name supplied.");
13884			}
13885			return Scene;
13886		};
13887
13888		// set event listeners
13889		Scene.on("change.internal", function (e) {
13890			if (e.what !== "loglevel" && e.what !== "tweenChanges") {
13891				// no need for a scene update scene with these options...
13892				if (e.what === "triggerElement") {
13893					updateTriggerElementPosition();
13894				} else if (e.what === "reverse") {
13895					// the only property left that may have an impact on the current scene state. Everything else is handled by the shift event.
13896					Scene.update();
13897				}
13898			}
13899		}).on("shift.internal", function (e) {
13900			updateScrollOffset();
13901			Scene.update(); // update scene to reflect new position
13902		});
13903
13904		/**
13905   * Send a debug message to the console.
13906   * @private
13907   * but provided publicly with _log for plugins
13908   *
13909   * @param {number} loglevel - The loglevel required to initiate output for the message.
13910   * @param {...mixed} output - One or more variables that should be passed to the console.
13911   */
13912		var log = this._log = function (loglevel, output) {
13913			if (_options.loglevel >= loglevel) {
13914				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ") ->");
13915				_util.log.apply(window, arguments);
13916			}
13917		};
13918
13919		/**
13920   * Add the scene to a controller.  
13921   * This is the equivalent to `Controller.addScene(scene)`.
13922   * @method ScrollMagic.Scene#addTo
13923   *
13924   * @example
13925   * // add a scene to a ScrollMagic Controller
13926   * scene.addTo(controller);
13927   *
13928   * @param {ScrollMagic.Controller} controller - The controller to which the scene should be added.
13929   * @returns {Scene} Parent object for chaining.
13930   */
13931		this.addTo = function (controller) {
13932			if (!(controller instanceof ScrollMagic.Controller)) {
13933				log(1, "ERROR: supplied argument of 'addTo()' is not a valid ScrollMagic Controller");
13934			} else if (_controller != controller) {
13935				// new controller
13936				if (_controller) {
13937					// was associated to a different controller before, so remove it...
13938					_controller.removeScene(Scene);
13939				}
13940				_controller = controller;
13941				validateOption();
13942				updateDuration(true);
13943				updateTriggerElementPosition(true);
13944				updateScrollOffset();
13945				_controller.info("container").addEventListener('resize', onContainerResize);
13946				controller.addScene(Scene);
13947				Scene.trigger("add", {
13948					controller: _controller
13949				});
13950				log(3, "added " + NAMESPACE + " to controller");
13951				Scene.update();
13952			}
13953			return Scene;
13954		};
13955
13956		/**
13957   * **Get** or **Set** the current enabled state of the scene.  
13958   * This can be used to disable this scene without removing or destroying it.
13959   * @method ScrollMagic.Scene#enabled
13960   *
13961   * @example
13962   * // get the current value
13963   * var enabled = scene.enabled();
13964   *
13965   * // disable the scene
13966   * scene.enabled(false);
13967   *
13968   * @param {boolean} [newState] - The new enabled state of the scene `true` or `false`.
13969   * @returns {(boolean|Scene)} Current enabled state or parent object for chaining.
13970   */
13971		this.enabled = function (newState) {
13972			if (!arguments.length) {
13973				// get
13974				return _enabled;
13975			} else if (_enabled != newState) {
13976				// set
13977				_enabled = !!newState;
13978				Scene.update(true);
13979			}
13980			return Scene;
13981		};
13982
13983		/**
13984   * Remove the scene from the controller.  
13985   * This is the equivalent to `Controller.removeScene(scene)`.
13986   * The scene will not be updated anymore until you readd it to a controller.
13987   * To remove the pin or the tween you need to call removeTween() or removePin() respectively.
13988   * @method ScrollMagic.Scene#remove
13989   * @example
13990   * // remove the scene from its controller
13991   * scene.remove();
13992   *
13993   * @returns {Scene} Parent object for chaining.
13994   */
13995		this.remove = function () {
13996			if (_controller) {
13997				_controller.info("container").removeEventListener('resize', onContainerResize);
13998				var tmpParent = _controller;
13999				_controller = undefined;
14000				tmpParent.removeScene(Scene);
14001				Scene.trigger("remove");
14002				log(3, "removed " + NAMESPACE + " from controller");
14003			}
14004			return Scene;
14005		};
14006
14007		/**
14008   * Destroy the scene and everything.
14009   * @method ScrollMagic.Scene#destroy
14010   * @example
14011   * // destroy the scene without resetting the pin and tween to their initial positions
14012   * scene = scene.destroy();
14013   *
14014   * // destroy the scene and reset the pin and tween
14015   * scene = scene.destroy(true);
14016   *
14017   * @param {boolean} [reset=false] - If `true` the pin and tween (if existent) will be reset.
14018   * @returns {null} Null to unset handler variables.
14019   */
14020		this.destroy = function (reset) {
14021			Scene.trigger("destroy", {
14022				reset: reset
14023			});
14024			Scene.remove();
14025			Scene.off("*.*");
14026			log(3, "destroyed " + NAMESPACE + " (reset: " + (reset ? "true" : "false") + ")");
14027			return null;
14028		};
14029
14030		/**
14031   * Updates the Scene to reflect the current state.  
14032   * This is the equivalent to `Controller.updateScene(scene, immediately)`.  
14033   * The update method calculates the scene's start and end position (based on the trigger element, trigger hook, duration and offset) and checks it against the current scroll position of the container.  
14034   * It then updates the current scene state accordingly (or does nothing, if the state is already correct) – Pins will be set to their correct position and tweens will be updated to their correct progress.
14035   * This means an update doesn't necessarily result in a progress change. The `progress` event will be fired if the progress has indeed changed between this update and the last.  
14036   * _**NOTE:** This method gets called constantly whenever ScrollMagic detects a change. The only application for you is 
14036if you change something outside of the realm of ScrollMagic, like moving the trigger or changing tween parameters._
14037   * @method ScrollMagic.Scene#update
14038   * @example
14039   * // update the scene on next tick
14040   * scene.update();
14041   *
14042   * // update the scene immediately
14043   * scene.update(true);
14044   *
14045   * @fires Scene.update
14046   *
14047   * @param {boolean} [immediately=false] - If `true` the update will be instant, if `false` it will wait until next update cycle (better performance).
14048   * @returns {Scene} Parent object for chaining.
14049   */
14050		this.update = function (immediately) {
14051			if (_controller) {
14052				if (immediately) {
14053					if (_controller.enabled() && _enabled) {
14054						var scrollPos = _controller.info("scrollPos"),
14055						    newProgress;
14056
14057						if (_options.duration > 0) {
14058							newProgress = (scrollPos - _scrollOffset.start) / (_scrollOffset.end - _scrollOffset.start);
14059						} else {
14060							newProgress = scrollPos >= _scrollOffset.start ? 1 : 0;
14061						}
14062
14063						Scene.trigger("update", {
14064							startPos: _scrollOffset.start,
14065							endPos: _scrollOffset.end,
14066							scrollPos: scrollPos
14067						});
14068
14069						Scene.progress(newProgress);
14070					} else if (_pin && _state === SCENE_STATE_DURING) {
14071						updatePinState(true); // unpin in position
14072					}
14073				} else {
14074					_controller.updateScene(Scene, false);
14075				}
14076			}
14077			return Scene;
14078		};
14079
14080		/**
14081   * Updates dynamic scene variables like the trigger element position or the duration.
14082   * This method is automatically called in regular intervals from the controller. See {@link ScrollMagic.Controller} option `refreshInterval`.
14083   * 
14084   * You can call it to minimize lag, for example when you intentionally change the position of the triggerElement.
14085   * If you don't it will simply be updated in the next refresh interval of the container, which is usually sufficient.
14086   *
14087   * @method ScrollMagic.Scene#refresh
14088   * @since 1.1.0
14089   * @example
14090   * scene = new ScrollMagic.Scene({triggerElement: "#trigger"});
14091   * 
14092   * // change the position of the trigger
14093   * $("#trigger").css("top", 500);
14094   * // immediately let the scene know of this change
14095   * scene.refresh();
14096   *
14097   * @fires {@link Scene.shift}, if the trigger element position or the duration changed
14098   * @fires {@link Scene.change}, if the duration changed
14099   *
14100   * @returns {Scene} Parent object for chaining.
14101   */
14102		this.refresh = function () {
14103			updateDuration();
14104			updateTriggerElementPosition();
14105			// update trigger element position
14106			return Scene;
14107		};
14108
14109		/**
14110   * **Get** or **Set** the scene's progress.  
14111   * Usually it shouldn't be necessary to use this as a setter, as it is set automatically by scene.update().  
14112   * The order in which the events are fired depends on the duration of the scene:
14113   *  1. Scenes with `duration == 0`:  
14114   *  Scenes that have no duration by definition have no ending. Thus the `end` event will never be fired.  
14115   *  When the trigger position of the scene is passed the events are always fired in this order:  
14116   *  `enter`, `start`, `progress` when scrolling forward  
14117   *  and  
14118   *  `progress`, `start`, `leave` when scrolling in reverse
14119   *  2. Scenes with `duration > 0`:  
14120   *  Scenes with a set duration have a defined start and end point.  
14121   *  When scrolling past the start position of the scene it will fire these events in this order:  
14122   *  `enter`, `start`, `progress`  
14123   *  When continuing to scroll and passing the end point it will fire these events:  
14124   *  `progress`, `end`, `leave`  
14125   *  When reversing through the end point these events are fired:  
14126   *  `enter`, `end`, `progress`  
14127   *  And when continuing to scroll past the start position in reverse it will fire:  
14128   *  `progress`, `start`, `leave`  
14129   *  In between start and end the `progress` event will be called constantly, whenever the progress changes.
14130   * 
14131   * In short:  
14132   * `enter` events will always trigger **before** the progress update and `leave` envents will trigger **after** the progress update.  
14133   * `start` and `end` will always trigger at their respective position.
14134   * 
14135   * Please review the event descriptions for details on the events and the event object that is passed to the callback.
14136   * 
14137   * @method ScrollMagic.Scene#progress
14138   * @example
14139   * // get the current scene progress
14140   * var progress = scene.progress();
14141   *
14142   * // set new scene progress
14143   * scene.progress(0.3);
14144   *
14145   * @fires {@link Scene.enter}, when used as setter
14146   * @fires {@link Scene.start}, when used as setter
14147   * @fires {@link Scene.progress}, when used as setter
14148   * @fires {@link Scene.end}, when used as setter
14149   * @fires {@link Scene.leave}, when used as setter
14150   *
14151   * @param {number} [progress] - The new progress value of the scene `[0-1]`.
14152   * @returns {number} `get` -  Current scene progress.
14153   * @returns {Scene} `set` -  Parent object for chaining.
14154   */
14155		this.progress = function (progress) {
14156			if (!arguments.length) {
14157				// get
14158				return _progress;
14159			} else {
14160				// set
14161				var doUpdate = false,
14162				    oldState = _state,
14163				    scrollDirection = _controller ? _controller.info("scrollDirection") : 'PAUSED',
14164				    reverseOrForward = _options.reverse || progress >= _progress;
14165				if (_options.duration === 0) {
14166					// zero duration scenes
14167					doUpdate = _progress != progress;
14168					_progress = progress < 1 && reverseOrForward ? 0 : 1;
14169					_state = _progress === 0 ? SCENE_STATE_BEFORE : SCENE_STATE_DURING;
14170				} else {
14171					// scenes with start and end
14172					if (progress < 0 && _state !== SCENE_STATE_BEFORE && reverseOrForward) {
14173						// go back to initial state
14174						_progress = 0;
14175						_state = SCENE_STATE_BEFORE;
14176						doUpdate = true;
14177					} else if (progress >= 0 && progress < 1 && reverseOrForward) {
14178						_progress = progress;
14179						_state = SCENE_STATE_DURING;
14180						doUpdate = true;
14181					} else if (progress >= 1 && _state !== SCENE_STATE_AFTER) {
14182						_progress = 1;
14183						_state = SCENE_STATE_AFTER;
14184						doUpdate = true;
14185					} else if (_state === SCENE_STATE_DURING && !reverseOrForward) {
14186						updatePinState(); // in case we scrolled backwards mid-scene and reverse is disabled => update the pin position, so it doesn't move back as well.
14187					}
14188				}
14189				if (doUpdate) {
14190					// fire events
14191					var eventVars = {
14192						progress: _progress,
14193						state: _state,
14194						scrollDirection: scrollDirection
14195					},
14196					    stateChanged = _state != oldState;
14197
14198					var trigger = function (eventName) {
14199						// tmp helper to simplify code
14200						Scene.trigger(eventName, eventVars);
14201					};
14202
14203					if (stateChanged) {
14204						// enter events
14205						if (oldState !== SCENE_STATE_DURING) {
14206							trigger("enter");
14207							trigger(oldState === SCENE_STATE_BEFORE ? "start" : "end");
14208						}
14209					}
14210					trigger("progress");
14211					if (stateChanged) {
14212						// leave events
14213						if (_state !== SCENE_STATE_DURING) {
14214							trigger(_state === SCENE_STATE_BEFORE ? "start" : "end");
14215							trigger("leave");
14216						}
14217					}
14218				}
14219
14220				return Scene;
14221			}
14222		};
14223
14224		/**
14225   * Update the start and end scrollOffset of the container.
14226   * The positions reflect what the controller's scroll position will be at the start and end respectively.
14227   * Is called, when:
14228   *   - Scene event "change" is called with: offset, triggerHook, duration 
14229   *   - scroll container event "resize" is called
14230   *   - the position of the triggerElement changes
14231   *   - the controller changes -> addTo()
14232   * @private
14233   */
14234		var updateScrollOffset = function () {
14235			_scrollOffset = {
14236				start: _triggerPos + _options.offset
14237			};
14238			if (_controller && _options.triggerElement) {
14239				// take away triggerHook portion to get relative to top
14240				_scrollOffset.start -= _controller.info("size") * _options.triggerHook;
14241			}
14242			_scrollOffset.end = _scrollOffset.start + _options.duration;
14243		};
14244
14245		/**
14246   * Updates the duration if set to a dynamic function.
14247   * This method is called when the scene is added to a controller and in regular intervals from the controller through scene.refresh().
14248   * 
14249   * @fires {@link Scene.change}, if the duration changed
14250   * @fires {@link Scene.shift}, if the duration changed
14251   *
14252   * @param {boolean} [suppressEvents=false] - If true the shift event will be suppressed.
14253   * @private
14254   */
14255		var updateDuration = function (suppressEvents) {
14256			// update duration
14257			if (_durationUpdateMethod) {
14258				var varname = "duration";
14259				if (changeOption(varname, _durationUpdateMethod.call(Scene)) && !suppressEvents) {
14260					// set
14261					Scene.trigger("change", {
14262						what: varname,
14263						newval: _options[varname]
14264					});
14265					Scene.trigger("shift", {
14266						reason: varname
14267					});
14268				}
14269			}
14270		};
14271
14272		/**
14273   * Updates the position of the triggerElement, if present.
14274   * This method is called ...
14275   *  - ... when the triggerElement is changed
14276   *  - ... when the scene is added to a (new) controller
14277   *  - ... in regular intervals from the controller through scene.refresh().
14278   * 
14279   * @fires {@link Scene.shift}, if the position changed
14280   *
14281   * @param {boolean} [suppressEvents=false] - If true the shift event will be suppressed.
14282   * @private
14283   */
14284		var updateTriggerElementPosition = function (suppressEvents) {
14285			var elementPos = 0,
14286			    telem = _options.triggerElement;
14287			if (_controller && telem) {
14288				var controllerInfo = _controller.info(),
14289				    containerOffset = _util.get.offset(controllerInfo.container),
14290
14291				// container position is needed because element offset is returned in relation to document, not in relation to container.
14292				param = controllerInfo.vertical ? "top" : "left"; // which param is of interest ?
14293				// if parent is spacer, use spacer position instead so correct start position is returned for pinned elements.
14294				while (telem.parentNode.hasAttribute(PIN_SPACER_ATTRIBUTE)) {
14295					telem = telem.parentNode;
14296				}
14297
14298				var elementOffset = _util.get.offset(telem);
14299
14300				if (!controllerInfo.isDocument) {
14301					// container is not the document root, so substract scroll Position to get correct trigger element position relative to scrollcontent
14302					containerOffset[param] -= _controller.scrollPos();
14303				}
14304
14305				elementPos = elementOffset[param] - containerOffset[param];
14306			}
14307			var changed = elementPos != _triggerPos;
14308			_triggerPos = elementPos;
14309			if (changed && !suppressEvents) {
14310				Scene.trigger("shift", {
14311					reason: "triggerElementPosition"
14312				});
14313			}
14314		};
14315
14316		/**
14317   * Trigger a shift event, when the container is resized and the triggerHook is > 1.
14318   * @private
14319   */
14320		var onContainerResize = function (e) {
14321			if (_options.triggerHook > 0) {
14322				Scene.trigger("shift", {
14323					reason: "containerResize"
14324				});
14325			}
14326		};
14327
14328		var _validate = _util.extend(SCENE_OPTIONS.validate, {
14329			// validation for duration handled internally for reference to private var _durationMethod
14330			duration: function (val) {
14331				if (_util.type.String(val) && val.match(/^(\.|\d)*\d+%$/)) {
14332					// percentage value
14333					var perc = parseFloat(val) / 100;
14334					val = function () {
14335						return _controller ? _controller.info("size") * perc : 0;
14336					};
14337				}
14338				if (_util.type.Function(val)) {
14339					// function
14340					_durationUpdateMethod = val;
14341					try {
14342						val = parseFloat(_durationUpdateMethod());
14343					} catch (e) {
14344						val = -1; // will cause error below
14345					}
14346				}
14347				// val has to be float
14348				val = parseFloat(val);
14349				if (!_util.type.Number(val) || val < 0) {
14350					if (_durationUpdateMethod) {
14351						_durationUpdateMethod = undefined;
14352						throw ["Invalid return value of supplied function for option \"duration\":", val];
14353					} else {
14354						throw ["Invalid value for option \"duration\":", val];
14355					}
14356				}
14357				return val;
14358			}
14359		});
14360
14361		/**
14362   * Checks the validity of a specific or all options and reset to default if neccessary.
14363   * @private
14364   */
14365		var validateOption = function (check) {
14366			check = arguments.length ? [check] : Object.keys(_validate);
14367			check.forEach(function (optionName, key) {
14368				var value;
14369				if (_validate[optionName]) {
14370					// there is a validation method for this option
14371					try {
14372						// validate value
14373						value = _validate[optionName](_options[optionName]);
14374					} catch (e) {
14375						// validation failed -> reset to default
14376						value = DEFAULT_OPTIONS[optionName];
14377						var logMSG = _util.type.String(e) ? [e] : e;
14378						if (_util.type.Array(logMSG)) {
14379							logMSG[0] = "ERROR: " + logMSG[0];
14380							logMSG.unshift(1); // loglevel 1 for error msg
14381							log.apply(this, logMSG);
14382						} else {
14383							log(1, "ERROR: Problem executing validation callback for option '" + optionName + "':", e.message);
14384						}
14385					} finally {
14386						_options[optionName] = value;
14387					}
14388				}
14389			});
14390		};
14391
14392		/**
14393   * Helper used by the setter/getters for scene options
14394   * @private
14395   */
14396		var changeOption = function (varname, newval) {
14397			var changed = false,
14398			    oldval = _options[varname];
14399			if (_options[varname] != newval) {
14400				_options[varname] = newval;
14401				validateOption(varname); // resets to default if necessary
14402				changed = oldval != _options[varname];
14403			}
14404			return changed;
14405		};
14406
14407		// generate getters/setters for all options
14408		var addSceneOption = function (optionName) {
14409			if (!Scene[optionName]) {
14410				Scene[optionName] = function (newVal) {
14411					if (!arguments.length) {
14412						// get
14413						return _options[optionName];
14414					} else {
14415						if (optionName === "duration") {
14416							// new duration is set, so any previously set function must be unset
14417							_durationUpdateMethod = undefined;
14418						}
14419						if (changeOption(optionName, newVal)) {
14420							// set
14421							Scene.trigger("change", {
14422								what: optionName,
14423								newval: _options[optionName]
14424							});
14425							if (SCENE_OPTIONS.shifts.indexOf(optionName) > -1) {
14426								Scene.trigger("shift", {
14427									reason: optionName
14428								});
14429							}
14430						}
14431					}
14432					return Scene;
14433				};
14434			}
14435		};
14436
14437		/**
14438   * **Get** or **Set** the duration option value.
14439   * As a setter it also accepts a function returning a numeric value.  
14440   * This is particularly useful for responsive setups.
14441   *
14442   * The duration is updated using the supplied function every time `Scene.refresh()` is called, which happens periodically from the controller (see ScrollMagic.Controller option `refreshInterval`).  
14443   * _**NOTE:** Be aware that it's an easy way to kill performance, if you supply a function that has high CPU demand.  
14444   * Even for size and position calculations it is recommended to use a variable to cache the value. (see example)  
14445   * This counts double if you use the same function for multiple scenes._
14446   *
14447   * @method ScrollMagic.Scene#duration
14448   * @example
14449   * // get the current duration value
14450   * var duration = scene.duration();
14451   *
14452   * // set a new duration
14453   * scene.duration(300);
14454   *
14455   * // use a function to automatically adjust the duration to the window height.
14456   * var durationValueCache;
14457   * function getDuration () {
14458   *   return durationValueCache;
14459   * }
14460   * function updateDuration (e) {
14461   *   durationValueCache = window.innerHeight;
14462   * }
14463   * $(window).on("resize", updateDuration); // update the duration when the window size changes
14464   * $(window).triggerHandler("resize"); // set to initial value
14465   * scene.duration(getDuration); // supply duration method
14466   *
14467   * @fires {@link Scene.change}, when used as setter
14468   * @fires {@link Scene.shift}, when used as setter
14469   * @param {(number|function)} [newDuration] - The new duration of the scene.
14470   * @returns {number} `get` -  Current scene duration.
14471   * @returns {Scene} `set` -  Parent object for chaining.
14472   */
14473
14474		/**
14475   * **Get** or **Set** the offset option value.
14476   * @method ScrollMagic.Scene#offset
14477   * @example
14478   * // get the current offset
14479   * var offset = scene.offset();
14480   *
14481   * // set a new offset
14482   * scene.offset(100);
14483   *
14484   * @fires {@link Scene.change}, when used as setter
14485   * @fires {@link Scene.shift}, when used as setter
14486   * @param {number} [newOffset] - The new offset of the scene.
14487   * @returns {number} `get` -  Current scene offset.
14488   * @returns {Scene} `set` -  Parent object for chaining.
14489   */
14490
14491		/**
14492   * **Get** or **Set** the triggerElement option value.
14493   * Does **not** fire `Scene.shift`, because changing the trigger Element doesn't necessarily mean the start position changes. This will be determined in `Scene.refresh()`, which is automatically triggered.
14494   * @method ScrollMagic.Scene#triggerElement
14495   * @example
14496   * // get the current triggerElement
14497   * var triggerElement = scene.triggerElement();
14498   *
14499   * // set a new triggerElement using a selector
14500   * scene.triggerElement("#trigger");
14501   * // set a new triggerElement using a DOM object
14502   * scene.triggerElement(document.getElementById("trigger"));
14503   *
14504   * @fires {@link Scene.change}, when used as setter
14505   * @param {(string|object)} [newTriggerElement] - The new trigger element for the scene.
14506   * @returns {(string|object)} `get` -  Current triggerElement.
14507   * @returns {Scene} `set` -  Parent object for chaining.
14508   */
14509
14510		/**
14511   * **Get** or **Set** the triggerHook option value.
14512   * @method ScrollMagic.Scene#triggerHook
14513   * @example
14514   * // get the current triggerHook value
14515   * var triggerHook = scene.triggerHook();
14516   *
14517   * // set a new triggerHook using a string
14518   * scene.triggerHook("onLeave");
14519   * // set a new triggerHook using a number
14520   * scene.triggerHook(0.7);
14521   *
14522   * @fires {@link Scene.change}, when used as setter
14523   * @fires {@link Scene.shift}, when used as setter
14524   * @param {(number|string)} [newTriggerHook] - The new triggerHook of the scene. See {@link Scene} parameter description for value options.
14525   * @returns {number} `get` -  Current triggerHook (ALWAYS numerical).
14526   * @returns {Scene} `set` -  Parent object for chaining.
14527   */
14528
14529		/**
14530   * **Get** or **Set** the reverse option value.
14531   * @method ScrollMagic.Scene#reverse
14532   * @example
14533   * // get the current reverse option
14534   * var reverse = scene.reverse();
14535   *
14536   * // set new reverse option
14537   * scene.reverse(false);
14538   *
14539   * @fires {@link Scene.change}, when used as setter
14540   * @param {boolean} [newReverse] - The new reverse setting of the scene.
14541   * @returns {boolean} `get` -  Current reverse option value.
14542   * @returns {Scene} `set` -  Parent object for chaining.
14543   */
14544
14545		/**
14546   * **Get** or **Set** the loglevel option value.
14547   * @method ScrollMagic.Scene#loglevel
14548   * @example
14549   * // get the current loglevel
14550   * var loglevel = scene.loglevel();
14551   *
14552   * // set new loglevel
14553   * scene.loglevel(3);
14554   *
14555   * @fires {@link Scene.change}, when used as setter
14556   * @param {number} [newLoglevel] - The new loglevel setting of the scene. `[0-3]`
14557   * @returns {number} `get` -  Current loglevel.
14558   * @returns {Scene} `set` -  Parent object for chaining.
14559   */
14560
14561		/**
14562   * **Get** the associated controller.
14563   * @method ScrollMagic.Scene#controller
14564   * @example
14565   * // get the controller of a scene
14566   * var controller = scene.controller();
14567   *
14568   * @returns {ScrollMagic.Controller} Parent controller or `undefined`
14569   */
14570		this.controller = function () {
14571			return _controller;
14572		};
14573
14574		/**
14575   * **Get** the current state.
14576   * @method ScrollMagic.Scene#state
14577   * @example
14578   * // get the current state
14579   * var state = scene.state();
14580   *
14581   * @returns {string} `"BEFORE"`, `"DURING"` or `"AFTER"`
14582   */
14583		this.state = function () {
14584			return _state;
14585		};
14586
14587		/**
14588   * **Get** the current scroll offset for the start of the scene.  
14589   * Mind, that the scrollOffset is related to the size of the container, if `triggerHook` is bigger than `0` (or `"onLeave"`).  
14590   * This means, that resizing the container or changing the `triggerHook` will influence the scene's start offset.
14591   * @method ScrollMagic.Scene#scrollOffset
14592   * @example
14593   * // get the current scroll offset for the start and end of the scene.
14594   * var start = scene.scrollOffset();
14595   * var end = scene.scrollOffset() + scene.duration();
14596   * console.log("the scene starts at", start, "and ends at", end);
14597   *
14598   * @returns {number} The scroll offset (of the container) at which the scene will trigger. Y value for vertical and X value for horizontal scrolls.
14599   */
14600		this.scrollOffset = function () {
14601			return _scrollOffset.start;
14602		};
14603
14604		/**
14605   * **Get** the trigger position of the scene (including the value of the `offset` option).  
14606   * @method ScrollMagic.Scene#triggerPosition
14607   * @example
14608   * // get the scene's trigger position
14609   * var triggerPosition = scene.triggerPosition();
14610   *
14611   * @returns {number} Start position of the scene. Top position value for vertical and left position value for horizontal scrolls.
14612   */
14613		this.triggerPosition = function () {
14614			var pos = _options.offset; // the offset is the basis
14615			if (_controller) {
14616				// get the trigger position
14617				if (_options.triggerElement) {
14618					// Element as trigger
14619					pos += _triggerPos;
14620				} else {
14621					// return the height of the triggerHook to start at the beginning
14622					pos += _controller.info("size") * Scene.triggerHook();
14623				}
14624			}
14625			return pos;
14626		};
14627
14628		var _pin, _pinOptions;
14629
14630		Scene.on("shift.internal", function (e) {
14631			var durationChanged = e.reason === "duration";
14632			if (_state === SCENE_STATE_AFTER && durationChanged || _state === SCENE_STATE_DURING && _options.duration === 0) {
14633				// if [duration changed after a scene (inside scene progress updates pin position)] or [duration is 0, we are in pin phase and some other value changed].
14634				updatePinState();
14635			}
14636			if (durationChanged) {
14637				updatePinDimensions();
14638			}
14639		}).on("progress.internal", function (e) {
14640			updatePinState();
14641		}).on("add.internal", function (e) {
14642			updatePinDimensions();
14643		}).on("destroy.internal", function (e) {
14644			Scene.removePin(e.reset);
14645		});
14646		/**
14647   * Update the pin state.
14648   * @private
14649   */
14650		var updatePinState = function (forceUnpin) {
14651			if (_pin && _controller) {
14652				var containerInfo = _controller.info(),
14653				    pinTarget = _pinOptions.spacer.firstChild; // may be pin element or another spacer, if cascading pins
14654				if (!forceUnpin && _state === SCENE_STATE_DURING) {
14655					// during scene or if duration is 0 and we are past the trigger
14656					// pinned state
14657					if (_util.css(pinTarget, "position") != "fixed") {
14658						// change state before updating pin spacer (position changes due to fixed collapsing might occur.)
14659						_util.css(pinTarget, {
14660							"position": "fixed"
14661						});
14662						// update pin spacer
14663						updatePinDimensions();
14664					}
14665
14666					var fixedPos = _util.get.offset(_pinOptions.spacer, true),
14667
14668					// get viewport position of spacer
14669					scrollDistance = _options.reverse || _options.duration === 0 ? containerInfo.scrollPos - _scrollOffset.start // quicker
14670					: Math.round(_progress * _options.duration * 10) / 10; // if no reverse and during pin the position needs to be recalculated using the progress
14671					// add scrollDistance
14672					fixedPos[containerInfo.vertical ? "top" : "left"] += scrollDistance;
14673
14674					// set new values
14675					_util.css(_pinOptions.spacer.firstChild, {
14676						top: fixedPos.top,
14677						left: fixedPos.left
14678					});
14679				} else {
14680					// unpinned state
14681					var newCSS = {
14682						position: _pinOptions.inFlow ? "relative" : "absolute",
14683						top: 0,
14684						left: 0
14685					},
14686					    change = _util.css(pinTarget, "position") != newCSS.position;
14687
14688					if (!_pinOptions.pushFollowers) {
14689						newCSS[containerInfo.vertical ? "top" : "left"] = _options.duration * _progress;
14690					} else if (_options.duration > 0) {
14691						// only concerns scenes with duration
14692						if (_state === SCENE_STATE_AFTER && parseFloat(_util.css(_pinOptions.spacer, "padding-top")) === 0) {
14693							change = true; // if in after state but havent updated spacer yet (jumped past pin)
14694						} else if (_state === SCENE_STATE_BEFORE && parseFloat(_util.css(_pinOptions.spacer, "padding-bottom")) === 0) {
14695							// before
14696							change = true; // jumped past fixed state upward direction
14697						}
14698					}
14699					// set new values
14700					_util.css(pinTarget, newCSS);
14701					if (change) {
14702						// update pin spacer if state changed
14703						updatePinDimensions();
14704					}
14705				}
14706			}
14707		};
14708
14709		/**
14710   * Update the pin spacer and/or element size.
14711   * The size of the spacer needs to be updated whenever the duration of the scene changes, if it is to push down following elements.
14712   * @private
14713   */
14714		var updatePinDimensions = function () {
14715			if (_pin && _controller && _pinOptions.inFlow) {
14716				// no spacerresize, if original position is absolute
14717				var after = _state === SCENE_STATE_AFTER,
14718				    before = _state === SCENE_STATE_BEFORE,
14719				    during = _state === SCENE_STATE_DURING,
14720				    vertical = _controller.info("vertical"),
14721				    pinTarget = _pinOptions.spacer.firstChild,
14722
14723				// usually the pined element but can also be another spacer (cascaded pins)
14724				marginCollapse = _util.isMarginCollapseType(_util.css(_pinOptions.spacer, "display")),
14725				    css = {};
14726
14727				// set new size
14728				// if relsize: spacer -> pin | else: pin -> spacer
14729				if (_pinOptions.relSize.width || _pinOptions.relSize.autoFullWidth) {
14730					if (during) {
14731						_util.css(_pin, {
14732							"width": _util.get.width(_pinOptions.spacer)
14733						});
14734					} else {
14735						_util.css(_pin, {
14736							"width": "100%"
14737						});
14738					}
14739				} else {
14740					// minwidth is needed for cascaded pins.
14741					css["min-width"] = _util.get.width(vertical ? _pin : pinTarget, true, true);
14742					css.width = during ? css["min-width"] : "auto";
14743				}
14744				if (_pinOptions.relSize.height) {
14745					if (during) {
14746						// the only padding the spacer should ever include is the duration (if pushFollowers = true), so we need to substract that.
14747						_util.css(_pin, {
14748							"height": _util.get.height(_pinOptions.spacer) - (_pinOptions.pushFollowers ? _options.duration : 0)
14749						});
14750					} else {
14751						_util.css(_pin, {
14752							"height": "100%"
14753						});
14754					}
14755				} else {
14756					// margin is only included if it's a cascaded pin to resolve an IE9 bug
14757					css["min-height"] = _util.get.height(vertical ? pinTarget : _pin, true, !marginCollapse); // needed for cascading pins
14758					css.height = during ? css["min-height"] : "auto";
14759				}
14760
14761				// add space for duration if pushFollowers is true
14762				if (_pinOptions.pushFollowers) {
14763					css["padding" + (vertical ? "Top" : "Left")] = _options.duration * _progress;
14764					css["padding" + (vertical ? "Bottom" : "Right")] = _options.duration * (1 - _progress);
14765				}
14766				_util.css(_pinOptions.spacer, css);
14767			}
14768		};
14769
14770		/**
14771   * Updates the Pin state (in certain scenarios)
14772   * If the controller container is not the document and we are mid-pin-phase scrolling or resizing the main document can result to wrong pin positions.
14773   * So this function is called on resize and scroll of the document.
14774   * @private
14775   */
14776		var updatePinInContainer = function () {
14777			if (_controller && _pin && _state === SCENE_STATE_DURING && !_controller.info("isDocument")) {
14778				updatePinState();
14779			}
14780		};
14781
14782		/**
14783   * Updates the Pin spacer size state (in certain scenarios)
14784   * If container is resized during pin and relatively sized the size of the pin might need to be updated...
14785   * So this function is called on resize of the container.
14786   * @private
14787   */
14788		var updateRelativePinSpacer = function () {
14789			if (_controller && _pin && // well, duh
14790			_state === SCENE_STATE_DURING && ( // element in pinned state?
14791			// is width or height relatively sized, but not in relation to body? then we need to recalc.
14792			(_pinOptions.relSize.width || _pinOptions.relSize.autoFullWidth) && _util.get.width(window) != _util.get.width(_pinOptions.spacer.parentNode) || _pinOptions.relSize.height && _util.get.height(window) != _util.get.height(_pinOptions.spacer.parentNode))) {
14793				updatePinDimensions();
14794			}
14795		};
14796
14797		/**
14798   * Is called, when the mousewhel is used while over a pinned element inside a div container.
14799   * If the scene is in fixed state scroll events would be counted towards the body. This forwards the event to the scroll container.
14800   * @private
14801   */
14802		var onMousewheelOverPin = function (e) {
14803			if (_controller && _pin && _state === SCENE_STATE_DURING && !_controller.info("isDocument")) {
14804				// in pin state
14805				e.preventDefault();
14806				_controller._setScrollPos(_controller.info("scrollPos") - ((e.wheelDelta || e[_controller.info("vertical") ? "wheelDeltaY" : "wheelDeltaX"]) / 3 || -e.detail * 30));
14807			}
14808		};
14809
14810		/**
14811   * Pin an element for the duration of the tween.  
14812   * If the scene duration is 0 the element will only be unpinned, if the user scrolls back past the start position.  
14813   * Make sure only one pin is applied to an element at the same time.
14814   * An element can be pinned multiple times, but only successively.
14815   * _**NOTE:** The option `pushFollowers` has no effect, when the scene duration is 0._
14816   * @method ScrollMagic.Scene#setPin
14817   * @example
14818   * // pin element and push all following elements down by the amount of the pin duration.
14819   * scene.setPin("#pin");
14820   *
14821   * // pin element and keeping all following elements in their place. The pinned element will move past them.
14822   * scene.setPin("#pin", {pushFollowers: false});
14823   *
14824   * @param {(string|object)} element - A Selector targeting an element or a DOM object that is supposed to be pinned.
14825   * @param {object} [settings] - settings for the pin
14826   * @param {boolean} [settings.pushFollowers=true] - If `true` following elements will be "pushed" down for the duration of the pin, if `false` the pinned element will just scroll past them.  
14827   Ignored, when duration is `0`.
14828   * @param {string} [settings.spacerClass="scrollmagic-pin-spacer"] - Classname of the pin spacer element, which is used to replace the element.
14829   *
14830   * @returns {Scene} Parent object for chaining.
14831   */
14832		this.setPin = function (element, settings) {
14833			var defaultSettings = {
14834				pushFollowers: true,
14835				spacerClass: "scrollmagic-pin-spacer"
14836			};
14837			settings = _util.extend({}, defaultSettings, settings);
14838
14839			// validate Element
14840			element = _util.get.elements(element)[0];
14841			if (!element) {
14842				log(1, "ERROR calling method 'setPin()': Invalid pin element supplied.");
14843				return Scene; // cancel
14844			} else if (_util.css(element, "position") === "fixed") {
14845				log(1, "ERROR calling method 'setPin()': Pin does not work with elements that are positioned 'fixed'.");
14846				return Scene; // cancel
14847			}
14848
14849			if (_pin) {
14850				// preexisting pin?
14851				if (_pin === element) {
14852					// same pin we already have -> do nothing
14853					return Scene; // cancel
14854				} else {
14855					// kill old pin
14856					Scene.removePin();
14857				}
14858			}
14859			_pin = element;
14860
14861			var parentDisplay = _pin.parentNode.style.display,
14862			    boundsParams = ["top", "left", "bottom", "right", "margin", "marginLeft", "marginRight", "marginTop", "marginBottom"];
14863
14864			_pin.parentNode.style.display = 'none'; // hack start to force css to return stylesheet values instead of calculated px values.
14865			var inFlow = _util.css(_pin, "position") != "absolute",
14866			    pinCSS = _util.css(_pin, boundsParams.concat(["display"])),
14867			    sizeCSS = _util.css(_pin, ["width", "height"]);
14868			_pin.parentNode.style.display = parentDisplay; // hack end.
14869			if (!inFlow && settings.pushFollowers) {
14870				log(2, "WARNING: If the pinned element is positioned absolutely pushFollowers will be disabled.");
14871				settings.pushFollowers = false;
14872			}
14873			window.setTimeout(function () {
14874				// wait until all finished, because with responsive duration it will only be set after scene is added to controller
14875				if (_pin && _options.duration === 0 && settings.pushFollowers) {
14876					log(2, "WARNING: pushFollowers =", true, "has no effect, when scene duration is 0.");
14877				}
14878			}, 0);
14879
14880			// create spacer and insert
14881			var spacer = _pin.parentNode.insertBefore(document.createElement('div'), _pin),
14882			    spacerCSS = _util.extend(pinCSS, {
14883				position: inFlow ? "relative" : "absolute",
14884				boxSizing: "content-box",
14885				mozBoxSizing: "content-box",
14886				webkitBoxSizing: "content-box"
14887			});
14888
14889			if (!inFlow) {
14890				// copy size if positioned absolutely, to work for bottom/right positioned elements.
14891				_util.extend(spacerCSS, _util.css(_pin, ["width", "height"]));
14892			}
14893
14894			_util.css(spacer, spacerCSS);
14895			spacer.setAttribute(PIN_SPACER_ATTRIBUTE, "");
14896			_util.addClass(spacer, settings.spacerClass);
14897
14898			// set the pin Options
14899			_pinOptions = {
14900				spacer: spacer,
14901				relSize: { // save if size is defined using % values. if so, handle spacer resize differently...
14902					width: sizeCSS.width.slice(-1) === "%",
14903					height: sizeCSS.height.slice(-1) === "%",
14904					autoFullWidth: sizeCSS.width === "auto" && inFlow && _util.isMarginCollapseType(pinCSS.display)
14905				},
14906				pushFollowers: settings.pushFollowers,
14907				inFlow: inFlow
14908				// stores if the element takes up space in the document flow
14909			};
14910
14911			if (!_pin.___origStyle) {
14912				_pin.___origStyle = {};
14913				var pinInlineCSS = _pin.style,
14914				    copyStyles = boundsParams.concat(["width", "height", "position", "boxSizing", "mozBoxSizing", "webkitBoxSizing"]);
14915				copyStyles.forEach(function (val) {
14916					_pin.___origStyle[val] = pinInlineCSS[val] || "";
14917				});
14918			}
14919
14920			// if relative size, transfer it to spacer and make pin calculate it...
14921			if (_pinOptions.relSize.width) {
14922				_util.css(spacer, {
14923					width: sizeCSS.width
14924				});
14925			}
14926			if (_pinOptions.relSize.height) {
14927				_util.css(spacer, {
14928					height: sizeCSS.height
14929				});
14930			}
14931
14932			// now place the pin element inside the spacer	
14933			spacer.appendChild(_pin);
14934			// and set new css
14935			_util.css(_pin, {
14936				position: inFlow ? "relative" : "absolute",
14937				margin: "auto",
14938				top: "auto",
14939				left: "auto",
14940				bottom: "auto",
14941				right: "auto"
14942			});
14943
14944			if (_pinOptions.relSize.width || _pinOptions.relSize.autoFullWidth) {
14945				_util.css(_pin, {
14946					boxSizing: "border-box",
14947					mozBoxSizing: "border-box",
14948					webkitBoxSizing: "border-box"
14949				});
14950			}
14951
14952			// add listener to document to update pin position in case controller is not the document.
14953			window.addEventListener('scroll', updatePinInContainer);
14954			window.addEventListener('resize', updatePinInContainer);
14955			window.addEventListener('resize', updateRelativePinSpacer);
14956			// add mousewheel listener to catch scrolls over fixed elements
14957			_pin.addEventListener("mousewheel", onMousewheelOverPin);
14958			_pin.addEventListener("DOMMouseScroll", onMousewheelOverPin);
14959
14960			log(3, "added pin");
14961
14962			// finally update the pin to init
14963			updatePinState();
14964
14965			return Scene;
14966		};
14967
14968		/**
14969   * Remove the pin from the scene.
14970   * @method ScrollMagic.Scene#removePin
14971   * @example
14972   * // remove the pin from the scene without resetting it (the spacer is not removed)
14973   * scene.removePin();
14974   *
14975   * // remove the pin from the scene and reset the pin element to its initial position (spacer is removed)
14976   * scene.removePin(true);
14977   *
14978   * @param {boolean} [reset=false] - If `false` the spacer will not be removed and the element's position will not be reset.
14979   * @returns {Scene} Parent object for chaining.
14980   */
14981		this.removePin = function (reset) {
14982			if (_pin) {
14983				if (_state === SCENE_STATE_DURING) {
14984					updatePinState(true); // force unpin at position
14985				}
14986				if (reset || !_controller) {
14987					// if there's no controller no progress was made anyway...
14988					var pinTarget = _pinOptions.spacer.firstChild; // usually the pin element, but may be another spacer (cascaded pins)...
14989					if (pinTarget.hasAttribute(PIN_SPACER_ATTRIBUTE)) {
14990						// copy margins to child spacer
14991						var style = _pinOptions.spacer.style,
14992						    values = ["margin", "marginLeft", "marginRight", "marginTop", "marginBottom"];
14993						margins = {};
14994						values.forEach(function (val) {
14995							margins[val] = style[val] || "";
14996						});
14997						_util.css(pinTarget, margins);
14998					}
14999					_pinOptions.spacer.parentNode.insertBefore(pinTarget, _pinOptions.spacer);
15000					_pinOptions.spacer.parentNode.removeChild(_pinOptions.spacer);
15001					if (!_pin.parentNode.hasAttribute(PIN_SPACER_ATTRIBUTE)) {
15002						// if it's the last pin for this element -> restore inline styles
15003						// TODO: only correctly set for first pin (when cascading) - how to fix?
15004						_util.css(_pin, _pin.___origStyle);
15005						delete _pin.___origStyle;
15006					}
15007				}
15008				window.removeEventListener('scroll', updatePinInContainer);
15009				window.removeEventListener('resize', updatePinInContainer);
15010				window.removeEventListener('resize', updateRelativePinSpacer);
15011				_pin.removeEventListener("mousewheel", onMousewheelOverPin);
15012				_pin.removeEventListener("DOMMouseScroll", onMousewheelOverPin);
15013				_pin = undefined;
15014				log(3, "removed pin (reset: " + (reset ? "true" : "false") + ")");
15015			}
15016			return Scene;
15017		};
15018
15019		var _cssClasses,
15020		    _cssClassElems = [];
15021
15022		Scene.on("destroy.internal", function (e) {
15023			Scene.removeClassToggle(e.reset);
15024		});
15025		/**
15026   * Define a css class modification while the scene is active.  
15027   * When the scene triggers the classes will be added to the supplied element and removed, when the scene is over.
15028   * If the scene duration is 0 the classes will only be removed if the user scrolls back past the start position.
15029   * @method ScrollMagic.Scene#setClassToggle
15030   * @example
15031   * // add the class 'myclass' to the element with the id 'my-elem' for the duration of the scene
15032   * scene.setClassToggle("#my-elem", "myclass");
15033   *
15034   * // add multiple classes to multiple elements defined by the selector '.classChange'
15035   * scene.setClassToggle(".classChange", "class1 class2 class3");
15036   *
15037   * @param {(string|object)} element - A Selector targeting one or more elements or a DOM object that is supposed to be modified.
15038   * @param {string} classes - One or more Classnames (separated by space) that should be added to the element during the scene.
15039   *
15040   * @returns {Scene} Parent object for chaining.
15041   */
15042		this.setClassToggle = function (element, classes) {
15043			var elems = _util.get.elements(element);
15044			if (elems.length === 0 || !_util.type.String(classes)) {
15045				log(1, "ERROR calling method 'setClassToggle()': Invalid " + (elems.length === 0 ? "element" : "classes") + " supplied.");
15046				return Scene;
15047			}
15048			if (_cssClassElems.length > 0) {
15049				// remove old ones
15050				Scene.removeClassToggle();
15051			}
15052			_cssClasses = classes;
15053			_cssClassElems = elems;
15054			Scene.on("enter.internal_class leave.internal_class", function (e) {
15055				var toggle = e.type === "enter" ? _util.addClass : _util.removeClass;
15056				_cssClassElems.forEach(function (elem, key) {
15057					toggle(elem, _cssClasses);
15058				});
15059			});
15060			return Scene;
15061		};
15062
15063		/**
15064   * Remove the class binding from the scene.
15065   * @method ScrollMagic.Scene#removeClassToggle
15066   * @example
15067   * // remove class binding from the scene without reset
15068   * scene.removeClassToggle();
15069   *
15070   * // remove class binding and remove the changes it caused
15071   * scene.removeClassToggle(true);
15072   *
15073   * @param {boolean} [reset=false] - If `false` and the classes are currently active, they will remain on the element. If `true` they will be removed.
15074   * @returns {Scene} Parent object for chaining.
15075   */
15076		this.removeClassToggle = function (reset) {
15077			if (reset) {
15078				_cssClassElems.forEach(function (elem, key) {
15079					_util.removeClass(elem, _cssClasses);
15080				});
15081			}
15082			Scene.off("start.internal_class end.internal_class");
15083			_cssClasses = undefined;
15084			_cssClassElems = [];
15085			return Scene;
15086		};
15087
15088		// INIT
15089		construct();
15090		return Scene;
15091	};
15092
15093	// store pagewide scene options
15094	var SCENE_OPTIONS = {
15095		defaults: {
15096			duration: 0,
15097			offset: 0,
15098			triggerElement: undefined,
15099			triggerHook: 0.5,
15100			reverse: true,
15101			loglevel: 2
15102		},
15103		validate: {
15104			offset: function (val) {
15105				val = parseFloat(val);
15106				if (!_util.type.Number(val)) {
15107					throw ["Invalid value for option \"offset\":", val];
15108				}
15109				return val;
15110			},
15111			triggerElement: function (val) {
15112				val = val || undefined;
15113				if (val) {
15114					var elem = _util.get.elements(val)[0];
15115					if (elem) {
15116						val = elem;
15117					} else {
15118						throw ["Element defined in option \"triggerElement\" was not found:", val];
15119					}
15120				}
15121				return val;
15122			},
15123			triggerHook: function (val) {
15124				var translate = {
15125					"onCenter": 0.5,
15126					"onEnter": 1,
15127					"onLeave": 0
15128				};
15129				if (_util.type.Number(val)) {
15130					val = Math.max(0, Math.min(parseFloat(val), 1)); //  make sure its betweeen 0 and 1
15131				} else if (val in translate) {
15132					val = translate[val];
15133				} else {
15134					throw ["Invalid value for option \"triggerHook\": ", val];
15135				}
15136				return val;
15137			},
15138			reverse: function (val) {
15139				return !!val; // force boolean
15140			},
15141			loglevel: function (val) {
15142				val = parseInt(val);
15143				if (!_util.type.Number(val) || val < 0 || val > 3) {
15144					throw ["Invalid value for option \"loglevel\":", val];
15145				}
15146				return val;
15147			}
15148		},
15149		// holder for  validation methods. duration validation is handled in 'getters-setters.js'
15150		shifts: ["duration", "offset", "triggerHook"]
15151		// list of options that trigger a `shift` event
15152	};
15153	/*
15154  * method used to add an option to ScrollMagic Scenes.
15155  * TODO: DOC (private for dev)
15156  */
15157	ScrollMagic.Scene.addOption = function (name, defaultValue, validationCallback, shifts) {
15158		if (!(name in SCENE_OPTIONS.defaults)) {
15159			SCENE_OPTIONS.defaults[name] = defaultValue;
15160			SCENE_OPTIONS.validate[name] = validationCallback;
15161			if (shifts) {
15162				SCENE_OPTIONS.shifts.push(name);
15163			}
15164		} else {
15165			ScrollMagic._util.log(1, "[static] ScrollMagic.Scene -> Cannot add Scene option '" + name + "', because it already exists.");
15166		}
15167	};
15168	// instance extension function for plugins
15169	// TODO: DOC (private for dev)
15170	ScrollMagic.Scene.extend = function (extension) {
15171		var oldClass = this;
15172		ScrollMagic.Scene = function () {
15173			oldClass.apply(this, arguments);
15174			this.$super = _util.extend({}, this); // copy parent state
15175			return extension.apply(this, arguments) || this;
15176		};
15177		_util.extend(ScrollMagic.Scene, oldClass); // copy properties
15178		ScrollMagic.Scene.prototype = oldClass.prototype; // copy prototype
15179		ScrollMagic.Scene.prototype.constructor = ScrollMagic.Scene; // restore constructor
15180	};
15181
15182	/**
15183  * TODO: DOCS (private for dev)
15184  * @class
15185  * @private
15186  */
15187
15188	ScrollMagic.Event = function (type, namespace, target, vars) {
15189		vars = vars || {};
15190		for (var key in vars) {
15191			this[key] = vars[key];
15192		}
15193		this.type = type;
15194		this.target = this.currentTarget = target;
15195		this.namespace = namespace || '';
15196		this.timeStamp = this.timestamp = Date.now();
15197		return this;
15198	};
15199
15200	/*
15201  * TODO: DOCS (private for dev)
15202  */
15203
15204	var _util = ScrollMagic._util = function (window) {
15205		var U = {},
15206		    i;
15207
15208		/**
15209   * ------------------------------
15210   * internal helpers
15211   * ------------------------------
15212   */
15213
15214		// parse float and fall back to 0.
15215		var floatval = function (number) {
15216			return parseFloat(number) || 0;
15217		};
15218		// get current style IE safe (otherwise IE would return calculated values for 'auto')
15219		var _getComputedStyle = function (elem) {
15220			return elem.currentStyle ? elem.currentStyle : window.getComputedStyle(elem);
15221		};
15222
15223		// get element dimension (width or height)
15224		var _dimension = function (which, elem, outer, includeMargin) {
15225			elem = elem === document ? window : elem;
15226			if (elem === window) {
15227				includeMargin = false;
15228			} else if (!_type.DomElement(elem)) {
15229				return 0;
15230			}
15231			which = which.charAt(0).toUpperCase() + which.substr(1).toLowerCase();
15232			var dimension = (outer ? elem['offset' + which] || elem['outer' + which] : elem['client' + which] || elem['inner' + which]) || 0;
15233			if (outer && includeMargin) {
15234				var style = _getComputedStyle(elem);
15235				dimension += which === 'Height' ? floatval(style.marginTop) + floatval(style.marginBottom) : floatval(style.marginLeft) + floatval(style.marginRight);
15236			}
15237			return dimension;
15238		};
15239		// converts 'margin-top' into 'marginTop'
15240		var _camelCase = function (str) {
15241			return str.replace(/^[^a-z]+([a-z])/g, '$1').replace(/-([a-z])/g, function (g) {
15242				return g[1].toUpperCase();
15243			});
15244		};
15245
15246		/**
15247   * ------------------------------
15248   * external helpers
15249   * ------------------------------
15250   */
15251
15252		// extend obj – same as jQuery.extend({}, objA, objB)
15253		U.extend = function (obj) {
15254			obj = obj || {};
15255			for (i = 1; i < arguments.length; i++) {
15256				if (!arguments[i]) {
15257					continue;
15258				}
15259				for (var key in arguments[i]) {
15260					if (arguments[i].hasOwnProperty(key)) {
15261						obj[key] = arguments[i][key];
15262					}
15263				}
15264			}
15265			return obj;
15266		};
15267
15268		// check if a css display type results in margin-collapse or not
15269		U.isMarginCollapseType = function (str) {
15270			return ["block", "flex", "list-item", "table", "-webkit-box"].indexOf(str) > -1;
15271		};
15272
15273		// implementation of requestAnimationFrame
15274		// based on https://gist.github.com/paulirish/1579671
15275		var lastTime = 0,
15276		    vendors = ['ms', 'moz', 'webkit', 'o'];
15277		var _requestAnimationFrame = window.requestAnimationFrame;
15278		var _cancelAnimationFrame = window.cancelAnimationFrame;
15279		// try vendor prefixes if the above doesn't work
15280		for (i = 0; !_requestAnimationFrame && i < vendors.length; ++i) {
15281			_requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame'];
15282			_cancelAnimationFrame = window[vendors[i] + 'CancelAnimationFrame'] || window[vendors[i] + 'CancelRequestAnimationFrame'];
15283		}
15284
15285		// fallbacks
15286		if (!_requestAnimationFrame) {
15287			_requestAnimationFrame = function (callback) {
15288				var currTime = new Date().getTime(),
15289				    timeToCall = Math.max(0, 16 - (currTime - lastTime)),
15290				    id = window.setTimeout(function () {
15291					callback(currTime + timeToCall);
15292				}, timeToCall);
15293				lastTime = currTime + timeToCall;
15294				return id;
15295			};
15296		}
15297		if (!_cancelAnimationFrame) {
15298			_cancelAnimationFrame = function (id) {
15299				window.clearTimeout(id);
15300			};
15301		}
15302		U.rAF = _requestAnimationFrame.bind(window);
15303		U.cAF = _cancelAnimationFrame.bind(window);
15304
15305		var loglevels = ["error", "warn", "log"],
15306		    console = window.console || {};
15307
15308		console.log = console.log || function () {}; // no console log, well - do nothing then...
15309		// make sure methods for all levels exist.
15310		for (i = 0; i < loglevels.length; i++) {
15311			var method = loglevels[i];
15312			if (!console[method]) {
15313				console[method] = console.log; // prefer .log over nothing
15314			}
15315		}
15316		U.log = function (loglevel) {
15317			if (loglevel > loglevels.length || loglevel <= 0) loglevel = loglevels.length;
15318			var now = new Date(),
15319			    time = ("0" + now.getHours()).slice(-2) + ":" + ("0" + now.getMinutes()).slice(-2) + ":" + ("0" + now.getSeconds()).slice(-2) + ":" + ("00" + now.getMilliseconds()).slice(-3),
15320			    method = loglevels[loglevel - 1],
15321			    args = Array.prototype.splice.call(arguments, 1),
15322			    func = Function.prototype.bind.call(console[method], console);
15323			args.unshift(time);
15324			func.apply(console, args);
15325		};
15326
15327		/**
15328   * ------------------------------
15329   * type testing
15330   * ------------------------------
15331   */
15332
15333		var _type = U.type = function (v) {
15334			return Object.prototype.toString.call(v).replace(/^\[object (.+)\]$/, "$1").toLowerCase();
15335		};
15336		_type.String = function (v) {
15337			return _type(v) === 'string';
15338		};
15339		_type.Function = function (v) {
15340			return _type(v) === 'function';
15341		};
15342		_type.Array = function (v) {
15343			return Array.isArray(v);
15344		};
15345		_type.Number = function (v) {
15346			return !_type.Array(v) && v - parseFloat(v) + 1 >= 0;
15347		};
15348		_type.DomElement = function (o) {
15349			return typeof HTMLElement === "object" ? o instanceof HTMLElement : //DOM2
15350			o && typeof o === "object" && o !== null && o.nodeType === 1 && typeof o.nodeName === "string";
15351		};
15352
15353		/**
15354   * ------------------------------
15355   * DOM Element info
15356   * ------------------------------
15357   */
15358		// always returns a list of matching DOM elements, from a selector, a DOM element or an list of elements or even an array of selectors
15359		var _get = U.get = {};
15360		_get.elements = function (selector) {
15361			var arr = [];
15362			if (_type.String(selector)) {
15363				try {
15364					selector = document.querySelectorAll(selector);
15365				} catch (e) {
15366					// invalid selector
15367					return arr;
15368				}
15369			}
15370			if (_type(selector) === 'nodelist' || _type.Array(selector)) {
15371				for (var i = 0, ref = arr.length = selector.length; i < ref; i++) {
15372					// list of elements
15373					var elem = selector[i];
15374					arr[i] = _type.DomElement(elem) ? elem : _get.elements(elem); // if not an element, try to resolve recursively
15375				}
15376			} else if (_type.DomElement(selector) || selector === document || selector === window) {
15377				arr = [selector]; // only the element
15378			}
15379			return arr;
15380		};
15381		// get scroll top value
15382		_get.scrollTop = function (elem) {
15383			return elem && typeof elem.scrollTop === 'number' ? elem.scrollTop : window.pageYOffset || 0;
15384		};
15385		// get scroll left value
15386		_get.scrollLeft = function (elem) {
15387			return elem && typeof elem.scrollLeft === 'number' ? elem.scrollLeft : window.pageXOffset || 0;
15388		};
15389		// get element height
15390		_get.width = function (elem, outer, includeMargin) {
15391			return _dimension('width', elem, outer, includeMargin);
15392		};
15393		// get element width
15394		_get.height = function (elem, outer, includeMargin) {
15395			return _dimension('height', elem, outer, includeMargin);
15396		};
15397
15398		// get element position (optionally relative to viewport)
15399		_get.offset = function (elem, relativeToViewport) {
15400			var offset = {
15401				top: 0,
15402				left: 0
15403			};
15404			if (elem && elem.getBoundingClientRect) {
15405				// check if available
15406				var rect = elem.getBoundingClientRect();
15407				offset.top = rect.top;
15408				offset.left = rect.left;
15409				if (!relativeToViewport) {
15410					// clientRect is by default relative to viewport...
15411					offset.top += _get.scrollTop();
15412					offset.left += _get.scrollLeft();
15413				}
15414			}
15415			return offset;
15416		};
15417
15418		/**
15419   * ------------------------------
15420   * DOM Element manipulation
15421   * ------------------------------
15422   */
15423
15424		U.addClass = function (elem, classname) {
15425			if (classname) {
15426				if (elem.classList) elem.classList.add(classname);else elem.className += ' ' + classname;
15427			}
15428		};
15429		U.removeClass = function (elem, classname) {
15430			if (classname) {
15431				if (elem.classList) elem.classList.remove(classname);else elem.className = elem.className.replace(new RegExp('(^|\\b)' + classname.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
15432			}
15433		};
15434		// if options is string -> returns css value
15435		// if options is array -> returns object with css value pairs
15436		// if options is object -> set new css values
15437		U.css = function (elem, options) {
15438			if (_type.String(options)) {
15439				return _getComputedStyle(elem)[_camelCase(options)];
15440			} else if (_type.Array(options)) {
15441				var obj = {},
15442				    style = _getComputedStyle(elem);
15443				options.forEach(function (option, key) {
15444					obj[option] = style[_camelCase(option)];
15445				});
15446				return obj;
15447			} else {
15448				for (var option in options) {
15449					var val = options[option];
15450					if (val == parseFloat(val)) {
15451						// assume pixel for seemingly numerical values
15452						val += 'px';
15453					}
15454					elem.style[_camelCase(option)] = val;
15455				}
15456			}
15457		};
15458
15459		return U;
15460	}(window || {});
15461
15462	ScrollMagic.Scene.prototype.addIndicators = function () {
15463		ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling addIndicators() due to missing Plugin \'debug.addIndicators\'. Please make sure to include plugins/debug.addIndicators.js');
15464		return this;
15465	};
15466	ScrollMagic.Scene.prototype.removeIndicators = function () {
15467		ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling removeIndicators() due to missing Plugin \'debug.addIndicators\'. Please make sure to include plugins/debug.addIndicators.js');
15468		return this;
15469	};
15470	ScrollMagic.Scene.prototype.setTween = function () {
15471		ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling setTween() due to missing Plugin \'animation.gsap\'. Please make sure to include plugins/animation.gsap.js');
15472		return this;
15473	};
15474	ScrollMagic.Scene.prototype.removeTween = function () {
15475		ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling removeTween() due to missing Plugin \'animation.gsap\'. Please make sure to include plugins/animation.gsap.js');
15476		return this;
15477	};
15478	ScrollMagic.Scene.prototype.setVelocity = function () {
15479		ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling setVelocity() due to missing Plugin \'animation.velocity\'. Please make sure to include plugins/animation.velocity.js');
15480		return this;
15481	};
15482	ScrollMagic.Scene.prototype.removeVelocity = function () {
15483		ScrollMagic._util.log(1, '(ScrollMagic.Scene) -> ERROR calling removeVelocity() due to missing Plugin \'animation.velocity\'. Please make sure to include plugins/animation.velocity.js');
15484		return this;
15485	};
15486
15487	return ScrollMagic;
15488});
15489
15490/***/ }),
15491/* 3 */,
15492/* 4 */,
15493/* 5 */
15494/***/ (function(module, exports) {
15495
15496var g;
15497
15498// This works in non-strict mode
15499g = function () {
15500	return this;
15501}();
15502
15503try {
15504	// This works if eval is allowed (see CSP)
15505	g = g || Function("return this")() || (1, eval)("this");
15506} catch (e) {
15507	// This works if the window reference is available
15508	if (typeof window === "object") g = window;
15509}
15510
15511// g can still be undefined, but nothing to do about it...
15512// We return undefined, instead of nothing here, so it's
15513// easier to handle this case. if(!global) { ...}
15514
15515module.exports = g;
15516
15517/***/ }),
15518/* 6 */
15519/***/ (function(module, __webpack_exports__, __webpack_require__) {
15520
15521"use strict";
15522/* eslint consistent-return: "off" */
15523/* eslint func-names: ["off"] */
15524/* eslint max-len: ["off", { "code": 200 }] */
15525/* eslint prefer-destructuring: ["off"] */
15526/**
15527 * ------------------------------------------------------------------
15528 * 判断浏览器类型
15529 * ------------------------------------------------------------------
15530 */
15531
15532const browserType = function () {
15533  const userAgent = navigator.userAgent; // 取得浏览器的userAgent字符串
15534  const isOpera = userAgent.indexOf('Opera') > -1; // 判断是否Opera浏览器
15535  // let isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1 && !isOpera; //判断是否IE浏览器
15536  const isIE = window.ActiveXObject || 'ActiveXObject' in window;
15537  // let isEdge = userAgent.indexOf("Windows NT 6.1; Trident/7.0;") > -1 && !isIE; //判断是否IE的Edge浏览器
15538  const isEdge = userAgent.indexOf('Edge') > -1; // 判断是否IE的Edge浏览器
15539  const isFF = userAgent.indexOf('Firefox') > -1; // 判断是否Firefox浏览器
15540  const isSafari = userAgent.indexOf('Safari') > -1 && userAgent.indexOf('Chrome') === -1; // 判断是否Safari浏览器
15541  const isChrome = userAgent.indexOf('Chrome') > -1 && userAgent.indexOf('Safari') > -1 && !isEdge; // 判断Chrome浏览器
15542
15543  if (isIE) {
15544    const reIE = new RegExp('MSIE (\\d+\\.\\d+);');
15545    reIE.test(userAgent);
15546    const fIEVersion = parseFloat(RegExp.$1);
15547    if (userAgent.indexOf('MSIE 6.0') !== -1) {
15548      return 'IE6';
15549    } else if (fIEVersion === 7) {
15550      return 'IE7';
15551    } else if (fIEVersion === 8) {
15552      return 'IE8';
15553    } else if (fIEVersion === 9) {
15554      return 'IE9';
15555    } else if (fIEVersion === 10) {
15556      return 'IE10';
15557    } else if (userAgent.toLowerCase().match(/rv:([\d.]+)\) like gecko/)) {
15558      return 'IE11';
15559    }
15560    return '0'; // IE版本过低
15561  } // isIE end
15562
15563  if (isFF) {
15564    return 'FF';
15565  }
15566  if (isOpera) {
15567    return 'Opera';
15568  }
15569  if (isSafari) {
15570    return 'Safari';
15571  }
15572  if (isChrome) {
15573    return 'Chrome';
15574  }
15575  if (isEdge) {
15576    return 'Edge';
15577  }
15578};
15579
15580/* harmony default export */ __webpack_exports__["a"] = (browserType);
15581
15582/***/ }),
15583/* 7 */
15584/***/ (function(module, exports, __webpack_require__) {
15585
15586/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
15587 * VERSION: 1.20.3
15588 * DATE: 2017-10-02
15589 * UPDATES AND DOCS AT: http://greensock.com
15590 * 
15591 * Includes all of the following: TweenLite, TweenMax, TimelineLite, TimelineMax, EasePack, CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin
15592 *
15593 * @license Copyright (c) 2008-2017, GreenSock. All rights reserved.
15594 * This work is subject to the terms at http://greensock.com/standard-license or for
15595 * Club GreenSock members, the software agreement that was issued with your membership.
15596 * 
15597 * @author: Jack Doyle, [email protected]
15598 **/
15599var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node
15600(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () {
15601
15602	"use strict";
15603
15604	_gsScope._gsDefine("TweenMax", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) {
15605
15606		var _slice = function (a) {
15607			//don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
15608			var b = [],
15609			    l = a.length,
15610			    i;
15611			for (i = 0; i !== l; b.push(a[i++]));
15612			return b;
15613		},
15614		    _applyCycle = function (vars, targets, i) {
15615			var alt = vars.cycle,
15616			    p,
15617			    val;
15618			for (p in alt) {
15619				val = alt[p];
15620				vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length];
15621			}
15622			delete vars.cycle;
15623		},
15624		    TweenMax = function (target, duration, vars) {
15625			TweenLite.call(this, target, duration, vars);
15626			this._cycle = 0;
15627			this._yoyo = this.vars.yoyo === true || !!this.vars.yoyoEase;
15628			this._repeat = this.vars.repeat || 0;
15629			this._repeatDelay = this.vars.repeatDelay || 0;
15630			if (this._repeat) {
15631				this._uncache(true); //ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it.
15632			}
15633			this.render = TweenMax.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
15634		},
15635		    _tinyNum = 0.0000000001,
15636		    TweenLiteInternals = TweenLite._internals,
15637		    _isSelector = TweenLiteInternals.isSelector,
15638		    _isArray = TweenLiteInternals.isArray,
15639		    p = TweenMax.prototype = TweenLite.to({}, 0.1, {}),
15640		    _blankArray = [];
15641
15642		TweenMax.version = "1.20.3";
15643		p.constructor = TweenMax;
15644		p.kill()._gc = false;
15645		TweenMax.killTweensOf = TweenMax.killDelayedCallsTo = TweenLite.killTweensOf;
15646		TweenMax.getTweensOf = TweenLite.getTweensOf;
15647		TweenMax.lagSmoothing = TweenLite.lagSmoothing;
15648		TweenMax.ticker = TweenLite.ticker;
15649		TweenMax.render = TweenLite.render;
15650
15651		p.invalidate = function () {
15652			this._yoyo = this.vars.yoyo === true || !!this.vars.yoyoEase;
15653			this._repeat = this.vars.repeat || 0;
15654			this._repeatDelay = this.vars.repeatDelay || 0;
15655			this._yoyoEase = null;
15656			this._uncache(true);
15657			return TweenLite.prototype.invalidate.call(this);
15658		};
15659
15660		p.updateTo = function (vars, resetDuration) {
15661			var curRatio = this.ratio,
15662			    immediate = this.vars.immediateRender || vars.immediateRender,
15663			    p;
15664			if (resetDuration && this._startTime < this._timeline._time) {
15665				this._startTime = this._timeline._time;
15666				this._uncache(false);
15667				if (this._gc) {
15668					this._enabled(true, false);
15669				} else {
15670					this._timeline.insert(this, this._startTime - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct.
15671				}
15672			}
15673			for (p in vars) {
15674				this.vars[p] = vars[p];
15675			}
15676			if (this._initted || immediate) {
15677				if (resetDuration) {
15678					this._initted = false;
15679					if (immediate) {
15680						this.render(0, true, true);
15681					}
15682				} else {
15683					if (this._gc) {
15684						this._enabled(true, false);
15685					}
15686					if (this._notifyPluginsOfEnabled && this._firstPT) {
15687						TweenLite._onPluginEvent("_onDisable", this); //in case a plugin like MotionBlur must perform some cleanup tasks
15688					}
15689					if (this._time / this._duration > 0.998) {
15690						//if the tween has finished (or come extremely close to finishing), we just need to rewind it to 0 and then render it again at the end which forces it to re-initialize (parsing the new vars). We allow tweens that are close to finishing (but haven't quite finished) to work this way too because otherwise, the values are so small when determining where to project the starting values that binary math issues creep in and can make the tween appear to render incorrectly when run backwards. 
15691						var prevTime = this._totalTime;
15692						this.render(0, true, false);
15693						this._initted = false;
15694						this.render(prevTime, true, false);
15695					} else {
15696						this._initted = false;
15697						this._init();
15698						if (this._time > 0 || immediate) {
15699							var inv = 1 / (1 - curRatio),
15700							    pt = this._firstPT,
15701							    endValue;
15702							while (pt) {
15703								endValue = pt.s + pt.c;
15704								pt.c *= inv;
15705								pt.s = endValue - pt.c;
15706								pt = pt._next;
15707							}
15708						}
15709					}
15710				}
15711			}
15712			return this;
15713		};
15714
15715		p.render = function (time, suppressEvents, force) {
15716			if (!this._initted) if (this._duration === 0 && this.vars.repeat) {
15717				//zero duration tweens that render immediately have render() called from TweenLite's constructor, before TweenMax's constructor has finished setting _repeat, _repeatDelay, and _yoyo which are critical in determining totalDuration() so we need to call invalidate() which is a low-kb way to get those set properly.
15718				this.invalidate();
15719			}
15720			var totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
15721			    prevTime = this._time,
15722			    prevTotalTime = this._totalTime,
15723			    prevCycle = this._cycle,
15724			    duration = this._duration,
15725			    prevRawPrevTime = this._rawPrevTime,
15726			    isComplete,
15727			    callback,
15728			    pt,
15729			    cycleDuration,
15730			    r,
15731			    type,
15732			    pow,
15733			    rawPrevTime,
15734			    yoyoEase;
15735			if (time >= totalDur - 0.0000001 && time >= 0) {
15736				//to work around occasional floating point math artifacts.
15737				this._totalTime = totalDur;
15738				this._cycle = this._repeat;
15739				if (this._yoyo && (this._cycle & 1) !== 0) {
15740					this._time = 0;
15741					this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
15742				} else {
15743					this._time = duration;
15744					this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
15745				}
15746				if (!this._reversed) {
15747					isComplete = true;
15748					callback = "onComplete";
15749					force = force || this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
15750				}
15751				if (duration === 0) if (this._initted || !this.vars.lazy || force) {
15752					//zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
15753					if (this._startTime === this._timeline._duration) {
15754						//if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent roun
15754ding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate.
15755						time = 0;
15756					}
15757					if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) {
15758						//note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause.
15759						force = true;
15760						if (prevRawPrevTime > _tinyNum) {
15761							callback = "onReverseComplete";
15762						}
15763					}
15764					this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
15765				}
15766			} else if (time < 0.0000001) {
15767				//to work around occasional floating point math artifacts, round super small values to 0.
15768				this._totalTime = this._time = this._cycle = 0;
15769				this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
15770				if (prevTotalTime !== 0 || duration === 0 && prevRawPrevTime > 0) {
15771					callback = "onReverseComplete";
15772					isComplete = this._reversed;
15773				}
15774				if (time < 0) {
15775					this._active = false;
15776					if (duration === 0) if (this._initted || !this.vars.lazy || force) {
15777						//zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
15778						if (prevRawPrevTime >= 0) {
15779							force = true;
15780						}
15781						this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
15782					}
15783				}
15784				if (!this._initted) {
15785					//if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately.
15786					force = true;
15787				}
15788			} else {
15789				this._totalTime = this._time = time;
15790				if (this._repeat !== 0) {
15791					cycleDuration = duration + this._repeatDelay;
15792					this._cycle = this._totalTime / cycleDuration >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)
15793					if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
15794						this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
15795					}
15796					this._time = this._totalTime - this._cycle * cycleDuration;
15797					if (this._yoyo) if ((this._cycle & 1) !== 0) {
15798						this._time = duration - this._time;
15799						yoyoEase = this._yoyoEase || this.vars.yoyoEase; //note: we don't set this._yoyoEase in _init() like we do other properties because it's TweenMax-specific and doing it here allows us to optimize performance (most tweens don't have a yoyoEase). Note that we also must skip the this.ratio calculation further down right after we _init() in this function, because we're doing it here.
15800						if (yoyoEase) {
15801							if (!this._yoyoEase) {
15802								if (yoyoEase === true && !this._initted) {
15803									//if it's not initted and yoyoEase is true, this._ease won't have been populated yet so we must discern it here.
15804									yoyoEase = this.vars.ease;
15805									this._yoyoEase = yoyoEase = !yoyoEase ? TweenLite.defaultEase : yoyoEase instanceof Ease ? yoyoEase : typeof yoyoEase === "function" ? new Ease(yoyoEase, this.vars.easeParams) : Ease.map[yoyoEase] || TweenLite.defaultEase;
15806								} else {
15807									this._yoyoEase = yoyoEase = yoyoEase === true ? this._ease : yoyoEase instanceof Ease ? yoyoEase : Ease.map[yoyoEase];
15808								}
15809							}
15810							this.ratio = yoyoEase ? 1 - yoyoEase.getRatio((duration - this._time) / duration) : 0;
15811						}
15812					}
15813					if (this._time > duration) {
15814						this._time = duration;
15815					} else if (this._time < 0) {
15816						this._time = 0;
15817					}
15818				}
15819
15820				if (this._easeType && !yoyoEase) {
15821					r = this._time / duration;
15822					type = this._easeType;
15823					pow = this._easePower;
15824					if (type === 1 || type === 3 && r >= 0.5) {
15825						r = 1 - r;
15826					}
15827					if (type === 3) {
15828						r *= 2;
15829					}
15830					if (pow === 1) {
15831						r *= r;
15832					} else if (pow === 2) {
15833						r *= r * r;
15834					} else if (pow === 3) {
15835						r *= r * r * r;
15836					} else if (pow === 4) {
15837						r *= r * r * r * r;
15838					}
15839
15840					if (type === 1) {
15841						this.ratio = 1 - r;
15842					} else if (type === 2) {
15843						this.ratio = r;
15844					} else if (this._time / duration < 0.5) {
15845						this.ratio = r / 2;
15846					} else {
15847						this.ratio = 1 - r / 2;
15848					}
15849				} else if (!yoyoEase) {
15850					this.ratio = this._ease.getRatio(this._time / duration);
15851				}
15852			}
15853
15854			if (prevTime === this._time && !force && prevCycle === this._cycle) {
15855				if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) {
15856					//so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
15857					this._callback("onUpdate");
15858				}
15859				return;
15860			} else if (!this._initted) {
15861				this._init();
15862				if (!this._initted || this._gc) {
15863					//immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that overwriting occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example.
15864					return;
15865				} else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) {
15866					//we stick it in the queue for rendering at the very end of the tick - this is a performance optimization because browsers invalidate styles and force a recalculation if you read, write, and then read style data (so it's better to read/read/read/write/write/write than read/write/read/write/read/write). The down side, of course, is that usually you WANT things to render immediately because you may have code running right after that which depends on the change. Like imagine running TweenLite.set(...) and then immediately after that, creating a nother tween that animates the same property to another value; the starting values of that 2nd tween wouldn't be accurate if lazy is true.
15867					this._time = prevTime;
15868					this._totalTime = prevTotalTime;
15869					this._rawPrevTime = prevRawPrevTime;
15870					this._cycle = prevCycle;
15871					TweenLiteInternals.lazyTweens.push(this);
15872					this._lazy = [time, suppressEvents];
15873					return;
15874				}
15875				//_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently.
15876				if (this._time && !isComplete && !yoyoEase) {
15877					this.ratio = this._ease.getRatio(this._time / duration);
15878				} else if (isComplete && this._ease._calcEnd && !yoyoEase) {
15879					this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1);
15880				}
15881			}
15882			if (this._lazy !== false) {
15883				this._lazy = false;
15884			}
15885
15886			if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
15887				this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
15888			}
15889			if (prevTotalTime === 0) {
15890				if (this._initted === 2 && time > 0) {
15891					//this.invalidate();
15892					this._init(); //will just apply overwriting since _initted of (2) means it was a from() tween that had immediateRender:true
15893				}
15894				if (this._startAt) {
15895					if (time >= 0) {
15896						this._startAt.render(time, true, force);
15897					} else if (!callback) {
15898						callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area.
15899					}
15900				}
15901				if (this.vars.onStart) if (this._totalTime !== 0 || duration === 0) if (!suppressEvents) {
15902					this._callback("onStart");
15903				}
15904			}
15905
15906			pt = this._firstPT;
15907			while (pt) {
15908				if (pt.f) {
15909					pt.t[pt.p](pt.c * this.ratio + pt.s);
15910				} else {
15911					pt.t[pt.p] = pt.c * this.ratio + pt.s;
15912				}
15913				pt = pt._next;
15914			}
15915
15916			if (this._onUpdate) {
15917				if (time < 0) if (this._startAt && this._startTime) {
15918					//if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
15919					this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete.
15920				}
15921				if (!suppressEvents) if (this._totalTime !== prevTotalTime || callback) {
15922					this._callback("onUpdate");
15923				}
15924			}
15925			if (this._cycle !== prevCycle) if (!suppressEvents) if (!this._gc) if (this.vars.onRepeat) {
15926				this._callback("onRepeat");
15927			}
15928			if (callback) if (!this._gc || force) {
15929				//check gc because there's a chance that kill() could be called in an onUpdate
15930				if (time < 0 && this._startAt && !this._onUpdate && this._startTime) {
15931					//if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
15932					this._startAt.render(time, true, force);
15933				}
15934				if (isComplete) {
15935					if (this._timeline.autoRemoveChildren) {
15936						this._enabled(false, false);
15937					}
15938					this._active = false;
15939				}
15940				if (!suppressEvents && this.vars[callback]) {
15941					this._callback(callback);
15942				}
15943				if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) {
15944					//the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon sce
15944nario, but possible nonetheless.
15945					this._rawPrevTime = 0;
15946				}
15947			}
15948		};
15949
15950		//---- STATIC FUNCTIONS -----------------------------------------------------------------------------------------------------------
15951
15952		TweenMax.to = function (target, duration, vars) {
15953			return new TweenMax(target, duration, vars);
15954		};
15955
15956		TweenMax.from = function (target, duration, vars) {
15957			vars.runBackwards = true;
15958			vars.immediateRender = vars.immediateRender != false;
15959			return new TweenMax(target, duration, vars);
15960		};
15961
15962		TweenMax.fromTo = function (target, duration, fromVars, toVars) {
15963			toVars.startAt = fromVars;
15964			toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
15965			return new TweenMax(target, duration, toVars);
15966		};
15967
15968		TweenMax.staggerTo = TweenMax.allTo = function (targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
15969			stagger = stagger || 0;
15970			var delay = 0,
15971			    a = [],
15972			    finalComplete = function () {
15973				if (vars.onComplete) {
15974					vars.onComplete.apply(vars.onCompleteScope || this, arguments);
15975				}
15976				onCompleteAll.apply(onCompleteAllScope || vars.callbackScope || this, onCompleteAllParams || _blankArray);
15977			},
15978			    cycle = vars.cycle,
15979			    fromCycle = vars.startAt && vars.startAt.cycle,
15980			    l,
15981			    copy,
15982			    i,
15983			    p;
15984			if (!_isArray(targets)) {
15985				if (typeof targets === "string") {
15986					targets = TweenLite.selector(targets) || targets;
15987				}
15988				if (_isSelector(targets)) {
15989					targets = _slice(targets);
15990				}
15991			}
15992			targets = targets || [];
15993			if (stagger < 0) {
15994				targets = _slice(targets);
15995				targets.reverse();
15996				stagger *= -1;
15997			}
15998			l = targets.length - 1;
15999			for (i = 0; i <= l; i++) {
16000				copy = {};
16001				for (p in vars) {
16002					copy[p] = vars[p];
16003				}
16004				if (cycle) {
16005					_applyCycle(copy, targets, i);
16006					if (copy.duration != null) {
16007						duration = copy.duration;
16008						delete copy.duration;
16009					}
16010				}
16011				if (fromCycle) {
16012					fromCycle = copy.startAt = {};
16013					for (p in vars.startAt) {
16014						fromCycle[p] = vars.startAt[p];
16015					}
16016					_applyCycle(copy.startAt, targets, i);
16017				}
16018				copy.delay = delay + (copy.delay || 0);
16019				if (i === l && onCompleteAll) {
16020					copy.onComplete = finalComplete;
16021				}
16022				a[i] = new TweenMax(targets[i], duration, copy);
16023				delay += stagger;
16024			}
16025			return a;
16026		};
16027
16028		TweenMax.staggerFrom = TweenMax.allFrom = function (targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
16029			vars.runBackwards = true;
16030			vars.immediateRender = vars.immediateRender != false;
16031			return TweenMax.staggerTo(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
16032		};
16033
16034		TweenMax.staggerFromTo = TweenMax.allFromTo = function (targets, duration, fromVars, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
16035			toVars.startAt = fromVars;
16036			toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
16037			return TweenMax.staggerTo(targets, duration, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
16038		};
16039
16040		TweenMax.delayedCall = function (delay, callback, params, scope, useFrames) {
16041			return new TweenMax(callback, 0, { delay: delay, onComplete: callback, onCompleteParams: params, callbackScope: scope, onReverseComplete: callback, onReverseCompleteParams: params, immediateRender: false, useFrames: useFrames, overwrite: 0 });
16042		};
16043
16044		TweenMax.set = function (target, vars) {
16045			return new TweenMax(target, 0, vars);
16046		};
16047
16048		TweenMax.isTweening = function (target) {
16049			return TweenLite.getTweensOf(target, true).length > 0;
16050		};
16051
16052		var _getChildrenOf = function (timeline, includeTimelines) {
16053			var a = [],
16054			    cnt = 0,
16055			    tween = timeline._first;
16056			while (tween) {
16057				if (tween instanceof TweenLite) {
16058					a[cnt++] = tween;
16059				} else {
16060					if (includeTimelines) {
16061						a[cnt++] = tween;
16062					}
16063					a = a.concat(_getChildrenOf(tween, includeTimelines));
16064					cnt = a.length;
16065				}
16066				tween = tween._next;
16067			}
16068			return a;
16069		},
16070		    getAllTweens = TweenMax.getAllTweens = function (includeTimelines) {
16071			return _getChildrenOf(Animation._rootTimeline, includeTimelines).concat(_getChildrenOf(Animation._rootFramesTimeline, includeTimelines));
16072		};
16073
16074		TweenMax.killAll = function (complete, tweens, delayedCalls, timelines) {
16075			if (tweens == null) {
16076				tweens = true;
16077			}
16078			if (delayedCalls == null) {
16079				delayedCalls = true;
16080			}
16081			var a = getAllTweens(timelines != false),
16082			    l = a.length,
16083			    allTrue = tweens && delayedCalls && timelines,
16084			    isDC,
16085			    tween,
16086			    i;
16087			for (i = 0; i < l; i++) {
16088				tween = a[i];
16089				if (allTrue || tween instanceof SimpleTimeline || (isDC = tween.target === tween.vars.onComplete) && delayedCalls || tweens && !isDC) {
16090					if (complete) {
16091						tween.totalTime(tween._reversed ? 0 : tween.totalDuration());
16092					} else {
16093						tween._enabled(false, false);
16094					}
16095				}
16096			}
16097		};
16098
16099		TweenMax.killChildTweensOf = function (parent, complete) {
16100			if (parent == null) {
16101				return;
16102			}
16103			var tl = TweenLiteInternals.tweenLookup,
16104			    a,
16105			    curParent,
16106			    p,
16107			    i,
16108			    l;
16109			if (typeof parent === "string") {
16110				parent = TweenLite.selector(parent) || parent;
16111			}
16112			if (_isSelector(parent)) {
16113				parent = _slice(parent);
16114			}
16115			if (_isArray(parent)) {
16116				i = parent.length;
16117				while (--i > -1) {
16118					TweenMax.killChildTweensOf(parent[i], complete);
16119				}
16120				return;
16121			}
16122			a = [];
16123			for (p in tl) {
16124				curParent = tl[p].target.parentNode;
16125				while (curParent) {
16126					if (curParent === parent) {
16127						a = a.concat(tl[p].tweens);
16128					}
16129					curParent = curParent.parentNode;
16130				}
16131			}
16132			l = a.length;
16133			for (i = 0; i < l; i++) {
16134				if (complete) {
16135					a[i].totalTime(a[i].totalDuration());
16136				}
16137				a[i]._enabled(false, false);
16138			}
16139		};
16140
16141		var _changePause = function (pause, tweens, delayedCalls, timelines) {
16142			tweens = tweens !== false;
16143			delayedCalls = delayedCalls !== false;
16144			timelines = timelines !== false;
16145			var a = getAllTweens(timelines),
16146			    allTrue = tweens && delayedCalls && timelines,
16147			    i = a.length,
16148			    isDC,
16149			    tween;
16150			while (--i > -1) {
16151				tween = a[i];
16152				if (allTrue || tween instanceof SimpleTimeline || (isDC = tween.target === tween.vars.onComplete) && delayedCalls || tweens && !isDC) {
16153					tween.paused(pause);
16154				}
16155			}
16156		};
16157
16158		TweenMax.pauseAll = function (tweens, delayedCalls, timelines) {
16159			_changePause(true, tweens, delayedCalls, timelines);
16160		};
16161
16162		TweenMax.resumeAll = function (tweens, delayedCalls, timelines) {
16163			_changePause(false, tweens, delayedCalls, timelines);
16164		};
16165
16166		TweenMax.globalTimeScale = function (value) {
16167			var tl = Animation._rootTimeline,
16168			    t = TweenLite.ticker.time;
16169			if (!arguments.length) {
16170				return tl._timeScale;
16171			}
16172			value = value || _tinyNum; //can't allow zero because it'll throw the math off
16173			tl._startTime = t - (t - tl._startTime) * tl._timeScale / value;
16174			tl = Animation._rootFramesTimeline;
16175			t = TweenLite.ticker.frame;
16176			tl._startTime = t - (t - tl._startTime) * tl._timeScale / value;
16177			tl._timeScale = Animation._rootTimeline._timeScale = value;
16178			return value;
16179		};
16180
16181		//---- GETTERS / SETTERS ----------------------------------------------------------------------------------------------------------
16182
16183		p.progress = function (value, suppressEvents) {
16184			return !arguments.length ? this._time / this.duration() : this.totalTime(this.duration() * (this._yoyo && (this._cycle & 1) !== 0 ? 1 - value : value) + this._cycle * (this._duration + this._repeatDelay), suppressEvents);
16185		};
16186
16187		p.totalProgress = function (value, suppressEvents) {
16188			return !arguments.length ? this._totalTime / this.totalDuration() : this.totalTime(this.totalDuration() * value, suppressEvents);
16189		};
16190
16191		p.time = function (value, suppressEvents) {
16192			if (!arguments.length) {
16193				return this._time;
16194			}
16195			if (this._dirty) {
16196				this.totalDuration();
16197			}
16198			if (value > this._duration) {
16199				value = this._duration;
16200			}
16201			if (this._yoyo && (this._cycle & 1) !== 0) {
16202				value = this._duration - value + this._cycle * (this._duration + this._repeatDelay);
16203			} else if (this._repeat !== 0) {
16204				value += this._cycle * (this._duration + this._repeatDelay);
16205			}
16206			return this.totalTime(value, suppressEvents);
16207		};
16208
16209		p.duration = function (value) {
16210			if (!arguments.length) {
16211				return this._duration; //don't set _dirty = false because there could be repeats that haven't been factored 
16211into the _totalDuration yet. Otherwise, if you create a repeated TweenMax and then immediately check its duration(), it would cache the value and the totalDuration would not be correct, thus repeats wouldn't take effect.
16212			}
16213			return Animation.prototype.duration.call(this, value);
16214		};
16215
16216		p.totalDuration = function (value) {
16217			if (!arguments.length) {
16218				if (this._dirty) {
16219					//instead of Infinity, we use 999999999999 so that we can accommodate reverses
16220					this._totalDuration = this._repeat === -1 ? 999999999999 : this._duration * (this._repeat + 1) + this._repeatDelay * this._repeat;
16221					this._dirty = false;
16222				}
16223				return this._totalDuration;
16224			}
16225			return this._repeat === -1 ? this : this.duration((value - this._repeat * this._repeatDelay) / (this._repeat + 1));
16226		};
16227
16228		p.repeat = function (value) {
16229			if (!arguments.length) {
16230				return this._repeat;
16231			}
16232			this._repeat = value;
16233			return this._uncache(true);
16234		};
16235
16236		p.repeatDelay = function (value) {
16237			if (!arguments.length) {
16238				return this._repeatDelay;
16239			}
16240			this._repeatDelay = value;
16241			return this._uncache(true);
16242		};
16243
16244		p.yoyo = function (value) {
16245			if (!arguments.length) {
16246				return this._yoyo;
16247			}
16248			this._yoyo = value;
16249			return this;
16250		};
16251
16252		return TweenMax;
16253	}, true);
16254
16255	/*
16256  * ----------------------------------------------------------------
16257  * TimelineLite
16258  * ----------------------------------------------------------------
16259  */
16260	_gsScope._gsDefine("TimelineLite", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) {
16261
16262		var TimelineLite = function (vars) {
16263			SimpleTimeline.call(this, vars);
16264			this._labels = {};
16265			this.autoRemoveChildren = this.vars.autoRemoveChildren === true;
16266			this.smoothChildTiming = this.vars.smoothChildTiming === true;
16267			this._sortChildren = true;
16268			this._onUpdate = this.vars.onUpdate;
16269			var v = this.vars,
16270			    val,
16271			    p;
16272			for (p in v) {
16273				val = v[p];
16274				if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) {
16275					v[p] = this._swapSelfInParams(val);
16276				}
16277			}
16278			if (_isArray(v.tweens)) {
16279				this.add(v.tweens, 0, v.align, v.stagger);
16280			}
16281		},
16282		    _tinyNum = 0.0000000001,
16283		    TweenLiteInternals = TweenLite._internals,
16284		    _internals = TimelineLite._internals = {},
16285		    _isSelector = TweenLiteInternals.isSelector,
16286		    _isArray = TweenLiteInternals.isArray,
16287		    _lazyTweens = TweenLiteInternals.lazyTweens,
16288		    _lazyRender = TweenLiteInternals.lazyRender,
16289		    _globals = _gsScope._gsDefine.globals,
16290		    _copy = function (vars) {
16291			var copy = {},
16292			    p;
16293			for (p in vars) {
16294				copy[p] = vars[p];
16295			}
16296			return copy;
16297		},
16298		    _applyCycle = function (vars, targets, i) {
16299			var alt = vars.cycle,
16300			    p,
16301			    val;
16302			for (p in alt) {
16303				val = alt[p];
16304				vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length];
16305			}
16306			delete vars.cycle;
16307		},
16308		    _pauseCallback = _internals.pauseCallback = function () {},
16309		    _slice = function (a) {
16310			//don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
16311			var b = [],
16312			    l = a.length,
16313			    i;
16314			for (i = 0; i !== l; b.push(a[i++]));
16315			return b;
16316		},
16317		    p = TimelineLite.prototype = new SimpleTimeline();
16318
16319		TimelineLite.version = "1.20.3";
16320		p.constructor = TimelineLite;
16321		p.kill()._gc = p._forcingPlayhead = p._hasPause = false;
16322
16323		/* might use later...
16324  //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales.
16325  function localToGlobal(time, animation) {
16326  	while (animation) {
16327  		time = (time / animation._timeScale) + animation._startTime;
16328  		animation = animation.timeline;
16329  	}
16330  	return time;
16331  }
16332  	//translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales
16333  function globalToLocal(time, animation) {
16334  	var scale = 1;
16335  	time -= localToGlobal(0, animation);
16336  	while (animation) {
16337  		scale *= animation._timeScale;
16338  		animation = animation.timeline;
16339  	}
16340  	return time * scale;
16341  }
16342  */
16343
16344		p.to = function (target, duration, vars, position) {
16345			var Engine = vars.repeat && _globals.TweenMax || TweenLite;
16346			return duration ? this.add(new Engine(target, duration, vars), position) : this.set(target, vars, position);
16347		};
16348
16349		p.from = function (target, duration, vars, position) {
16350			return this.add((vars.repeat && _globals.TweenMax || TweenLite).from(target, duration, vars), position);
16351		};
16352
16353		p.fromTo = function (target, duration, fromVars, toVars, position) {
16354			var Engine = toVars.repeat && _globals.TweenMax || TweenLite;
16355			return duration ? this.add(Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position);
16356		};
16357
16358		p.staggerTo = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
16359			var tl = new TimelineLite({ onComplete: onCompleteAll, onCompleteParams: onCompleteAllParams, callbackScope: onCompleteAllScope, smoothChildTiming: this.smoothChildTiming }),
16360			    cycle = vars.cycle,
16361			    copy,
16362			    i;
16363			if (typeof targets === "string") {
16364				targets = TweenLite.selector(targets) || targets;
16365			}
16366			targets = targets || [];
16367			if (_isSelector(targets)) {
16368				//senses if the targets object is a selector. If it is, we should translate it into an array.
16369				targets = _slice(targets);
16370			}
16371			stagger = stagger || 0;
16372			if (stagger < 0) {
16373				targets = _slice(targets);
16374				targets.reverse();
16375				stagger *= -1;
16376			}
16377			for (i = 0; i < targets.length; i++) {
16378				copy = _copy(vars);
16379				if (copy.startAt) {
16380					copy.startAt = _copy(copy.startAt);
16381					if (copy.startAt.cycle) {
16382						_applyCycle(copy.startAt, targets, i);
16383					}
16384				}
16385				if (cycle) {
16386					_applyCycle(copy, targets, i);
16387					if (copy.duration != null) {
16388						duration = copy.duration;
16389						delete copy.duration;
16390					}
16391				}
16392				tl.to(targets[i], duration, copy, i * stagger);
16393			}
16394			return this.add(tl, position);
16395		};
16396
16397		p.staggerFrom = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
16398			vars.immediateRender = vars.immediateRender != false;
16399			vars.runBackwards = true;
16400			return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
16401		};
16402
16403		p.staggerFromTo = function (targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
16404			toVars.startAt = fromVars;
16405			toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
16406			return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
16407		};
16408
16409		p.call = function (callback, params, scope, position) {
16410			return this.add(TweenLite.delayedCall(0, callback, params, scope), position);
16411		};
16412
16413		p.set = function (target, vars, position) {
16414			position = this._parseTimeOrLabel(position, 0, true);
16415			if (vars.immediateRender == null) {
16416				vars.immediateRender = position === this._time && !this._paused;
16417			}
16418			return this.add(new TweenLite(target, 0, vars), position);
16419		};
16420
16421		TimelineLite.exportRoot = function (vars, ignoreDelayedCalls) {
16422			vars = vars || {};
16423			if (vars.smoothChildTiming == null) {
16424				vars.smoothChildTiming = true;
16425			}
16426			var tl = new TimelineLite(vars),
16427			    root = tl._timeline,
16428			    hasNegativeStart,
16429			    time,
16430			    tween,
16431			    next;
16432			if (ignoreDelayedCalls == null) {
16433				ignoreDelayedCalls = true;
16434			}
16435			root._remove(tl, true);
16436			tl._startTime = 0;
16437			tl._rawPrevTime = tl._time = tl._totalTime = root._time;
16438			tween = root._first;
16439			while (tween) {
16440				next = tween._next;
16441				if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) {
16442					time = tween._startTime - tween._delay;
16443					if (time < 0) {
16444						hasNegativeStart = 1;
16445					}
16446					tl.add(tween, time);
16447				}
16448				tween = next;
16449			}
16450			root.add(tl, 0);
16451			if (hasNegativeStart) {
16452				//calling totalDuration() will force the adjustment necessary to shift the children forward so none of them start before zero, and moves the timeline backwards the same amount, so the playhead is still aligned where it should be globally, but the timeline doesn't have illegal children that start before zero.
16453				tl.totalDuration();
16454			}
16455			return tl;
16456		};
16457
16458		p.add = function (value, position, align, stagger) {
16459			var curTime, l, i, child, tl, beforeRawTime;
16460			if (typeof position !== "number") {
16461				position = this._parseTimeOrLabel(position, 0, true, value);
16462			}
16463			if (!(value instanceof Animation)) {
16464				if (value instanceof Array || value && value.push && _isArray(value)) {
16465					align = align || "normal";
16466					stagger = stagger || 0;
16467					curTime = position;
16468					l = value.length;
16469					for (i = 0; i < l; i++) {
16470						if (_isArray(child = value[i])) {
16471							child = new TimelineLite({ tweens: child });
16472						}
16473						this.add(child, curTime);
16474						if (typeof child !== "string" && typeof child !== "function") {
16475							if (align === "sequence") {
16476								curTime = child._startTime + child.totalDuration() / child._timeScale;
16477							} else if (align === "start") {
16478								child._startTime -= child.delay();
16479							}
16480						}
16481						curTime += stagger;
16482					}
16483					return this._uncache(true);
16484				} else if (typeof value === "string") {
16485					return this.addLabel(value, position);
16486				} else if (typeof value === "function") {
16487					value = TweenLite.delayedCall(0, value);
16488				} else {
16489					throw "Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string.";
16490				}
16491			}
16492
16493			SimpleTimeline.prototype.add.call(this, value, position);
16494
16495			if (value._time) {
16496				//in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning.
16497				value.render((this.rawTime() - value._startTime) * value._timeScale, false, false);
16498			}
16499
16500			//if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate.
16501			if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) {
16502				//in case any of the ancestors had completed but should now be enabled...
16503				tl = this;
16504				beforeRawTime = tl.rawTime() > value._startTime; //if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect.
16505				while (tl._timeline) {
16506					if (beforeRawTime && tl._timeline.smoothChildTiming) {
16507						tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it.
16508					} else if (tl._gc) {
16509						tl._enabled(true, false);
16510					}
16511					tl = tl._timeline;
16512				}
16513			}
16514
16515			return this;
16516		};
16517
16518		p.remove = function (value) {
16519			if (value instanceof Animation) {
16520				this._remove(value, false);
16521				var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline; //now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline.
16522				value._startTime = (value._paused ? value._pauseTime : tl._time) - (!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale; //ensure that if it gets played again, the timing is correct.
16523				return this;
16524			} else if (value instanceof Array || value && value.push && _isArray(value)) {
16525				var i = value.length;
16526				while (--i > -1) {
16527					this.remove(value[i]);
16528				}
16529				return this;
16530			} else if (typeof value === "string") {
16531				return this.removeLabel(value);
16532			}
16533			return this.kill(null, value);
16534		};
16535
16536		p._remove = function (tween, skipDisable) {
16537			SimpleTimeline.prototype._remove.call(this, tween, skipDisable);
16538			var last = this._last;
16539			if (!last) {
16540				this._time = this._totalTime = this._duration = this._totalDuration = 0;
16541			} else if (this._time > this.duration()) {
16542				this._time = this._duration;
16543				this._totalTime = this._totalDuration;
16544			}
16545			return this;
16546		};
16547
16548		p.append = function (value, offsetOrLabel) {
16549			return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value));
16550		};
16551
16552		p.insert = p.insertMultiple = function (value, position, align, stagger) {
16553			return this.add(value, position || 0, align, stagger);
16554		};
16555
16556		p.appendMultiple = function (tweens, offsetOrLabel, align, stagger) {
16557			return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger);
16558		};
16559
16560		p.addLabel = function (label, position) {
16561			this._labels[label] = this._parseTimeOrLabel(position);
16562			return this;
16563		};
16564
16565		p.addPause = function (position, callback, params, scope) {
16566			var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this);
16567			t.vars.onComplete = t.vars.onReverseComplete = callback;
16568			t.data = "isPause";
16569			this._hasPause = true;
16570			return this.add(t, position);
16571		};
16572
16573		p.removeLabel = function (label) {
16574			delete this._labels[label];
16575			return this;
16576		};
16577
16578		p.getLabelTime = function (label) {
16579			return this._labels[label] != null ? this._labels[label] : -1;
16580		};
16581
16582		p._parseTimeOrLabel = function (timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) {
16583			var clippedDuration, i;
16584			//if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration().
16585			if (ignore instanceof Animation && ignore.timeline === this) {
16586				this.remove(ignore);
16587			} else if (ignore && (ignore instanceof Array || ignore.push && _isArray(ignore))) {
16588				i = ignore.length;
16589				while (--i > -1) {
16590					if (ignore[i] instanceof Animation && ignore[i].timeline === this) {
16591						this.remove(ignore[i]);
16592					}
16593				}
16594			}
16595			clippedDuration = typeof timeOrLabel === "number" && !offsetOrLabel ? 0 : this.duration() > 99999999999 ? this.recent().endTime(false) : this._duration; //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead.
16596			if (typeof offsetOrLabel === "string") {
16597				return this._parseTimeOrLabel(offsetOrLabel, appendIfAbsent && typeof timeOrLabel === "number" && this._labels[offsetOrLabel] == null ? timeOrLabel - clippedDuration : 0, appendIfAbsent);
16598			}
16599			offsetOrLabel = offsetOrLabel || 0;
16600			if (typeof timeOrLabel === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) {
16601				//if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value).
16602				i = timeOrLabel.indexOf("=");
16603				if (i === -1) {
16604					if (this._labels[timeOrLabel] == null) {
16605						return appendIfAbsent ? this._labels[timeOrLabel] = clippedDuration + offsetOrLabel : offsetOrLabel;
16606					}
16607					return this._labels[timeOrLabel] + offsetOrLabel;
16608				}
16609				offsetOrLabel = parseInt(timeOrLabel.charAt(i - 1) + "1", 10) * Number(timeOrLabel.substr(i + 1));
16610				timeOrLabel = i > 1 ? this._parseTimeOrLabel(timeOrLabel.substr(0, i - 1), 0, appendIfAbsent) : clippedDuration;
16611			} else if (timeOrLabel == null) {
16612				timeOrLabel = clippedDuration;
16613			}
16614			return Number(timeOrLabel) + offsetOrLabel;
16615		};
16616
16617		p.seek = function (position, suppressEvents) {
16618			return this.totalTime(typeof position === "number" ? position : this._parseTimeOrLabel(position), suppressEvents !== false);
16619		};
16620
16621		p.stop = function () {
16622			return this.paused(true);
16623		};
16624
16625		p.gotoAndPlay = function (position, suppressEvents) {
16626			return this.play(position, suppressEvents);
16627		};
16628
16629		p.gotoAndStop = function (position, suppressEvents) {
16630			return this.pause(position, suppressEvents);
16631		};
16632
16633		p.render = function (time, suppressEvents, force) {
16634			if (this._gc) {
16635				this._enabled(true, false);
16636			}
16637			var prevTime = this._time,
16638			    totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
16639			    prevStart = this._startTime,
16640			    prevTimeScale = this._timeScale,
16641			    prevPaused = this._paused,
16642			    tween,
16643			    isComplete,
16644			    next,
16645			    callback,
16646			    internalForce,
16647			    pauseTween,
16648			    curTime;
16649			if (prevTime !== this._time) {
16650				//if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump).
16651				time += this._time - prevTime;
16652			}
16653			if (time >= totalDur - 0.0000001 && time >= 0) {
16654				//to work around occasional floating point math artifacts.
16655				this._totalTime = this._time = totalDur;
16656				if (!this._reversed) if (!this._hasPausedChild()) {
16657					isComplete = true;
16658					callback = "onComplete";
16659					internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
16660					if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) {
16661						internalForce = true;
16662						if (this._rawPrevTime > _tinyNum) {
16663							callback = "onReverseComplete";
16664						}
16665					}
16666				}
16667				this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
16668				time = totalDur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7.
16669			} else if (time < 0.0000001) {
16670				//to work around occasional floating point math artifacts, round super small values to 0.
16671				this._totalTime = this._time = 0;
16672				if (prevTime !== 0 || this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || time < 0 && this._rawPrevTime >= 0)) {
16673					callback = "onReverseComplete";
16674					isComplete = this._reversed;
16675				}
16676				if (time < 0) {
16677					this._active = false;
16678					if (this._timeline.autoRemoveChildren && this._reversed) {
16679						//ensures proper GC if a timeline is resumed after it's finished reversing.
16680						internalForce = isComplete = true;
16681						callback = "onReverseComplete";
16682					} else if (this._rawPrevTime >= 0 && this._first) {
16683						//when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
16684						internalForce = true;
16685					}
16686					this._rawPrevTime = time;
16687				} else {
16688					this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
16689					if (time === 0 && isComplete) {
16690						//if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
16691						tween = this._first;
16692						while (tween && tween._startTime === 0) {
16693							if (!tween._duration) {
16694								isComplete = false;
16695							}
16696							tween = tween._next;
16697						}
16698					}
16699					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
16700					if (!this._initted) {
16701						internalForce = true;
16702					}
16703				}
16704			} else {
16705
16706				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
16707					if (time >= prevTime) {
16708						tween = this._first;
16709						while (tween && tween._startTime <= time && !pauseTween) {
16710							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
16711								pauseTween = tween;
16712							}
16713							tween = tween._next;
16714						}
16715					} else {
16716						tween = this._last;
16717						while (tween && tween._startTime >= time && !pauseTween) {
16718							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
16719								pauseTween = tween;
16720							}
16721							tween = tween._prev;
16722						}
16723					}
16724					if (pauseTween) {
16725						this._time = time = pauseTween._startTime;
16726						this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay);
16727					}
16728				}
16729
16730				this._totalTime = this._time = this._rawPrevTime = time;
16731			}
16732			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
16733				return;
16734			} else if (!this._initted) {
16735				this._initted = true;
16736			}
16737
16738			if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) {
16739				this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
16740			}
16741
16742			if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) {
16743				this._callback("onStart");
16744			}
16745
16746			curTime = this._time;
16747			if (curTime >= prevTime) {
16748				tween = this._first;
16749				while (tween) {
16750					next = tween._next; //record it here because the value could change after rendering...
16751					if (curTime !== this._time || this._paused && !prevPaused) {
16752						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
16753						break;
16754					} else if (tween._active || tween._startTime <= curTime && !tween._paused && !tween._gc) {
16755						if (pauseTween === tween) {
16756							this.pause();
16757						}
16758						if (!tween._reversed) {
16759							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
16760						} else {
16761							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
16762						}
16763					}
16764					tween = next;
16765				}
16766			} else {
16767				tween = this._last;
16768				while (tween) {
16769					next = tween._prev; //record it here because the value could change after rendering...
16770					if (curTime !== this._time || this._paused && !prevPaused) {
16771						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
16772						break;
16773					} else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) {
16774						if (pauseTween === tween) {
16775							pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
16776							while (pauseTween && pauseTween.endTime() > this._time) {
16777								pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force);
16778								pauseTween = pauseTween._prev;
16779							}
16780							pauseTween = null;
16781							this.pause();
16782						}
16783						if (!tween._reversed) {
16784							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
16785						} else {
16786							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
16787						}
16788					}
16789					tween = next;
16790				}
16791			}
16792
16793			if (this._onUpdate) if (!suppressEvents) {
16794				if (_lazyTweens.length) {
16795					//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
16796					_lazyRender();
16797				}
16798				this._callback("onUpdate");
16799			}
16800
16801			if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) {
16802				//if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
16803				if (isComplete) {
16804					if (_lazyTweens.length) {
16805						//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
16806						_lazyRender();
16807					}
16808					if (this._timeline.autoRemoveChildren) {
16809						this._enabled(false, false);
16810					}
16811					this._active = false;
16812				}
16813				if (!suppressEvents && this.vars[callback]) {
16814					this._callback(callback);
16815				}
16816			}
16817		};
16818
16819		p._hasPausedChild = function () {
16820			var tween = this._first;
16821			while (tween) {
16822				if (tween._paused || tween instanceof TimelineLite && tween._hasPausedChild()) {
16823					return true;
16824				}
16825				tween = tween._next;
16826			}
16827			return false;
16828		};
16829
16830		p.getChildren = function (nested, tweens, timelines, ignoreBeforeTime) {
16831			ignoreBeforeTime = ignoreBeforeTime || -9999999999;
16832			var a = [],
16833			    tween = this._first,
16834			    cnt = 0;
16835			while (tween) {
16836				if (tween._startTime < ignoreBeforeTime) {
16837					//do nothing
16838				} else if (tween instanceof TweenLite) {
16839					if (tweens !== false) {
16840						a[cnt++] = tween;
16841					}
16842				} else {
16843					if (timelines !== false) {
16844						a[cnt++] = tween;
16845					}
16846					if (nested !== false) {
16847						a = a.concat(tween.getChildren(true, tweens, timelines));
16848						cnt = a.length;
16849					}
16850				}
16851				tween = tween._next;
16852			}
16853			return a;
16854		};
16855
16856		p.getTweensOf = function (target, nested) {
16857			var disabled = this._gc,
16858			    a = [],
16859			    cnt = 0,
16860			    tweens,
16861			    i;
16862			if (disabled) {
16863				this._enabled(true, true); //getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here.
16864			}
16865			tweens = TweenLite.getTweensOf(target);
16866			i = tweens.length;
16867			while (--i > -1) {
16868				if (tweens[i].timeline === this || nested && this._contains(tweens[i])) {
16869					a[cnt++] = tweens[i];
16870				}
16871			}
16872			if (disabled) {
16873				this._enabled(false, true);
16874			}
16875			return a;
16876		};
16877
16878		p.recent = function () {
16879			return this._recent;
16880		};
16881
16882		p._contains = function (tween) {
16883			var tl = tween.timeline;
16884			while (tl) {
16885				if (tl === this) {
16886					return true;
16887				}
16888				tl = tl.timeline;
16889			}
16890			return false;
16891		};
16892
16893		p.shiftChildren = function (amount, adjustLabels, ignoreBeforeTime) {
16894			ignoreBeforeTime = ignoreBeforeTime || 0;
16895			var tween = this._first,
16896			    labels = this._labels,
16897			    p;
16898			while (tween) {
16899				if (tween._startTime >= ignoreBeforeTime) {
16900					tween._startTime += amount;
16901				}
16902				tween = tween._next;
16903			}
16904			if (adjustLabels) {
16905				for (p in labels) {
16906					if (labels[p] >= ignoreBeforeTime) {
16907						labels[p] += amount;
16908					}
16909				}
16910			}
16911			return this._uncache(true);
16912		};
16913
16914		p._kill = function (vars, target) {
16915			if (!vars && !target) {
16916				return this._enabled(false, false);
16917			}
16918			var tweens = !target ? this.getChildren(true, true, false) : this.getTweensOf(target),
16919			    i = tweens.length,
16920			    changed = false;
16921			while (--i > -1) {
16922				if (tweens[i]._kill(vars, target)) {
16923					changed = true;
16924				}
16925			}
16926			return changed;
16927		};
16928
16929		p.clear = function (labels) {
16930			var tweens = this.getChildren(false, true, true),
16931			    i = tweens.length;
16932			this._time = this._totalTime = 0;
16933			while (--i > -1) {
16934				tweens[i]._enabled(false, false);
16935			}
16936			if (labels !== false) {
16937				this._labels = {};
16938			}
16939			return this._uncache(true);
16940		};
16941
16942		p.invalidate = function () {
16943			var tween = this._first;
16944			while (tween) {
16945				tween.invalidate();
16946				tween = tween._next;
16947			}
16948			return Animation.prototype.invalidate.call(this);;
16949		};
16950
16951		p._enabled = function (enabled, ignoreTimeline) {
16952			if (enabled === this._gc) {
16953				var tween = this._first;
16954				while (tween) {
16955					tween._enabled(enabled, true);
16956					tween = tween._next;
16957				}
16958			}
16959			return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline);
16960		};
16961
16962		p.totalTime = function (time, suppressEvents, uncapped) {
16963			this._forcingPlayhead = true;
16964			var val = Animation.prototype.totalTime.apply(this, arguments);
16965			this._forcingPlayhead = false;
16966			return val;
16967		};
16968
16969		p.duration = function (value) {
16970			if (!arguments.length) {
16971				if (this._dirty) {
16972					this.totalDuration(); //just triggers recalculation
16973				}
16974				return this._duration;
16975			}
16976			if (this.duration() !== 0 && value !== 0) {
16977				this.timeScale(this._duration / value);
16978			}
16979			return this;
16980		};
16981
16982		p.totalDuration = function (value) {
16983			if (!arguments.length) {
16984				if (this._dirty) {
16985					var max = 0,
16986					    tween = this._last,
16987					    prevStart = 999999999999,
16988					    prev,
16989					    end;
16990					while (tween) {
16991						prev = tween._prev; //record it here in case the tween changes position in the sequence...
16992						if (tween._dirty) {
16993							tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it.
16994						}
16995						if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) {
16996							//in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence
16997							this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel().
16998							this.add(tween, tween._startTime - tween._delay);
16999							this._calculatingDuration = 0;
17000						} else {
17001							prevStart = tween._startTime;
17002						}
17003						if (tween._startTime < 0 && !tween._paused) {
17004							//children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.
17005							max -= tween._startTime;
17006							if (this._timeline.smoothChildTiming) {
17007								this._startTime += tween._startTime / this._timeScale;
17008								this._time -= tween._startTime;
17009								this._totalTime -= tween._startTime;
17010								this._rawPrevTime -= tween._startTime;
17011							}
17012							this.shiftChildren(-tween._startTime, false, -9999999999);
17013							prevStart = 0;
17014						}
17015						end = tween._startTime + tween._totalDuration / tween._timeScale;
17016						if (end > max) {
17017							max = end;
17018						}
17019						tween = prev;
17020					}
17021					this._duration = this._totalDuration = max;
17022					this._dirty = false;
17023				}
17024				return this._totalDuration;
17025			}
17026			return value && this.totalDuration() ? this.timeScale(this._totalDuration / value) : this;
17027		};
17028
17029		p.paused = function (value) {
17030			if (!value) {
17031				//if there's a pause directly at the spot from where we're unpausing, skip it.
17032				var tween = this._first,
17033				    time = this._time;
17034				while (tween) {
17035					if (tween._startTime === time && tween.data === "isPause") {
17036						tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire.
17037					}
17038					tween = tween._next;
17039				}
17040			}
17041			return Animation.prototype.paused.apply(this, arguments);
17042		};
17043
17044		p.usesFrames = function () {
17045			var tl = this._timeline;
17046			while (tl._timeline) {
17047				tl = tl._timeline;
17048			}
17049			return tl === Animation._rootFramesTimeline;
17050		};
17051
17052		p.rawTime = function (wrapRepeats) {
17053			return wrapRepeats && (this._paused || this._repeat && this.time() > 0 && this.totalProgress() < 1) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale;
17054		};
17055
17056		return TimelineLite;
17057	}, true);
17058
17059	/*
17060  * ----------------------------------------------------------------
17061  * TimelineMax
17062  * ----------------------------------------------------------------
17063  */
17064	_gsScope._gsDefine("TimelineMax", ["TimelineLite", "TweenLite", "easing.Ease"], function (TimelineLite, TweenLite, Ease) {
17065
17066		var TimelineMax = function (vars) {
17067			TimelineLite.call(this, vars);
17068			this._repeat = this.vars.repeat || 0;
17069			this._repeatDelay = this.vars.repeatDelay || 0;
17070			this._cycle = 0;
17071			this._yoyo = this.vars.yoyo === true;
17072			this._dirty = true;
17073		},
17074		    _tinyNum = 0.0000000001,
17075		    TweenLiteInternals = TweenLite._internals,
17076		    _lazyTweens = TweenLiteInternals.lazyTweens,
17077		    _lazyRender = TweenLiteInternals.lazyRender,
17078		    _globals = _gsScope._gsDefine.globals,
17079		    _easeNone = new Ease(null, null, 1, 0),
17080		    p = TimelineMax.prototype = new TimelineLite();
17081
17082		p.constructor = TimelineMax;
17083		p.kill()._gc = false;
17084		TimelineMax.version = "1.20.3";
17085
17086		p.invalidate = function () {
17087			this._yoyo = this.vars.yoyo === true;
17088			this._repeat = this.vars.repeat || 0;
17089			this._repeatDelay = this.vars.repeatDelay || 0;
17090			this._uncache(true);
17091			return TimelineLite.prototype.invalidate.call(this);
17092		};
17093
17094		p.addCallback = function (callback, position, params, scope) {
17095			return this.add(TweenLite.delayedCall(0, callback, params, scope), position);
17096		};
17097
17098		p.removeCallback = function (callback, position) {
17099			if (callback) {
17100				if (position == null) {
17101					this._kill(null, callback);
17102				} else {
17103					var a = this.getTweensOf(callback, false),
17104					    i = a.length,
17105					    time = this._parseTimeOrLabel(position);
17106					while (--i > -1) {
17107						if (a[i]._startTime === time) {
17108							a[i]._enabled(false, false);
17109						}
17110					}
17111				}
17112			}
17113			return this;
17114		};
17115
17116		p.removePause = function (position) {
17117			return this.removeCallback(TimelineLite._internals.pauseCallback, position);
17118		};
17119
17120		p.tweenTo = function (position, vars) {
17121			vars = vars || {};
17122			var copy = { ease: _easeNone, useFrames: this.usesFrames(), immediateRender: false },
17123			    Engine = vars.repeat && _globals.TweenMax || TweenLite,
17124			    duration,
17125			    p,
17126			    t;
17127			for (p in vars) {
17128				copy[p] = vars[p];
17129			}
17130			copy.time = this._parseTimeOrLabel(position);
17131			duration = Math.abs(Number(copy.time) - this._time) / this._timeScale || 0.001;
17132			t = new Engine(this, duration, copy);
17133			copy.onStart = function () {
17134				t.target.paused(true);
17135				if (t.vars.time !== t.target.time() && duration === t.duration()) {
17136					//don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all.
17137					t.duration(Math.abs(t.vars.time - t.target.time()) / t.target._timeScale);
17138				}
17139				if (vars.onStart) {
17140					//in case the user had an onStart in the vars - we don't want to overwrite it.
17141					vars.onStart.apply(vars.onStartScope || vars.callbackScope || t, vars.onStartParams || []); //don't use t._callback("onStart") or it'll point to the copy.onStart and we'll get a recursion error.
17142				}
17143			};
17144			return t;
17145		};
17146
17147		p.tweenFromTo = function (fromPosition, toPosition, vars) {
17148			vars = vars || {};
17149			fromPosition = this._parseTimeOrLabel(fromPosition);
17150			vars.startAt = { onComplete: this.seek, onCompleteParams: [fromPosition], callbackScope: this };
17151			vars.immediateRender = vars.immediateRender !== false;
17152			var t = this.tweenTo(toPosition, vars);
17153			return t.duration(Math.abs(t.vars.time - fromPosition) / this._timeScale || 0.001);
17154		};
17155
17156		p.render = function (time, suppressEvents, force) {
17157			if (this._gc) {
17158				this._enabled(true, false);
17159			}
17160			var prevTime = this._time,
17161			    totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
17162			    dur = this._duration,
17163			    prevTotalTime = this._totalTime,
17164			    prevStart = this._startTime,
17165			    prevTimeScale = this._timeScale,
17166			    prevRawPrevTime = this._rawPrevTime,
17167			    prevPaused = this._paused,
17168			    prevCycle = this._cycle,
17169			    tween,
17170			    isComplete,
17171			    next,
17172			    callback,
17173			    internalForce,
17174			    cycleDuration,
17175			    pauseTween,
17176			    curTime;
17177			if (prevTime !== this._time) {
17178				//if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump).
17179				time += this._time - prevTime;
17180			}
17181			if (time >= totalDur - 0.0000001 && time >= 0) {
17182				//to work around occasional floating point math artifacts.
17183				if (!this._locked) {
17184					this._totalTime = totalDur;
17185					this._cycle = this._repeat;
17186				}
17187				if (!this._reversed) if (!this._hasPausedChild()) {
17188					isComplete = true;
17189					callback = "onComplete";
17190					internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
17191					if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && this._first) {
17192						internalForce = true;
17193						if (prevRawPrevTime > _tinyNum) {
17194							callback = "onReverseComplete";
17195						}
17196					}
17197				}
17198				this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
17199				if (this._yoyo && (this._cycle & 1) !== 0) {
17200					this._time = time = 0;
17201				} else {
17202					this._time = dur;
17203					time = dur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. We cannot do less then 0.0001 because the same issue can occur when the duration is extremely large like 999999999999 in 
17203which case adding 0.00000001, for example, causes it to act like nothing was added.
17204				}
17205			} else if (time < 0.0000001) {
17206				//to work around occasional floating point math artifacts, round super small values to 0.
17207				if (!this._locked) {
17208					this._totalTime = this._cycle = 0;
17209				}
17210				this._time = 0;
17211				if (prevTime !== 0 || dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || time < 0 && prevRawPrevTime >= 0) && !this._locked) {
17212					//edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare)
17213					callback = "onReverseComplete";
17214					isComplete = this._reversed;
17215				}
17216				if (time < 0) {
17217					this._active = false;
17218					if (this._timeline.autoRemoveChildren && this._reversed) {
17219						internalForce = isComplete = true;
17220						callback = "onReverseComplete";
17221					} else if (prevRawPrevTime >= 0 && this._first) {
17222						//when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
17223						internalForce = true;
17224					}
17225					this._rawPrevTime = time;
17226				} else {
17227					this._rawPrevTime = dur || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
17228					if (time === 0 && isComplete) {
17229						//if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
17230						tween = this._first;
17231						while (tween && tween._startTime === 0) {
17232							if (!tween._duration) {
17233								isComplete = false;
17234							}
17235							tween = tween._next;
17236						}
17237					}
17238					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
17239					if (!this._initted) {
17240						internalForce = true;
17241					}
17242				}
17243			} else {
17244				if (dur === 0 && prevRawPrevTime < 0) {
17245					//without this, zero-duration repeating timelines (like with a simple callback nested at the very beginning and a repeatDelay) wouldn't render the first time through.
17246					internalForce = true;
17247				}
17248				this._time = this._rawPrevTime = time;
17249				if (!this._locked) {
17250					this._totalTime = time;
17251					if (this._repeat !== 0) {
17252						cycleDuration = dur + this._repeatDelay;
17253						this._cycle = this._totalTime / cycleDuration >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but it gets reported as 0.79999999!)
17254						if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
17255							this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
17256						}
17257						this._time = this._totalTime - this._cycle * cycleDuration;
17258						if (this._yoyo) if ((this._cycle & 1) !== 0) {
17259							this._time = dur - this._time;
17260						}
17261						if (this._time > dur) {
17262							this._time = dur;
17263							time = dur + 0.0001; //to avoid occasional floating point rounding error
17264						} else if (this._time < 0) {
17265							this._time = time = 0;
17266						} else {
17267							time = this._time;
17268						}
17269					}
17270				}
17271
17272				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
17273					time = this._time;
17274					if (time >= prevTime || this._repeat && prevCycle !== this._cycle) {
17275						tween = this._first;
17276						while (tween && tween._startTime <= time && !pauseTween) {
17277							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
17278								pauseTween = tween;
17279							}
17280							tween = tween._next;
17281						}
17282					} else {
17283						tween = this._last;
17284						while (tween && tween._startTime >= time && !pauseTween) {
17285							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
17286								pauseTween = tween;
17287							}
17288							tween = tween._prev;
17289						}
17290					}
17291					if (pauseTween && pauseTween._startTime < dur) {
17292						this._time = time = pauseTween._startTime;
17293						this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay);
17294					}
17295				}
17296			}
17297
17298			if (this._cycle !== prevCycle) if (!this._locked) {
17299				/*
17300    make sure children at the end/beginning of the timeline are rendered properly. If, for example,
17301    a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
17302    would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there
17303    could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So
17304    we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must
17305    ensure that zero-duration tweens at the very beginning or end of the TimelineMax work.
17306    */
17307				var backwards = this._yoyo && (prevCycle & 1) !== 0,
17308				    wrap = backwards === (this._yoyo && (this._cycle & 1) !== 0),
17309				    recTotalTime = this._totalTime,
17310				    recCycle = this._cycle,
17311				    recRawPrevTime = this._rawPrevTime,
17312				    recTime = this._time;
17313
17314				this._totalTime = prevCycle * dur;
17315				if (this._cycle < prevCycle) {
17316					backwards = !backwards;
17317				} else {
17318					this._totalTime += dur;
17319				}
17320				this._time = prevTime; //temporarily revert _time so that render() renders the children in the correct order. Without this, tweens won't rewind correctly. We could arhictect things in a "cleaner" way by splitting out the rendering queue into a separate method but for performance reasons, we kept it all inside this method.
17321
17322				this._rawPrevTime = dur === 0 ? prevRawPrevTime - 0.0001 : prevRawPrevTime;
17323				this._cycle = prevCycle;
17324				this._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render()
17325				prevTime = backwards ? 0 : dur;
17326				this.render(prevTime, suppressEvents, dur === 0);
17327				if (!suppressEvents) if (!this._gc) {
17328					if (this.vars.onRepeat) {
17329						this._cycle = recCycle; //in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle.
17330						this._locked = false;
17331						this._callback("onRepeat");
17332					}
17333				}
17334				if (prevTime !== this._time) {
17335					//in case there's a callback like onComplete in a nested tween/timeline that changes the playhead position, like via seek(), we should just abort.
17336					return;
17337				}
17338				if (wrap) {
17339					this._cycle = prevCycle; //if there's an onRepeat, we reverted this above, so make sure it's set properly again. We also unlocked in that scenario, so reset that too.
17340					this._locked = true;
17341					prevTime = backwards ? dur + 0.0001 : -0.0001;
17342					this.render(prevTime, true, false);
17343				}
17344				this._locked = false;
17345				if (this._paused && !prevPaused) {
17346					//if the render() triggered callback that paused this timeline, we should abort (very rare, but possible)
17347					return;
17348				}
17349				this._time = recTime;
17350				this._totalTime = recTotalTime;
17351				this._cycle = recCycle;
17352				this._rawPrevTime = recRawPrevTime;
17353			}
17354
17355			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
17356				if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) {
17357					//so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
17358					this._callback("onUpdate");
17359				}
17360				return;
17361			} else if (!this._initted) {
17362				this._initted = true;
17363			}
17364
17365			if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) {
17366				this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
17367			}
17368
17369			if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0 || !this._totalDuration) if (!suppressEvents) {
17370				this._callback("onStart");
17371			}
17372
17373			curTime = this._time;
17374			if (curTime >= prevTime) {
17375				tween = this._first;
17376				while (tween) {
17377					next = tween._next; //record it here because the value could change after rendering...
17378					if (curTime !== this._time || this._paused && !prevPaused) {
17379						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
17380						break;
17381					} else if (tween._active || tween._startTime <= this._time && !tween._paused && !tween._gc) {
17382						if (pauseTween === tween) {
17383							this.pause();
17384						}
17385						if (!tween._reversed) {
17386							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
17387						} else {
17388							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
17389						}
17390					}
17391					tween = next;
17392				}
17393			} else {
17394				tween = this._last;
17395				while (tween) {
17396					next = tween._prev; //record it here because the value could change after rendering...
17397					if (curTime !== this._time || this._paused && !prevPaused) {
17398						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
17399						break;
17400					} else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) {
17401						if (pauseTween === tween) {
17402							pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
17403							while (pauseTween && pauseTween.endTime() > this._time) {
17404								pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force);
17405								pauseTween = pauseTween._prev;
17406							}
17407							pauseTween = null;
17408							this.pause();
17409						}
17410						if (!tween._reversed) {
17411							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
17412						} else {
17413							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
17414						}
17415					}
17416					tween = next;
17417				}
17418			}
17419
17420			if (this._onUpdate) if (!suppressEvents) {
17421				if (_lazyTweens.length) {
17422					//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
17423					_lazyRender();
17424				}
17425				this._callback("onUpdate");
17426			}
17427			if (callback) if (!this._locked) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) {
17428				//if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
17429				if (isComplete) {
17430					if (_lazyTweens.length) {
17431						//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
17432						_lazyRender();
17433					}
17434					if (this._timeline.autoRemoveChildren) {
17435						this._enabled(false, false);
17436					}
17437					this._active = false;
17438				}
17439				if (!suppressEvents && this.vars[callback]) {
17440					this._callback(callback);
17441				}
17442			}
17443		};
17444
17445		p.getActive = function (nested, tweens, timelines) {
17446			if (nested == null) {
17447				nested = true;
17448			}
17449			if (tweens == null) {
17450				tweens = true;
17451			}
17452			if (timelines == null) {
17453				timelines = false;
17454			}
17455			var a = [],
17456			    all = this.getChildren(nested, tweens, timelines),
17457			    cnt = 0,
17458			    l = all.length,
17459			    i,
17460			    tween;
17461			for (i = 0; i < l; i++) {
17462				tween = all[i];
17463				if (tween.isActive()) {
17464					a[cnt++] = tween;
17465				}
17466			}
17467			return a;
17468		};
17469
17470		p.getLabelAfter = function (time) {
17471			if (!time) if (time !== 0) {
17472				//faster than isNan()
17473				time = this._time;
17474			}
17475			var labels = this.getLabelsArray(),
17476			    l = labels.length,
17477			    i;
17478			for (i = 0; i < l; i++) {
17479				if (labels[i].time > time) {
17480					return labels[i].name;
17481				}
17482			}
17483			return null;
17484		};
17485
17486		p.getLabelBefore = function (time) {
17487			if (time == null) {
17488				time = this._time;
17489			}
17490			var labels = this.getLabelsArray(),
17491			    i = labels.length;
17492			while (--i > -1) {
17493				if (labels[i].time < time) {
17494					return labels[i].name;
17495				}
17496			}
17497			return null;
17498		};
17499
17500		p.getLabelsArray = function () {
17501			var a = [],
17502			    cnt = 0,
17503			    p;
17504			for (p in this._labels) {
17505				a[cnt++] = { time: this._labels[p], name: p };
17506			}
17507			a.sort(function (a, b) {
17508				return a.time - b.time;
17509			});
17510			return a;
17511		};
17512
17513		p.invalidate = function () {
17514			this._locked = false; //unlock and set cycle in case invalidate() is called from inside an onRepeat
17515			return TimelineLite.prototype.invalidate.call(this);
17516		};
17517
17518		//---- GETTERS / SETTERS -------------------------------------------------------------------------------------------------------
17519
17520		p.progress = function (value, suppressEvents) {
17521			return !arguments.length ? this._time / this.duration() || 0 : this.totalTime(this.duration() * (this._yoyo && (this._cycle & 1) !== 0 ? 1 - value : value) + this._cycle * (this._duration + this._repeatDelay), suppressEvents);
17522		};
17523
17524		p.totalProgress = function (value, suppressEvents) {
17525			return !arguments.length ? this._totalTime / this.totalDuration() || 0 : this.totalTime(this.totalDuration() * value, suppressEvents);
17526		};
17527
17528		p.totalDuration = function (value) {
17529			if (!arguments.length) {
17530				if (this._dirty) {
17531					TimelineLite.prototype.totalDuration.call(this); //just forces refresh
17532					//Instead of Infinity, we use 999999999999 so that we can accommodate reverses.
17533					this._totalDuration = this._repeat === -1 ? 999999999999 : this._duration * (this._repeat + 1) + this._repeatDelay * this._repeat;
17534				}
17535				return this._totalDuration;
17536			}
17537			return this._repeat === -1 || !value ? this : this.timeScale(this.totalDuration() / value);
17538		};
17539
17540		p.time = function (value, suppressEvents) {
17541			if (!arguments.length) {
17542				return this._time;
17543			}
17544			if (this._dirty) {
17545				this.totalDuration();
17546			}
17547			if (value > this._duration) {
17548				value = this._duration;
17549			}
17550			if (this._yoyo && (this._cycle & 1) !== 0) {
17551				value = this._duration - value + this._cycle * (this._duration + this._repeatDelay);
17552			} else if (this._repeat !== 0) {
17553				value += this._cycle * (this._duration + this._repeatDelay);
17554			}
17555			return this.totalTime(value, suppressEvents);
17556		};
17557
17558		p.repeat = function (value) {
17559			if (!arguments.length) {
17560				return this._repeat;
17561			}
17562			this._repeat = value;
17563			return this._uncache(true);
17564		};
17565
17566		p.repeatDelay = function (value) {
17567			if (!arguments.length) {
17568				return this._repeatDelay;
17569			}
17570			this._repeatDelay = value;
17571			return this._uncache(true);
17572		};
17573
17574		p.yoyo = function (value) {
17575			if (!arguments.length) {
17576				return this._yoyo;
17577			}
17578			this._yoyo = value;
17579			return this;
17580		};
17581
17582		p.currentLabel = function (value) {
17583			if (!arguments.length) {
17584				return this.getLabelBefore(this._time + 0.00000001);
17585			}
17586			return this.seek(value, true);
17587		};
17588
17589		return TimelineMax;
17590	}, true);
17591
17592	/*
17593  * ----------------------------------------------------------------
17594  * BezierPlugin
17595  * ----------------------------------------------------------------
17596  */
17597	(function () {
17598
17599		var _RAD2DEG = 180 / Math.PI,
17600		    _r1 = [],
17601		    _r2 = [],
17602		    _r3 = [],
17603		    _corProps = {},
17604		    _globals = _gsScope._gsDefine.globals,
17605		    Segment = function (a, b, c, d) {
17606			if (c === d) {
17607				//if c and d match, the final autoRotate value could lock at -90 degrees, so differentiate them slightly.
17608				c = d - (d - b) / 1000000;
17609			}
17610			if (a === b) {
17611				//if a and b match, the starting autoRotate value could lock at -90 degrees, so differentiate them slightly.
17612				b = a + (c - a) / 1000000;
17613			}
17614			this.a = a;
17615			this.b = b;
17616			this.c = c;
17617			this.d = d;
17618			this.da = d - a;
17619			this.ca = c - a;
17620			this.ba = b - a;
17621		},
17622		    _correlate = ",x,y,z,left,top,right,bottom,marginTop,marginLeft,marginRight,marginBottom,paddingLeft,paddingTop,paddingRight,paddingBottom,backgroundPosition,backgroundPosition_y,",
17623		    cubicToQuadratic = function (a, b, c, d) {
17624			var q1 = { a: a },
17625			    q2 = {},
17626			    q3 = {},
17627			    q4 = { c: d },
17628			    mab = (a + b) / 2,
17629			    mbc = (b + c) / 2,
17630			    mcd = (c + d) / 2,
17631			    mabc = (mab + mbc) / 2,
17632			    mbcd = (mbc + mcd) / 2,
17633			    m8 = (mbcd - mabc) / 8;
17634			q1.b = mab + (a - mab) / 4;
17635			q2.b = mabc + m8;
17636			q1.c = q2.a = (q1.b + q2.b) / 2;
17637			q2.c = q3.a = (mabc + mbcd) / 2;
17638			q3.b = mbcd - m8;
17639			q4.b = mcd + (d - mcd) / 4;
17640			q3.c = q4.a = (q3.b + q4.b) / 2;
17641			return [q1, q2, q3, q4];
17642		},
17643		    _calculateControlPoints = function (a, curviness, quad, basic, correlate) {
17644			var l = a.length - 1,
17645			    ii = 0,
17646			    cp1 = a[0].a,
17647			    i,
17648			    p1,
17649			    p2,
17650			    p3,
17651			    seg,
17652			    m1,
17653			    m2,
17654			    mm,
17655			    cp2,
17656			    qb,
17657			    r1,
17658			    r2,
17659			    tl;
17660			for (i = 0; i < l; i++) {
17661				seg = a[ii];
17662				p1 = seg.a;
17663				p2 = seg.d;
17664				p3 = a[ii + 1].d;
17665
17666				if (correlate) {
17667					r1 = _r1[i];
17668					r2 = _r2[i];
17669					tl = (r2 + r1) * curviness * 0.25 / (basic ? 0.5 : _r3[i] || 0.5);
17670					m1 = p2 - (p2 - p1) * (basic ? curviness * 0.5 : r1 !== 0 ? tl / r1 : 0);
17671					m2 = p2 + (p3 - p2) * (basic ? curviness * 0.5 : r2 !== 0 ? tl / r2 : 0);
17672					mm = p2 - (m1 + ((m2 - m1) * (r1 * 3 / (r1 + r2) + 0.5) / 4 || 0));
17673				} else {
17674					m1 = p2 - (p2 - p1) * curviness * 0.5;
17675					m2 = p2 + (p3 - p2) * curviness * 0.5;
17676					mm = p2 - (m1 + m2) / 2;
17677				}
17678				m1 += mm;
17679				m2 += mm;
17680
17681				seg.c = cp2 = m1;
17682				if (i !== 0) {
17683					seg.b = cp1;
17684				} else {
17685					seg.b = cp1 = seg.a + (seg.c - seg.a) * 0.6; //instead of placing b on a exactly, we move it inline with c so that if the user specifies an ease like Back.easeIn or Elastic.easeIn which goes BEYOND the beginning, it will do so smoothly.
17686				}
17687
17688				seg.da = p2 - p1;
17689				seg.ca = cp2 - p1;
17690				seg.ba = cp1 - p1;
17691
17692				if (quad) {
17693					qb = cubicToQuadratic(p1, cp1, cp2, p2);
17694					a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]);
17695					ii += 4;
17696				} else {
17697					ii++;
17698				}
17699
17700				cp1 = m2;
17701			}
17702			seg = a[ii];
17703			seg.b = cp1;
17704			seg.c = cp1 + (seg.d - cp1) * 0.4; //instead of placing c on d exactly, we move it inline with b so that if the user specifies an ease like Back.easeOut or Elastic.easeOut which goes BEYOND the end, it will do so smoothly.
17705			seg.da = seg.d - seg.a;
17706			seg.ca = seg.c - seg.a;
17707			seg.ba = cp1 - seg.a;
17708			if (quad) {
17709				qb = cubicToQuadratic(seg.a, cp1, seg.c, seg.d);
17710				a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]);
17711			}
17712		},
17713		    _parseAnchors = function (values, p, correlate, prepend) {
17714			var a = [],
17715			    l,
17716			    i,
17717			    p1,
17718			    p2,
17719			    p3,
17720			    tmp;
17721			if (prepend) {
17722				values = [prepend].concat(values);
17723				i = values.length;
17724				while (--i > -1) {
17725					if (typeof (tmp = values[i][p]) === "string") if (tmp.charAt(1) === "=") {
17726						values[i][p] = prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)); //accommodate relative values. Do it inline instead of breaking it out into a function for speed reasons
17727					}
17728				}
17729			}
17730			l = values.length - 2;
17731			if (l < 0) {
17732				a[0] = new Segment(values[0][p], 0, 0, values[0][p]);
17733				return a;
17734			}
17735			for (i = 0; i < l; i++) {
17736				p1 = values[i][p];
17737				p2 = values[i + 1][p];
17738				a[i] = new Segment(p1, 0, 0, p2);
17739				if (correlate) {
17740					p3 = values[i + 2][p];
17741					_r1[i] = (_r1[i] || 0) + (p2 - p1) * (p2 - p1);
17742					_r2[i] = (_r2[i] || 0) + (p3 - p2) * (p3 - p2);
17743				}
17744			}
17745			a[i] = new Segment(values[i][p], 0, 0, values[i + 1][p]);
17746			return a;
17747		},
17748		    bezierThrough = function (values, curviness, quadratic, basic, correlate, prepend) {
17749			var obj = {},
17750			    props = [],
17751			    first = prepend || values[0],
17752			    i,
17753			    p,
17754			    a,
17755			    j,
17756			    r,
17757			    l,
17758			    seamless,
17759			    last;
17760			correlate = typeof correlate === "string" ? "," + correlate + "," : _correlate;
17761			if (curviness == null) {
17762				curviness = 1;
17763			}
17764			for (p in values[0]) {
17765				props.push(p);
17766			}
17767			//check to see if the last and first values are identical (well, within 0.05). If so, make seamless by appending the second element to the very end of the values array and the 2nd-to-last element to the very beginning (we'll remove those segments later)
17768			if (values.length > 1) {
17769				last = values[values.length - 1];
17770				seamless = true;
17771				i = props.length;
17772				while (--i > -1) {
17773					p = props[i];
17774					if (Math.abs(first[p] - last[p]) > 0.05) {
17775						//build in a tolerance of +/-0.05 to accommodate rounding errors.
17776						seamless = false;
17777						break;
17778					}
17779				}
17780				if (seamless) {
17781					values = values.concat(); //duplicate the array to avoid contaminating the original which the user may be reusing for other tweens
17782					if (prepend) {
17783						values.unshift(prepend);
17784					}
17785					values.push(values[1]);
17786					prepend = values[values.length - 3];
17787				}
17788			}
17789			_r1.length = _r2.length = _r3.length = 0;
17790			i = props.length;
17791			while (--i > -1) {
17792				p = props[i];
17793				_corProps[p] = correlate.indexOf("," + p + ",") !== -1;
17794				obj[p] = _parseAnchors(values, p, _corProps[p], prepend);
17795			}
17796			i = _r1.length;
17797			while (--i > -1) {
17798				_r1[i] = Math.sqrt(_r1[i]);
17799				_r2[i] = Math.sqrt(_r2[i]);
17800			}
17801			if (!basic) {
17802				i = props.length;
17803				while (--i > -1) {
17804					if (_corProps[p]) {
17805						a = obj[props[i]];
17806						l = a.length - 1;
17807						for (j = 0; j < l; j++) {
17808							r = a[j + 1].da / _r2[j] + a[j].da / _r1[j] || 0;
17809							_r3[j] = (_r3[j] || 0) + r * r;
17810						}
17811					}
17812				}
17813				i = _r3.length;
17814				while (--i > -1) {
17815					_r3[i] = Math.sqrt(_r3[i]);
17816				}
17817			}
17818			i = props.length;
17819			j = quadratic ? 4 : 1;
17820			while (--i > -1) {
17821				p = props[i];
17822				a = obj[p];
17823				_calculateControlPoints(a, curviness, quadratic, basic, _corProps[p]); //this method requires that _parseAnchors() and _setSegmentRatios() ran first so that _r1, _r2, and _r3 values are populated for all properties
17824				if (seamless) {
17825					a.splice(0, j);
17826					a.splice(a.length - j, j);
17827				}
17828			}
17829			return obj;
17830		},
17831		    _parseBezierData = function (values, type, prepend) {
17832			type = type || "soft";
17833			var obj = {},
17834			    inc = type === "cubic" ? 3 : 2,
17835			    soft = type === "soft",
17836			    props = [],
17837			    a,
17838			    b,
17839			    c,
17840			    d,
17841			    cur,
17842			    i,
17843			    j,
17844			    l,
17845			    p,
17846			    cnt,
17847			    tmp;
17848			if (soft && prepend) {
17849				values = [prepend].concat(values);
17850			}
17851			if (values == null || values.length < inc + 1) {
17852				throw "invalid Bezier data";
17853			}
17854			for (p in values[0]) {
17855				props.push(p);
17856			}
17857			i = props.length;
17858			while (--i > -1) {
17859				p = props[i];
17860				obj[p] = cur = [];
17861				cnt = 0;
17862				l = values.length;
17863				for (j = 0; j < l; j++) {
17864					a = prepend == null ? values[j][p] : typeof (tmp = values[j][p]) === "string" && tmp.charAt(1) === "=" ? prepend[p] + Number(tmp.charAt(0) + tmp.substr(2)) : Number(tmp);
17865					if (soft) if (j > 1) if (j < l - 1) {
17866						cur[cnt++] = (a + cur[cnt - 2]) / 2;
17867					}
17868					cur[cnt++] = a;
17869				}
17870				l = cnt - inc + 1;
17871				cnt = 0;
17872				for (j = 0; j < l; j += inc) {
17873					a = cur[j];
17874					b = cur[j + 1];
17875					c = cur[j + 2];
17876					d = inc === 2 ? 0 : cur[j + 3];
17877					cur[cnt++] = tmp = inc === 3 ? new Segment(a, b, c, d) : new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
17878				}
17879				cur.length = cnt;
17880			}
17881			return obj;
17882		},
17883		    _addCubicLengths = function (a, steps, resolution) {
17884			var inc = 1 / resolution,
17885			    j = a.length,
17886			    d,
17887			    d1,
17888			    s,
17889			    da,
17890			    ca,
17891			    ba,
17892			    p,
17893			    i,
17894			    inv,
17895			    bez,
17896			    index;
17897			while (--j > -1) {
17898				bez = a[j];
17899				s = bez.a;
17900				da = bez.d - s;
17901				ca = bez.c - s;
17902				ba = bez.b - s;
17903				d = d1 = 0;
17904				for (i = 1; i <= resolution; i++) {
17905					p = inc * i;
17906					inv = 1 - p;
17907					d = d1 - (d1 = (p * p * da + 3 * inv * (p * ca + inv * ba)) * p);
17908					index = j * resolution + i - 1;
17909					steps[index] = (steps[index] || 0) + d * d;
17910				}
17911			}
17912		},
17913		    _parseLengthData = function (obj, resolution) {
17914			resolution = resolution >> 0 || 6;
17915			var a = [],
17916			    lengths = [],
17917			    d = 0,
17918			    total = 0,
17919			    threshold = resolution - 1,
17920			    segments = [],
17921			    curLS = [],
17922			    //current length segments array
17923			p,
17924			    i,
17925			    l,
17926			    index;
17927			for (p in obj) {
17928				_addCubicLengths(obj[p], a, resolution);
17929			}
17930			l = a.length;
17931			for (i = 0; i < l; i++) {
17932				d += Math.sqrt(a[i]);
17933				index = i % resolution;
17934				curLS[index] = d;
17935				if (index === threshold) {
17936					total += d;
17937					index = i / resolution >> 0;
17938					segments[index] = curLS;
17939					lengths[index] = total;
17940					d = 0;
17941					curLS = [];
17942				}
17943			}
17944			return { length: total, lengths: lengths, segments: segments };
17945		},
17946		    BezierPlugin = _gsScope._gsDefine.plugin({
17947			propName: "bezier",
17948			priority: -1,
17949			version: "1.3.8",
17950			API: 2,
17951			global: true,
17952
17953			//gets called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
17954			init: function (target, vars, tween) {
17955				this._target = target;
17956				if (vars instanceof Array) {
17957					vars = { values: vars };
17958				}
17959				this._func = {};
17960				this._mod = {};
17961				this._props = [];
17962				this._timeRes = vars.timeResolution == null ? 6 : parseInt(vars.timeResolution, 10);
17963				var values = vars.values || [],
17964				    first = {},
17965				    second = values[0],
17966				    autoRotate = vars.autoRotate || tween.vars.orientToBezier,
17967				    p,
17968				    isFunc,
17969				    i,
17970				    j,
17971				    prepend;
17972
17973				this._autoRotate = autoRotate ? autoRotate instanceof Array ? autoRotate : [["x", "y", "rotation", autoRotate === true ? 0 : Number(autoRotate) || 0]] : null;
17974				for (p in second) {
17975					this._props.push(p);
17976				}
17977
17978				i = this._props.length;
17979				while (--i > -1) {
17980					p = this._props[i];
17981
17982					this._overwriteProps.push(p);
17983					isFunc = this._func[p] = typeof target[p] === "function";
17984					first[p] = !isFunc ? parseFloat(target[p]) : target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)]();
17985					if (!prepend) if (first[p] !== values[0][p]) {
17986						prepend = first;
17987					}
17988				}
17989				this._beziers = vars.type !== "cubic" && vars.type !== "quadratic" && vars.type !== "soft" ? bezierThrough(values, isNaN(vars.curviness) ? 1 : vars.curviness, false, vars.type === "thruBasic", vars.c
17989orrelate, prepend) : _parseBezierData(values, vars.type, first);
17990				this._segCount = this._beziers[p].length;
17991
17992				if (this._timeRes) {
17993					var ld = _parseLengthData(this._beziers, this._timeRes);
17994					this._length = ld.length;
17995					this._lengths = ld.lengths;
17996					this._segments = ld.segments;
17997					this._l1 = this._li = this._s1 = this._si = 0;
17998					this._l2 = this._lengths[0];
17999					this._curSeg = this._segments[0];
18000					this._s2 = this._curSeg[0];
18001					this._prec = 1 / this._curSeg.length;
18002				}
18003
18004				if (autoRotate = this._autoRotate) {
18005					this._initialRotations = [];
18006					if (!(autoRotate[0] instanceof Array)) {
18007						this._autoRotate = autoRotate = [autoRotate];
18008					}
18009					i = autoRotate.length;
18010					while (--i > -1) {
18011						for (j = 0; j < 3; j++) {
18012							p = autoRotate[i][j];
18013							this._func[p] = typeof target[p] === "function" ? target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)] : false;
18014						}
18015						p = autoRotate[i][2];
18016						this._initialRotations[i] = (this._func[p] ? this._func[p].call(this._target) : this._target[p]) || 0;
18017						this._overwriteProps.push(p);
18018					}
18019				}
18020				this._startRatio = tween.vars.runBackwards ? 1 : 0; //we determine the starting ratio when the tween inits which is always 0 unless the tween has runBackwards:true (indicating it's a from() tween) in which case it's 1.
18021				return true;
18022			},
18023
18024			//called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.)
18025			set: function (v) {
18026				var segments = this._segCount,
18027				    func = this._func,
18028				    target = this._target,
18029				    notStart = v !== this._startRatio,
18030				    curIndex,
18031				    inv,
18032				    i,
18033				    p,
18034				    b,
18035				    t,
18036				    val,
18037				    l,
18038				    lengths,
18039				    curSeg;
18040				if (!this._timeRes) {
18041					curIndex = v < 0 ? 0 : v >= 1 ? segments - 1 : segments * v >> 0;
18042					t = (v - curIndex * (1 / segments)) * segments;
18043				} else {
18044					lengths = this._lengths;
18045					curSeg = this._curSeg;
18046					v *= this._length;
18047					i = this._li;
18048					//find the appropriate segment (if the currently cached one isn't correct)
18049					if (v > this._l2 && i < segments - 1) {
18050						l = segments - 1;
18051						while (i < l && (this._l2 = lengths[++i]) <= v) {}
18052						this._l1 = lengths[i - 1];
18053						this._li = i;
18054						this._curSeg = curSeg = this._segments[i];
18055						this._s2 = curSeg[this._s1 = this._si = 0];
18056					} else if (v < this._l1 && i > 0) {
18057						while (i > 0 && (this._l1 = lengths[--i]) >= v) {}
18058						if (i === 0 && v < this._l1) {
18059							this._l1 = 0;
18060						} else {
18061							i++;
18062						}
18063						this._l2 = lengths[i];
18064						this._li = i;
18065						this._curSeg = curSeg = this._segments[i];
18066						this._s1 = curSeg[(this._si = curSeg.length - 1) - 1] || 0;
18067						this._s2 = curSeg[this._si];
18068					}
18069					curIndex = i;
18070					//now find the appropriate sub-segment (we split it into the number of pieces that was defined by "precision" and measured each one)
18071					v -= this._l1;
18072					i = this._si;
18073					if (v > this._s2 && i < curSeg.length - 1) {
18074						l = curSeg.length - 1;
18075						while (i < l && (this._s2 = curSeg[++i]) <= v) {}
18076						this._s1 = curSeg[i - 1];
18077						this._si = i;
18078					} else if (v < this._s1 && i > 0) {
18079						while (i > 0 && (this._s1 = curSeg[--i]) >= v) {}
18080						if (i === 0 && v < this._s1) {
18081							this._s1 = 0;
18082						} else {
18083							i++;
18084						}
18085						this._s2 = curSeg[i];
18086						this._si = i;
18087					}
18088					t = (i + (v - this._s1) / (this._s2 - this._s1)) * this._prec || 0;
18089				}
18090				inv = 1 - t;
18091
18092				i = this._props.length;
18093				while (--i > -1) {
18094					p = this._props[i];
18095					b = this._beziers[p][curIndex];
18096					val = (t * t * b.da + 3 * inv * (t * b.ca + inv * b.ba)) * t + b.a;
18097					if (this._mod[p]) {
18098						val = this._mod[p](val, target);
18099					}
18100					if (func[p]) {
18101						target[p](val);
18102					} else {
18103						target[p] = val;
18104					}
18105				}
18106
18107				if (this._autoRotate) {
18108					var ar = this._autoRotate,
18109					    b2,
18110					    x1,
18111					    y1,
18112					    x2,
18113					    y2,
18114					    add,
18115					    conv;
18116					i = ar.length;
18117					while (--i > -1) {
18118						p = ar[i][2];
18119						add = ar[i][3] || 0;
18120						conv = ar[i][4] === true ? 1 : _RAD2DEG;
18121						b = this._beziers[ar[i][0]];
18122						b2 = this._beziers[ar[i][1]];
18123
18124						if (b && b2) {
18125							//in case one of the properties got overwritten.
18126							b = b[curIndex];
18127							b2 = b2[curIndex];
18128
18129							x1 = b.a + (b.b - b.a) * t;
18130							x2 = b.b + (b.c - b.b) * t;
18131							x1 += (x2 - x1) * t;
18132							x2 += (b.c + (b.d - b.c) * t - x2) * t;
18133
18134							y1 = b2.a + (b2.b - b2.a) * t;
18135							y2 = b2.b + (b2.c - b2.b) * t;
18136							y1 += (y2 - y1) * t;
18137							y2 += (b2.c + (b2.d - b2.c) * t - y2) * t;
18138
18139							val = notStart ? Math.atan2(y2 - y1, x2 - x1) * conv + add : this._initialRotations[i];
18140
18141							if (this._mod[p]) {
18142								val = this._mod[p](val, target); //for modProps
18143							}
18144
18145							if (func[p]) {
18146								target[p](val);
18147							} else {
18148								target[p] = val;
18149							}
18150						}
18151					}
18152				}
18153			}
18154		}),
18155		    p = BezierPlugin.prototype;
18156
18157		BezierPlugin.bezierThrough = bezierThrough;
18158		BezierPlugin.cubicToQuadratic = cubicToQuadratic;
18159		BezierPlugin._autoCSS = true; //indicates that this plugin can be inserted into the "css" object using the autoCSS feature of TweenLite
18160		BezierPlugin.quadraticToCubic = function (a, b, c) {
18161			return new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
18162		};
18163
18164		BezierPlugin._cssRegister = function () {
18165			var CSSPlugin = _globals.CSSPlugin;
18166			if (!CSSPlugin) {
18167				return;
18168			}
18169			var _internals = CSSPlugin._internals,
18170			    _parseToProxy = _internals._parseToProxy,
18171			    _setPluginRatio = _internals._setPluginRatio,
18172			    CSSPropTween = _internals.CSSPropTween;
18173			_internals._registerComplexSpecialProp("bezier", { parser: function (t, e, prop, cssp, pt, plugin) {
18174					if (e instanceof Array) {
18175						e = { values: e };
18176					}
18177					plugin = new BezierPlugin();
18178					var values = e.values,
18179					    l = values.length - 1,
18180					    pluginValues = [],
18181					    v = {},
18182					    i,
18183					    p,
18184					    data;
18185					if (l < 0) {
18186						return pt;
18187					}
18188					for (i = 0; i <= l; i++) {
18189						data = _parseToProxy(t, values[i], cssp, pt, plugin, l !== i);
18190						pluginValues[i] = data.end;
18191					}
18192					for (p in e) {
18193						v[p] = e[p]; //duplicate the vars object because we need to alter some things which would cause problems if the user plans to reuse the same vars object for another tween.
18194					}
18195					v.values = pluginValues;
18196					pt = new CSSPropTween(t, "bezier", 0, 0, data.pt, 2);
18197					pt.data = data;
18198					pt.plugin = plugin;
18199					pt.setRatio = _setPluginRatio;
18200					if (v.autoRotate === 0) {
18201						v.autoRotate = true;
18202					}
18203					if (v.autoRotate && !(v.autoRotate instanceof Array)) {
18204						i = v.autoRotate === true ? 0 : Number(v.autoRotate);
18205						v.autoRotate = data.end.left != null ? [["left", "top", "rotation", i, false]] : data.end.x != null ? [["x", "y", "rotation", i, false]] : false;
18206					}
18207					if (v.autoRotate) {
18208						if (!cssp._transform) {
18209							cssp._enableTransforms(false);
18210						}
18211						data.autoRotate = cssp._target._gsTransform;
18212						data.proxy.rotation = data.autoRotate.rotation || 0;
18213						cssp._overwriteProps.push("rotation");
18214					}
18215					plugin._onInitTween(data.proxy, v, cssp._tween);
18216					return pt;
18217				} });
18218		};
18219
18220		p._mod = function (lookup) {
18221			var op = this._overwriteProps,
18222			    i = op.length,
18223			    val;
18224			while (--i > -1) {
18225				val = lookup[op[i]];
18226				if (val && typeof val === "function") {
18227					this._mod[op[i]] = val;
18228				}
18229			}
18230		};
18231
18232		p._kill = function (lookup) {
18233			var a = this._props,
18234			    p,
18235			    i;
18236			for (p in this._beziers) {
18237				if (p in lookup) {
18238					delete this._beziers[p];
18239					delete this._func[p];
18240					i = a.length;
18241					while (--i > -1) {
18242						if (a[i] === p) {
18243							a.splice(i, 1);
18244						}
18245					}
18246				}
18247			}
18248			a = this._autoRotate;
18249			if (a) {
18250				i = a.length;
18251				while (--i > -1) {
18252					if (lookup[a[i][2]]) {
18253						a.splice(i, 1);
18254					}
18255				}
18256			}
18257			return this._super._kill.call(this, lookup);
18258		};
18259	})();
18260
18261	/*
18262  * ----------------------------------------------------------------
18263  * CSSPlugin
18264  * ----------------------------------------------------------------
18265  */
18266	_gsScope._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin", "TweenLite"], function (TweenPlugin, TweenLite) {
18267
18268		/** @constructor **/
18269		var CSSPlugin = function () {
18270			TweenPlugin.call(this, "css");
18271			this._overwriteProps.length = 0;
18272			this.setRatio = CSSPlugin.prototype.setRatio; //speed optimization (avoid prototype lookup on this "hot" method)
18273		},
18274		    _globals = _gsScope._gsDefine.globals,
18275		    _hasPriority,
18276		    //turns true whenever a CSSPropTween instance is created that has a priority other than 0. This helps us discern whether or not we should spend the time organizing the linked list or not after a CSSPlugin's _onInitTween() method is called.
18277		_suffixMap,
18278		    //we set this in _onInitTween() each time as a way to have a persistent variable we can use in other methods like _parse() without having to pass it around as a parameter and we keep _parse() decoupled from a particular CSSPlugin instance
18279		_cs,
18280		    //computed style (we store this in a shared variable to conserve memory and make minification tighter
18281		_overwriteProps,
18282		    //alias to the currently instantiating CSSPlugin's _overwriteProps array. We use this closure in order to avoid having to pass a reference around from method to method and aid in minification.
18283		_specialProps = {},
18284		    p = CSSPlugin.prototype = new TweenPlugin("css");
18285
18286		p.constructor = CSSPlugin;
18287		CSSPlugin.version = "1.20.3";
18288		CSSPlugin.API = 2;
18289		CSSPlugin.defaultTransformPerspective = 0;
18290		CSSPlugin.defaultSkewType = "compensated";
18291		CSSPlugin.defaultSmoothOrigin = true;
18292		p = "px"; //we'll reuse the "p" variable to keep file size down
18293		CSSPlugin.suffixMap = { top: p, right: p, bottom: p, left: p, width: p, height: p, fontSize: p, padding: p, margin: p, perspective: p, lineHeight: "" };
18294
18295		var _numExp = /(?:\-|\.|\b)(\d|\.|e\-)+/g,
18296		    _relNumExp = /(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g,
18297		    _valuesExp = /(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b)/gi,
18298		    //finds all the values that begin with numbers or += or -= and then a number. Includes suffixes. We use this to split complex values apart like "1px 5px 20px rgb(255,102,51)"
18299		_NaNExp = /(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g,
18300		    //also allows scientific notation and doesn't kill the leading -/+ in -= and +=
18301		_suffixExp = /(?:\d|\-|\+|=|#|\.)*/g,
18302		    _opacityExp = /opacity *= *([^)]*)/i,
18303		    _opacityValExp = /opacity:([^;]*)/i,
18304		    _alphaFilterExp = /alpha\(opacity *=.+?\)/i,
18305		    _rgbhslExp = /^(rgb|hsl)/,
18306		    _capsExp = /([A-Z])/g,
18307		    _camelExp = /-([a-z])/gi,
18308		    _urlExp = /(^(?:url\(\"|url\())|(?:(\"\))$|\)$)/gi,
18309		    //for pulling out urls from url(...) or url("...") strings (some browsers wrap urls in quotes, some don't when reporting things like backgroundImage)
18310		_camelFunc = function (s, g) {
18311			return g.toUpperCase();
18312		},
18313		    _horizExp = /(?:Left|Right|Width)/i,
18314		    _ieGetMatrixExp = /(M11|M12|M21|M22)=[\d\-\.e]+/gi,
18315		    _ieSetMatrixExp = /progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i,
18316		    _commasOutsideParenExp = /,(?=[^\)]*(?:\(|$))/gi,
18317		    //finds any commas that are not within parenthesis
18318		_complexExp = /[\s,\(]/i,
18319		    //for testing a string to find if it has a space, comma, or open parenthesis (clues that it's a complex value)
18320		_DEG2RAD = Math.PI / 180,
18321		    _RAD2DEG = 180 / Math.PI,
18322		    _forcePT = {},
18323		    _dummyElement = { style: {} },
18324		    _doc = _gsScope.document || { createElement: function () {
18325				return _dummyElement;
18326			} },
18327		    _createElement = function (type, ns) {
18328			return _doc.createElementNS ? _doc.createElementNS(ns || "http://www.w3.org/1999/xhtml", type) : _doc.createElement(type);
18329		},
18330		    _tempDiv = _createElement("div"),
18331		    _tempImg = _createElement("img"),
18332		    _internals = CSSPlugin._internals = { _specialProps: _specialProps },
18333		    //provides a hook to a few internal methods that we need to access from inside other plugins
18334		_agent = (_gsScope.navigator || {}).userAgent || "",
18335		    _autoRound,
18336		    _reqSafariFix,
18337		    //we won't apply the Safari transform fix until we actually come across a tween that affects a transform property (to maintain best performance).
18338
18339		_isSafari,
18340		    _isFirefox,
18341		    //Firefox has a bug that causes 3D transformed elements to randomly disappear unless a repaint is forced after each update on each element.
18342		_isSafariLT6,
18343		    //Safari (and Android 4 which uses a flavor of Safari) has a bug that prevents changes to "top" and "left" properties from rendering properly if changed on the same frame as a transform UNLESS we set the element's WebkitBackfaceVisibility to hidden (weird, I know). Doing this for Android 3 and earlier seems to actually cause other problems, though (fun!)
18344		_ieVers,
18345		    _supportsOpacity = function () {
18346			//we set _isSafari, _ieVers, _isFirefox, and _supportsOpacity all in one function here to reduce file size slightly, especially in the minified version.
18347			var i = _agent.indexOf("Android"),
18348			    a = _createElement("a");
18349			_isSafari = _agent.indexOf("Safari") !== -1 && _agent.indexOf("Chrome") === -1 && (i === -1 || parseFloat(_agent.substr(i + 8, 2)) > 3);
18350			_isSafariLT6 = _isSafari && parseFloat(_agent.substr(_agent.indexOf("Version/") + 8, 2)) < 6;
18351			_isFirefox = _agent.indexOf("Firefox") !== -1;
18352			if (/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(_agent) || /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(_agent)) {
18353				_ieVers = parseFloat(RegExp.$1);
18354			}
18355			if (!a) {
18356				return false;
18357			}
18358			a.style.cssText = "top:1px;opacity:.55;";
18359			return (/^0.55/.test(a.style.opacity)
18360			);
18361		}(),
18362		    _getIEOpacity = function (v) {
18363			return _opacityExp.test(typeof v === "string" ? v : (v.currentStyle ? v.currentStyle.filter : v.style.filter) || "") ? parseFloat(RegExp.$1) / 100 : 1;
18364		},
18365		    _log = function (s) {
18366			//for logging messages, but in a way that won't throw errors in old versions of IE.
18367			if (_gsScope.console) {
18368				console.log(s);
18369			}
18370		},
18371		    _target,
18372		    //when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params
18373		_index,
18374		    //when initting a CSSPlugin, we set this variable so that we can access it from within many other functions without having to pass it around as params
18375
18376		_prefixCSS = "",
18377		    //the non-camelCase vendor prefix like "-o-", "-moz-", "-ms-", or "-webkit-"
18378		_prefix = "",
18379		    //camelCase vendor prefix like "O", "ms", "Webkit", or "Moz".
18380
18381		// @private feed in a camelCase property name like "transform" and it will check to see if it is valid as-is or if it needs a vendor prefix. It returns the corrected camelCase property name (i.e. "WebkitTransform" or "MozTransform" or "transform" or null if no such property is found, like if the browser is IE8 or before, "transform" won't be found at all)
18382		_checkPropPrefix = function (p, e) {
18383			e = e || _tempDiv;
18384			var s = e.style,
18385			    a,
18386			    i;
18387			if (s[p] !== undefined) {
18388				return p;
18389			}
18390			p = p.charAt(0).toUpperCase() + p.substr(1);
18391			a = ["O", "Moz", "ms", "Ms", "Webkit"];
18392			i = 5;
18393			while (--i > -1 && s[a[i] + p] === undefined) {}
18394			if (i >= 0) {
18395				_prefix = i === 3 ? "ms" : a[i];
18396				_prefixCSS = "-" + _prefix.toLowerCase() + "-";
18397				return _prefix + p;
18398			}
18399			return null;
18400		},
18401		    _getComputedStyle = _doc.defaultView ? _doc.defaultView.getComputedStyle : function () {},
18402
18403
18404		/**
18405   * @private Returns the css style for a particular property of an element. For example, to get whatever the current "left" css value for an element with an ID of "myElement", you could do:
18406   * var currentLeft = CSSPlugin.getStyle( document.getElementById("myElement"), "left");
18407   *
18408   * @param {!Object} t Target element whose style property you want to query
18409   * @param {!string} p Property name (like "left" or "top" or "marginTop", etc.)
18410   * @param {Object=} cs Computed style object. This just provides a way to speed processing if you're going to get several properties on the same element in quick succession - you can reuse the result of the getComputedStyle() call.
18411   * @param {boolean=} calc If true, the value will not be read directly from the element's "style" property (if it exists there), but instead the getComputedStyle() result will be used. This can be useful when you want to ensure that the browser itself is interpreting the value.
18412   * @param {string=} dflt Default value that should be returned in the place of null, "none", "auto" or "auto auto".
18413   * @return {?string} The current property value
18414   */
18415		_getStyle = CSSPlugin.getStyle = function (t, p, cs, calc, dflt) {
18416			var rv;
18417			if (!_supportsOpacity) if (p === "opacity") {
18418				//several versions of IE don't use the standard "opacity" property - they use things like filter:alpha(opacity=50), so we parse that here.
18419				return _getIEOpacity(t);
18420			}
18421			if (!calc && t.style[p]) {
18422				rv = t.style[p];
18423			} else if (cs = cs || _getComputedStyle(t)) {
18424				rv = cs[p] || cs.getPropertyValue(p) || cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase());
18425			} else if (t.currentStyle) {
18426				rv = t.currentStyle[p];
18427			}
18428			return dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto") ? dflt : rv;
18429		},
18430
18431
18432		/**
18433   * @private Pass the target element, the property name, the numeric value, and the suffix (like "%", "em", "px", etc.) and it will spit back the equivalent pixel number.
18434   * @param {!Object} t Target element
18435   * @param {!string} p Property name (like "left", "top", "marginLeft", etc.)
18436   * @param {!number} v Value
18437   * @param {string=} sfx Suffix (like "px" or "%" or "em")
18438   * @param {boolean=} recurse If true, the call is a recursive one. In some browsers (like IE7/8), occasionally the value isn't accurately reported initially, but if we run the function again it will take effect.
18439   * @return {number} value in pixels
18440   */
18441		_convertToPixels = _internals.convertToPixels = function (t, p, v, sfx, recurse) {
18442			if (sfx === "px" || !sfx && p !== "lineHeight") {
18443				return v;
18444			}
18445			if (sfx === "auto" || !v) {
18446				return 0;
18447			}
18448			var horiz = _horizExp.test(p),
18449			    node = t,
18450			    style = _tempDiv.style,
18451			    neg = v < 0,
18452			    precise = v === 1,
18453			    pix,
18454			    cache,
18455			    time;
18456			if (neg) {
18457				v = -v;
18458			}
18459			if (precise) {
18460				v *= 100;
18461			}
18462			if (p === "lineHeight" && !sfx) {
18463				//special case of when a simple lineHeight (without a unit) is used. Set it to the value, read back the computed value, and then revert.
18464				cache = _getComputedStyle(t).lineHeight;
18465				t.style.lineHeight = v;
18466				pix = parseFloat(_getComputedStyle(t).lineHeight);
18467				t.style.lineHeight = cache;
18468			} else if (sfx === "%" && p.indexOf("border") !== -1) {
18469				pix = v / 100 * (horiz ? t.clientWidth : t.clientHeight);
18470			} else {
18471				style.cssText = "border:0 solid red;position:" + _getStyle(t, "position") + ";line-height:0;";
18472				if (sfx === "%" || !node.appendChild || sfx.charAt(0) === "v" || sfx === "rem") {
18473					node = t.parentNode || _doc.body;
18474					if (_getStyle(node, "display").indexOf("flex") !== -1) {
18475						//Edge and IE11 have a bug that causes offsetWidth to report as 0 if the container has display:flex and the child is position:relative. Switching to position: absolute solves it.
18476						style.position = "absolute";
18477					}
18478					cache = node._gsCache;
18479					time = TweenLite.ticker.frame;
18480					if (cache && horiz && cache.time === time) {
18481						//performance optimization: we record the width of elements along with the ticker frame so that we can quickly get it again on the same tick (seems relatively safe to assume it wouldn't change on the same tick)
18482						return cache.width * v / 100;
18483					}
18484					style[horiz ? "width" : "height"] = v + sfx;
18485				} else {
18486					style[horiz ? "borderLeftWidth" : "borderTopWidth"] = v + sfx;
18487				}
18488				node.appendChild(_tempDiv);
18489				pix = parseFloat(_tempDiv[horiz ? "offsetWidth" : "offsetHeight"]);
18490				node.removeChild(_tempDiv);
18491				if (horiz && sfx === "%" && CSSPlugin.cacheWidths !== false) {
18492					cache = node._gsCache = node._gsCache || {};
18493					cache.time = time;
18494					cache.width = pix / v * 100;
18495				}
18496				if (pix === 0 && !recurse) {
18497					pix = _convertToPixels(t, p, v, sfx, true);
18498				}
18499			}
18500			if (precise) {
18501				pix /= 100;
18502			}
18503			return neg ? -pix : pix;
18504		},
18505		    _calculateOffset = _internals.calculateOffset = function (t, p, cs) {
18506			//for figuring out "top" or "left" in px when it's "auto". We need to factor in margin with the offsetLeft/offsetTop
18507			if (_getStyle(t, "position", cs) !== "absolute") {
18508				return 0;
18509			}
18510			var dim = p === "left" ? "Left" : "Top",
18511			    v = _getStyle(t, "margin" + dim, cs);
18512			return t["offset" + dim] - (_convertToPixels(t, p, parseFloat(v), v.replace(_suffixExp, "")) || 0);
18513		},
18514
18515
18516		// @private returns at object containing ALL of the style properties in camelCase and their associated values.
18517		_getAllStyles = function (t, cs) {
18518			var s = {},
18519			    i,
18520			    tr,
18521			    p;
18522			if (cs = cs || _getComputedStyle(t, null)) {
18523				if (i = cs.length) {
18524					while (--i > -1) {
18525						p = cs[i];
18526						if (p.indexOf("-transform") === -1 || _transformPropCSS === p) {
18527							//Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
18528							s[p.replace(_camelExp, _camelFunc)] = cs.getPropertyValue(p);
18529						}
18530					}
18531				} else {
18532					//some browsers behave differently - cs.length is always 0, so we must do a for...in loop.
18533					for (i in cs) {
18534						if (i.indexOf("Transform") === -1 || _transformProp === i) {
18535							//Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
18536							s[i] = cs[i];
18537						}
18538					}
18539				}
18540			} else if (cs = t.currentStyle || t.style) {
18541				for (i in cs) {
18542					if (typeof i === "string" && s[i] === undefined) {
18543						s[i.replace(_camelExp, _camelFunc)] = cs[i];
18544					}
18545				}
18546			}
18547			if (!_supportsOpacity) {
18548				s.opacity = _getIEOpacity(t);
18549			}
18550			tr = _getTransform(t, cs, false);
18551			s.rotation = tr.rotation;
18552			s.skewX = tr.skewX;
18553			s.scaleX = tr.scaleX;
18554			s.scaleY = tr.scaleY;
18555			s.x = tr.x;
18556			s.y = tr.y;
18557			if (_supports3D) {
18558				s.z = tr.z;
18559				s.rotationX = tr.rotationX;
18560				s.rotationY = tr.rotationY;
18561				s.scaleZ = tr.scaleZ;
18562			}
18563			if (s.filters) {
18564				delete s.filters;
18565			}
18566			return s;
18567		},
18568
18569
18570		// @private analyzes two style objects (as returned by _getAllStyles()) and only looks for differences between them that contain tweenable values (like a number or color). It returns an object with a "difs" property which refers to an object c
18570ontaining only those isolated properties and values for tweening, and a "firstMPT" property which refers to the first MiniPropTween instance in a linked list that recorded all the starting values of the different properties so that we can revert to them at the end or beginning of the tween - we don't want the cascading to get messed up. The forceLookup parameter is an optional generic object with properties that should be forced into the results - this is necessary for className tweens that are overwriting others because imagine a scenario where a rollover/rollout adds/removes a class and the user swipes the mouse over the target SUPER fast, thus nothing actually changed yet and the subsequent comparison of the properties would indicate they match (especially when px rounding is taken into consideration), thus no tweening is necessary even though it SHOULD tween and remove those properties after the tween (otherwise the inline styles will contaminate things). See the className SpecialProp code for details.
18571		_cssDif = function (t, s1, s2, vars, forceLookup) {
18572			var difs = {},
18573			    style = t.style,
18574			    val,
18575			    p,
18576			    mpt;
18577			for (p in s2) {
18578				if (p !== "cssText") if (p !== "length") if (isNaN(p)) if (s1[p] !== (val = s2[p]) || forceLookup && forceLookup[p]) if (p.indexOf("Origin") === -1) if (typeof val === "number" || typeof val === "string") {
18579					difs[p] = val === "auto" && (p === "left" || p === "top") ? _calculateOffset(t, p) : (val === "" || val === "auto" || val === "none") && typeof s1[p] === "string" && s1[p].replace(_NaNExp, "") !== "" ? 0 : val; //if the ending value is defaulting ("" or "auto"), we check the starting value and if it can be parsed into a number (a string which could have a suffix too, like 700px), then we swap in 0 for "" or "auto" so that things actually tween.
18580					if (style[p] !== undefined) {
18581						//for className tweens, we must remember which properties already existed inline - the ones that didn't should be removed when the tween isn't in progress because they were only introduced to facilitate the transition between classes.
18582						mpt = new MiniPropTween(style, p, style[p], mpt);
18583					}
18584				}
18585			}
18586			if (vars) {
18587				for (p in vars) {
18588					//copy properties (except className)
18589					if (p !== "className") {
18590						difs[p] = vars[p];
18591					}
18592				}
18593			}
18594			return { difs: difs, firstMPT: mpt };
18595		},
18596		    _dimensions = { width: ["Left", "Right"], height: ["Top", "Bottom"] },
18597		    _margins = ["marginLeft", "marginRight", "marginTop", "marginBottom"],
18598
18599
18600		/**
18601   * @private Gets the width or height of an element
18602   * @param {!Object} t Target element
18603   * @param {!string} p Property name ("width" or "height")
18604   * @param {Object=} cs Computed style object (if one exists). Just a speed optimization.
18605   * @return {number} Dimension (in pixels)
18606   */
18607		_getDimension = function (t, p, cs) {
18608			if ((t.nodeName + "").toLowerCase() === "svg") {
18609				//Chrome no longer supports offsetWidth/offsetHeight on SVG elements.
18610				return (cs || _getComputedStyle(t))[p] || 0;
18611			} else if (t.getCTM && _isSVG(t)) {
18612				return t.getBBox()[p] || 0;
18613			}
18614			var v = parseFloat(p === "width" ? t.offsetWidth : t.offsetHeight),
18615			    a = _dimensions[p],
18616			    i = a.length;
18617			cs = cs || _getComputedStyle(t, null);
18618			while (--i > -1) {
18619				v -= parseFloat(_getStyle(t, "padding" + a[i], cs, true)) || 0;
18620				v -= parseFloat(_getStyle(t, "border" + a[i] + "Width", cs, true)) || 0;
18621			}
18622			return v;
18623		},
18624
18625
18626		// @private Parses position-related complex strings like "top left" or "50px 10px" or "70% 20%", etc. which are used for things like transformOrigin or backgroundPosition. Optionally decorates a supplied object (recObj) with the following properties: "ox" (offsetX), "oy" (offsetY), "oxp" (if true, "ox" is a percentage not a pixel value), and "oxy" (if true, "oy" is a percentage not a pixel value)
18627		_parsePosition = function (v, recObj) {
18628			if (v === "contain" || v === "auto" || v === "auto auto") {
18629				//note: Firefox uses "auto auto" as default whereas Chrome uses "auto".
18630				return v + " ";
18631			}
18632			if (v == null || v === "") {
18633				v = "0 0";
18634			}
18635			var a = v.split(" "),
18636			    x = v.indexOf("left") !== -1 ? "0%" : v.indexOf("right") !== -1 ? "100%" : a[0],
18637			    y = v.indexOf("top") !== -1 ? "0%" : v.indexOf("bottom") !== -1 ? "100%" : a[1],
18638			    i;
18639			if (a.length > 3 && !recObj) {
18640				//multiple positions
18641				a = v.split(", ").join(",").split(",");
18642				v = [];
18643				for (i = 0; i < a.length; i++) {
18644					v.push(_parsePosition(a[i]));
18645				}
18646				return v.join(",");
18647			}
18648			if (y == null) {
18649				y = x === "center" ? "50%" : "0";
18650			} else if (y === "center") {
18651				y = "50%";
18652			}
18653			if (x === "center" || isNaN(parseFloat(x)) && (x + "").indexOf("=") === -1) {
18654				//remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it c
18654ould be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative.
18655				x = "50%";
18656			}
18657			v = x + " " + y + (a.length > 2 ? " " + a[2] : "");
18658			if (recObj) {
18659				recObj.oxp = x.indexOf("%") !== -1;
18660				recObj.oyp = y.indexOf("%") !== -1;
18661				recObj.oxr = x.charAt(1) === "=";
18662				recObj.oyr = y.charAt(1) === "=";
18663				recObj.ox = parseFloat(x.replace(_NaNExp, ""));
18664				recObj.oy = parseFloat(y.replace(_NaNExp, ""));
18665				recObj.v = v;
18666			}
18667			return recObj || v;
18668		},
18669
18670
18671		/**
18672   * @private Takes an ending value (typically a string, but can be a number) and a starting value and returns the change between the two, looking for relative value indicators like += and -= and it also ignores suffixes (but make sure the ending value starts with a number or +=/-= and that the starting value is a NUMBER!)
18673   * @param {(number|string)} e End value which is typically a string, but could be a number
18674   * @param {(number|string)} b Beginning value which is typically a string but could be a number
18675   * @return {number} Amount of change between the beginning and ending values (relative values that have a "+=" or "-=" are recognized)
18676   */
18677		_parseChange = function (e, b) {
18678			if (typeof e === "function") {
18679				e = e(_index, _target);
18680			}
18681			return typeof e === "string" && e.charAt(1) === "=" ? parseInt(e.charAt(0) + "1", 10) * parseFloat(e.substr(2)) : parseFloat(e) - parseFloat(b) || 0;
18682		},
18683
18684
18685		/**
18686   * @private Takes a value and a default number, checks if the value is relative, null, or numeric and spits back a normalized number accordingly. Primarily used in the _parseTransform() function.
18687   * @param {Object} v Value to be parsed
18688   * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
18689   * @return {number} Parsed value
18690   */
18691		_parseVal = function (v, d) {
18692			if (typeof v === "function") {
18693				v = v(_index, _target);
18694			}
18695			return v == null ? d : typeof v === "string" && v.charAt(1) === "=" ? parseInt(v.charAt(0) + "1", 10) * parseFloat(v.substr(2)) + d : parseFloat(v) || 0;
18696		},
18697
18698
18699		/**
18700   * @private Translates strings like "40deg" or "40" or 40rad" or "+=40deg" or "270_short" or "-90_cw" or "+=45_ccw" to a numeric radian angle. Of course a starting/default value must be fed in too so that relative values can be calculated properly.
18701   * @param {Object} v Value to be parsed
18702   * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
18703   * @param {string=} p property name for directionalEnd (optional - only used when the parsed value is directional ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation). Property name would be "rotation", "rotationX", or "rotationY"
18704   * @param {Object=} directionalEnd An object that will store the raw end values for directional angles ("_short", "_cw", or "_ccw" suffix). We need a way to store the uncompensated value so that at the end of the tween, we set it to exactly what was requested with no directional compensation.
18705   * @return {number} parsed angle in radians
18706   */
18707		_parseAngle = function (v, d, p, directionalEnd) {
18708			var min = 0.000001,
18709			    cap,
18710			    split,
18711			    dif,
18712			    result,
18713			    isRelative;
18714			if (typeof v === "function") {
18715				v = v(_index, _target);
18716			}
18717			if (v == null) {
18718				result = d;
18719			} else if (typeof v === "number") {
18720				result = v;
18721			} else {
18722				cap = 360;
18723				split = v.split("_");
18724				isRelative = v.charAt(1) === "=";
18725				dif = (isRelative ? parseInt(v.charAt(0) + "1", 10) * parseFloat(split[0].substr(2)) : parseFloat(split[0])) * (v.indexOf("rad") === -1 ? 1 : _RAD2DEG) - (isRelative ? 0 : d);
18726				if (split.length) {
18727					if (directionalEnd) {
18728						directionalEnd[p] = d + dif;
18729					}
18730					if (v.indexOf("short") !== -1) {
18731						dif = dif % cap;
18732						if (dif !== dif % (cap / 2)) {
18733							dif = dif < 0 ? dif + cap : dif - cap;
18734						}
18735					}
18736					if (v.indexOf("_cw") !== -1 && dif < 0) {
18737						dif = (dif + cap * 9999999999) % cap - (dif / cap | 0) * cap;
18738					} else if (v.indexOf("ccw") !== -1 && dif > 0) {
18739						dif = (dif - cap * 9999999999) % cap - (dif / cap | 0) * cap;
18740					}
18741				}
18742				result = d + dif;
18743			}
18744			if (result < min && result > -min) {
18745				result = 0;
18746			}
18747			return result;
18748		},
18749		    _colorLookup = { aqua: [0, 255, 255],
18750			lime: [0, 255, 0],
18751			silver: [192, 192, 192],
18752			black: [0, 0, 0],
18753			maroon: [128, 0, 0],
18754			teal: [0, 128, 128],
18755			blue: [0, 0, 255],
18756			navy: [0, 0, 128],
18757			white: [255, 255, 255],
18758			fuchsia: [255, 0, 255],
18759			olive: [128, 128, 0],
18760			yellow: [255, 255, 0],
18761			orange: [255, 165, 0],
18762			gray: [128, 128, 128],
18763			purple: [128, 0, 128],
18764			green: [0, 128, 0],
18765			red: [255, 0, 0],
18766			pink: [255, 192, 203],
18767			cyan: [0, 255, 255],
18768			transparent: [255, 255, 255, 0] },
18769		    _hue = function (h, m1, m2) {
18770			h = h < 0 ? h + 1 : h > 1 ? h - 1 : h;
18771			return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < 0.5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * 255 + 0.5 | 0;
18772		},
18773
18774
18775		/**
18776   * @private Parses a color (like #9F0, #FF9900, rgb(255,51,153) or hsl(108, 50%, 10%)) into an array with 3 elements for red, green, and blue or if toHSL parameter is true, it will populate the array with hue, saturation, and lightness values. If a relative value is found in an hsl() or hsla() string, it will preserve those relative prefixes and all the values in the array will be strings instead of numbers (in all other cases it will be populated with numbers).
18777   * @param {(string|number)} v The value the should be parsed which could be a string like #9F0 or rgb(255,102,51) or rgba(255,0,0,0.5) or it could be a number like 0xFF00CC or even a named color like red, blue, purple, etc.
18778   * @param {(boolean)} toHSL If true, an hsl() or hsla() value will be returned instead of rgb() or rgba()
18779   * @return {Array.<number>} An array containing red, green, and blue (and optionally alpha) in that order, or if the toHSL parameter was true, the array will contain hue, saturation and lightness (and optionally alpha) in that order. Always numbers unless there's a relative prefix found in an hsl() or hsla() string and toHSL is true.
18780   */
18781		_parseColor = CSSPlugin.parseColor = function (v, toHSL) {
18782			var a, r, g, b, h, s, l, max, min, d, wasHSL;
18783			if (!v) {
18784				a = _colorLookup.black;
18785			} else if (typeof v === "number") {
18786				a = [v >> 16, v >> 8 & 255, v & 255];
18787			} else {
18788				if (v.charAt(v.length - 1) === ",") {
18789					//sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)" - in this example "blue," has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value.
18790					v = v.substr(0, v.length - 1);
18791				}
18792				if (_colorLookup[v]) {
18793					a = _colorLookup[v];
18794				} else if (v.charAt(0) === "#") {
18795					if (v.length === 4) {
18796						//for shorthand like #9F0
18797						r = v.charAt(1);
18798						g = v.charAt(2);
18799						b = v.charAt(3);
18800						v = "#" + r + r + g + g + b + b;
18801					}
18802					v = parseInt(v.substr(1), 16);
18803					a = [v >> 16, v >> 8 & 255, v & 255];
18804				} else if (v.substr(0, 3) === "hsl") {
18805					a = wasHSL = v.match(_numExp);
18806					if (!toHSL) {
18807						h = Number(a[0]) % 360 / 360;
18808						s = Number(a[1]) / 100;
18809						l = Number(a[2]) / 100;
18810						g = l <= 0.5 ? l * (s + 1) : l + s - l * s;
18811						r = l * 2 - g;
18812						if (a.length > 3) {
18813							a[3] = Number(a[3]);
18814						}
18815						a[0] = _hue(h + 1 / 3, r, g);
18816						a[1] = _hue(h, r, g);
18817						a[2] = _hue(h - 1 / 3, r, g);
18818					} else if (v.indexOf("=") !== -1) {
18819						//if relative values are found, just return the raw strings with the relative prefixes in place.
18820						return v.match(_relNumExp);
18821					}
18822				} else {
18823					a = v.match(_numExp) || _colorLookup.transparent;
18824				}
18825				a[0] = Number(a[0]);
18826				a[1] = Number(a[1]);
18827				a[2] = Number(a[2]);
18828				if (a.length > 3) {
18829					a[3] = Number(a[3]);
18830				}
18831			}
18832			if (toHSL && !wasHSL) {
18833				r = a[0] / 255;
18834				g = a[1] / 255;
18835				b = a[2] / 255;
18836				max = Math.max(r, g, b);
18837				min = Math.min(r, g, b);
18838				l = (max + min) / 2;
18839				if (max === min) {
18840					h = s = 0;
18841				} else {
18842					d = max - min;
18843					s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
18844					h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
18845					h *= 60;
18846				}
18847				a[0] = h + 0.5 | 0;
18848				a[1] = s * 100 + 0.5 | 0;
18849				a[2] = l * 100 + 0.5 | 0;
18850			}
18851			return a;
18852		},
18853		    _formatColors = function (s, toHSL) {
18854			var colors = s.match(_colorExp) || [],
18855			    charIndex = 0,
18856			    parsed = "",
18857			    i,
18858			    color,
18859			    temp;
18860			if (!colors.length) {
18861				return s;
18862			}
18863			for (i = 0; i < colors.length; i++) {
18864				color = colors[i];
18865				temp = s.substr(charIndex, s.indexOf(color, charIndex) - charIndex);
18866				charIndex += temp.length + color.length;
18867				color = _parseColor(color, toHSL);
18868				if (color.length === 3) {
18869					color.push(1);
18870				}
18871				parsed += temp + (toHSL ? "hsla(" + color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : "rgba(" + color.
18871join(",")) + ")";
18872			}
18873			return parsed + s.substr(charIndex);
18874		},
18875		    _colorExp = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3}){1,2}\\b"; //we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc.
18876
18877		for (p in _colorLookup) {
18878			_colorExp += "|" + p + "\\b";
18879		}
18880		_colorExp = new RegExp(_colorExp + ")", "gi");
18881
18882		CSSPlugin.colorStringFilter = function (a) {
18883			var combined = a[0] + " " + a[1],
18884			    toHSL;
18885			if (_colorExp.test(combined)) {
18886				toHSL = combined.indexOf("hsl(") !== -1 || combined.indexOf("hsla(") !== -1;
18887				a[0] = _formatColors(a[0], toHSL);
18888				a[1] = _formatColors(a[1], toHSL);
18889			}
18890			_colorExp.lastIndex = 0;
18891		};
18892
18893		if (!TweenLite.defaultStringFilter) {
18894			TweenLite.defaultStringFilter = CSSPlugin.colorStringFilter;
18895		}
18896
18897		/**
18898   * @private Returns a formatter function that handles taking a string (or number in some cases) and returning a consistently formatted one in terms of delimiters, quantity of values, etc. For example, we may get boxShadow values defined as "0px red" or "0px 0px 10px rgb(255,0,0)" or "0px 0px 20px 20px #F00" and we need to ensure that what we get back is described with 4 numbers and a color. This allows us to feed it into the _parseComplex() method and split the values up appropriately. The neat thing about this _getFormatter() function is that the dflt defines a pattern as well as a default, so for example, _getFormatter("0px 0px 0px 0px #777", true) not only sets the default as 0px for all distances and #777 for the color, but also sets the pattern such that 4 numbers and a color will always get returned.
18899   * @param {!string} dflt The default value and pattern to follow. So "0px 0px 0px 0px #777" will ensure that 4 numbers and a color will always get returned.
18900   * @param {boolean=} clr If true, the values should be searched for color-related data. For example, boxShadow values typically contain a color whereas borderRadius don't.
18901   * @param {boolean=} collapsible If true, the value is a top/left/right/bottom style one that acts like margin or padding, where if only one value is received, it's used for all 4; if 2 are received, the first is duplicated for 3rd (bottom) and the 2nd is duplicated for the 4th spot (left), etc.
18902   * @return {Function} formatter function
18903   */
18904		var _getFormatter = function (dflt, clr, collapsible, multi) {
18905			if (dflt == null) {
18906				return function (v) {
18907					return v;
18908				};
18909			}
18910			var dColor = clr ? (dflt.match(_colorExp) || [""])[0] : "",
18911			    dVals = dflt.split(dColor).join("").match(_valuesExp) || [],
18912			    pfx = dflt.substr(0, dflt.indexOf(dVals[0])),
18913			    sfx = dflt.charAt(dflt.length - 1) === ")" ? ")" : "",
18914			    delim = dflt.indexOf(" ") !== -1 ? " " : ",",
18915			    numVals = dVals.length,
18916			    dSfx = numVals > 0 ? dVals[0].replace(_numExp, "") : "",
18917			    formatter;
18918			if (!numVals) {
18919				return function (v) {
18920					return v;
18921				};
18922			}
18923			if (clr) {
18924				formatter = function (v) {
18925					var color, vals, i, a;
18926					if (typeof v === "number") {
18927						v += dSfx;
18928					} else if (multi && _commasOutsideParenExp.test(v)) {
18929						a = v.replace(_commasOutsideParenExp, "|").split("|");
18930						for (i = 0; i < a.length; i++) {
18931							a[i] = formatter(a[i]);
18932						}
18933						return a.join(",");
18934					}
18935					color = (v.match(_colorExp) || [dColor])[0];
18936					vals = v.split(color).join("").match(_valuesExp) || [];
18937					i = vals.length;
18938					if (numVals > i--) {
18939						while (++i < numVals) {
18940							vals[i] = collapsible ? vals[(i - 1) / 2 | 0] : dVals[i];
18941						}
18942					}
18943					return pfx + vals.join(delim) + delim + color + sfx + (v.indexOf("inset") !== -1 ? " inset" : "");
18944				};
18945				return formatter;
18946			}
18947			formatter = function (v) {
18948				var vals, a, i;
18949				if (typeof v === "number") {
18950					v += dSfx;
18951				} else if (multi && _commasOutsideParenExp.test(v)) {
18952					a = v.replace(_commasOutsideParenExp, "|").split("|");
18953					for (i = 0; i < a.length; i++) {
18954						a[i] = formatter(a[i]);
18955					}
18956					return a.join(",");
18957				}
18958				vals = v.match(_valuesExp) || [];
18959				i = vals.length;
18960				if (numVals > i--) {
18961					while (++i < numVals) {
18962						vals[i] = collapsible ? vals[(i - 1) / 2 | 0] : dVals[i];
18963					}
18964				}
18965				return pfx + vals.join(delim) + sfx;
18966			};
18967			return formatter;
18968		},
18969
18970
18971		/**
18972   * @private returns a formatter function that's used for edge-related values like marginTop, marginLeft, paddingBottom, paddingRight, etc. Just pass a comma-delimited list of property names related to the edges.
18973   * @param {!string} props a comma-delimited list of property names in order from top to left, like "marginTop,marginRight,marginBottom,marginLeft"
18974   * @return {Function} a formatter function
18975   */
18976		_getEdgeParser = function (props) {
18977			props = props.split(",");
18978			return function (t, e, p, cssp, pt, plugin, vars) {
18979				var a = (e + "").split(" "),
18980				    i;
18981				vars = {};
18982				for (i = 0; i < 4; i++) {
18983					vars[props[i]] = a[i] = a[i] || a[(i - 1) / 2 >> 0];
18984				}
18985				return cssp.parse(t, vars, pt, plugin);
18986			};
18987		},
18988
18989
18990		// @private used when other plugins must tween values first, like BezierPlugin or ThrowPropsPlugin, etc. That plugin's setRatio() gets called first so that the values are updated, and then we loop through the MiniPropTweens which handle copying the values into their appropriate slots so that they can then be applied correctly in the main CSSPlugin setRatio() method. Remember, we typically create a proxy object that has a bunch of uniquely-named properties that we feed to the sub-plugin and it does its magic normally, and then we must interpret those values and apply them to the css because often numbers must get combined/concatenated, suffixes added, etc. to work with css, like boxShadow could have 4 values plus a color.
18991		_setPluginRatio = _internals._setPluginRatio = function (v) {
18992			this.plugin.setRatio(v);
18993			var d = this.data,
18994			    proxy = d.proxy,
18995			    mpt = d.firstMPT,
18996			    min = 0.000001,
18997			    val,
18998			    pt,
18999			    i,
19000			    str,
19001			    p;
19002			while (mpt) {
19003				val = proxy[mpt.v];
19004				if (mpt.r) {
19005					val = Math.round(val);
19006				} else if (val < min && val > -min) {
19007					val = 0;
19008				}
19009				mpt.t[mpt.p] = val;
19010				mpt = mpt._next;
19011			}
19012			if (d.autoRotate) {
19013				d.autoRotate.rotation = d.mod ? d.mod(proxy.rotation, this.t) : proxy.rotation; //special case for ModifyPlugin to hook into an auto-rotating bezier
19014			}
19015			//at the end, we must set the CSSPropTween's "e" (end) value dynamically here because that's what is used in the final setRatio() method. Same for "b" at the beginning.
19016			if (v === 1 || v === 0) {
19017				mpt = d.firstMPT;
19018				p = v === 1 ? "e" : "b";
19019				while (mpt) {
19020					pt = mpt.t;
19021					if (!pt.type) {
19022						pt[p] = pt.s + pt.xs0;
19023					} else if (pt.type === 1) {
19024						str = pt.xs0 + pt.s + pt.xs1;
19025						for (i = 1; i < pt.l; i++) {
19026							str += pt["xn" + i] + pt["xs" + (i + 1)];
19027						}
19028						pt[p] = str;
19029					}
19030					mpt = mpt._next;
19031				}
19032			}
19033		},
19034
19035
19036		/**
19037   * @private @constructor Used by a few SpecialProps to hold important values for proxies. For example, _parseToProxy() creates a MiniPropTween instance for each property that must get tweened on the proxy, and we record the original property name as well as the unique one we create for the proxy, plus whether or not the value needs to be roun
19037ded plus the original value.
19038   * @param {!Object} t target object whose property we're tweening (often a CSSPropTween)
19039   * @param {!string} p property name
19040   * @param {(number|string|object)} v value
19041   * @param {MiniPropTween=} next next MiniPropTween in the linked list
19042   * @param {boolean=} r if true, the tweened value should be rounded to the nearest integer
19043   */
19044		MiniPropTween = function (t, p, v, next, r) {
19045			this.t = t;
19046			this.p = p;
19047			this.v = v;
19048			this.r = r;
19049			if (next) {
19050				next._prev = this;
19051				this._next = next;
19052			}
19053		},
19054
19055
19056		/**
19057   * @private Most other plugins (like BezierPlugin and ThrowPropsPlugin and others) can only tween numeric values, but CSSPlugin must accommodate special values that have a bunch of extra data (like a suffix or strings between numeric values, etc.). For example, boxShadow has values like "10px 10px 20px 30px rgb(255,0,0)" which would utterly confuse other plugins. This method allows us to split that data apart and grab only the numeric data and attach it to uniquely-named properties of a generic proxy object ({}) so that we can feed that to virtually any plugin to have the numbers tweened. However, we must also keep track of which properties from the proxy go with which CSSPropTween values and instances. So we create a linked list of MiniPropTweens. Each one records a target (the original CSSPropTween), property (like "s" or "xn1" or "xn2") that we're tweening and the unique property name that was used for the proxy (like "boxShadow_xn1" and "boxShadow_xn2") and whether or not they need to be rounded. That way, in the _setPluginRatio() method we can simply copy the values over from the proxy to the CSSPropTween instance(s). Then, when the main CSSPlugin setRatio() method runs and applies the CSSPropTween values accordingly, they're updated nicely. So the external plugin tweens the numbers, _setPluginRatio() copies them over, and setRatio() acts normally, applying css-specific values to the element.
19058   * This method returns an object that has the following properties:
19059   *  - proxy: a generic object containing the starting values for all the properties that will be tweened by the external plugin.  This is what we feed to the external _onInitTween() as the target
19060   *  - end: a generic object containing the ending values for all the properties that will be tweened by the external plugin. This is what we feed to the external plugin's _onInitTween() as the destination values
19061   *  - firstMPT: the first MiniPropTween in the linked list
19062   *  - pt: the first CSSPropTween in the linked list that was created when parsing. If shallow is true, this linked list will NOT attach to the one passed into the _parseToProxy() as the "pt" (4th) parameter.
19063   * @param {!Object} t target object to be tweened
19064   * @param {!(Object|string)} vars the object containing the information about the tweening values (typically the end/destination values) that should be parsed
19065   * @param {!CSSPlugin} cssp The CSSPlugin instance
19066   * @param {CSSPropTween=} pt the next CSSPropTween in the linked list
19067   * @param {TweenPlugin=} plugin the external TweenPlugin instance that will be handling tweening the numeric values
19068   * @param {boolean=} shallow if true, the resulting linked list from the parse will NOT be attached to the CSSPropTween that was passed in as the "pt" (4th) parameter.
19069   * @return An object containing the following properties: proxy, end, firstMPT, and pt (see above for descriptions)
19070   */
19071		_parseToProxy = _internals._parseToProxy = function (t, vars, cssp, pt, plugin, shallow) {
19072			var bpt = pt,
19073			    start = {},
19074			    end = {},
19075			    transform = cssp._transform,
19076			    oldForce = _forcePT,
19077			    i,
19078			    p,
19079			    xp,
19080			    mpt,
19081			    firstPT;
19082			cssp._transform = null;
19083			_forcePT = vars;
19084			pt = firstPT = cssp.parse(t, vars, pt, plugin);
19085			_forcePT = oldForce;
19086			//break off from the linked list so the new ones are isolated.
19087			if (shallow) {
19088				cssp._transform = transform;
19089				if (bpt) {
19090					bpt._prev = null;
19091					if (bpt._prev) {
19092						bpt._prev._next = null;
19093					}
19094				}
19095			}
19096			while (pt && pt !== bpt) {
19097				if (pt.type <= 1) {
19098					p = pt.p;
19099					end[p] = pt.s + pt.c;
19100					start[p] = pt.s;
19101					if (!shallow) {
19102						mpt = new MiniPropTween(pt, "s", p, mpt, pt.r);
19103						pt.c = 0;
19104					}
19105					if (pt.type === 1) {
19106						i = pt.l;
19107						while (--i > 0) {
19108							xp = "xn" + i;
19109							p = pt.p + "_" + xp;
19110							end[p] = pt.data[xp];
19111							start[p] = pt[xp];
19112							if (!shallow) {
19113								mpt = new MiniPropTween(pt, xp, p, mpt, pt.rxp[xp]);
19114							}
19115						}
19116					}
19117				}
19118				pt = pt._next;
19119			}
19120			return { proxy: start, end: end, firstMPT: mpt, pt: firstPT };
19121		},
19122
19123
19124		/**
19125   * @constructor Each property that is tweened has at least one CSSPropTween associated with it. These instances store important information like the target, property, starting value, amount of change, etc. They can also optionally have a number of "extra" strings and numeric values named xs1, xn1, xs2, xn2, xs3, xn3, etc. where "s" indicates string and "n" indicates number. These can be pieced together in a complex-value tween (type:1) that has alternating types of data like a string, number, string, number, etc. For example, boxShadow could be "5px 5px 8px rgb(102, 102, 51)". In that value, there are 6 numbers that may need to tween and then pieced back together into a string again with spaces, suffixes, etc. xs0 is special in that it stores the suffix for standard (type:0) tweens, -OR- the first string (prefix) in a complex-value (type:1) CSSPropTween -OR- it can be the non-tweening value in a type:-1 CSSPropTween. We do this to conserve memory.
19126   * CSSPropTweens have the following optional properties as well (not defined through the constructor):
19127   *  - l: Length in terms of the number of extra properties that the CSSPropTween has (default: 0). For example, for a boxShadow we may need to tween 5 numbers in which case l would be 5; Keep in mind that the start/end values for the first number that's tweened are always stored in the s and c properties to conserve memory. All additional values thereafter are stored in xn1, xn2, etc.
19128   *  - xfirst: The first instance of any sub-CSSPropTweens that are tweening properties of this instance. For example, we may split up a boxShadow tween so that there's a main CSSPropTween of type:1 that has various xs* and xn* values associated with the h-shadow, v-shadow, blur, color, etc. Then we spawn a CSSPropTween for each of those that has a higher priority and runs BEFORE the main CSSPropTween so that the values are all set by the time it needs to re-assemble them. The xfirst gives us an easy way to identify the first one in that chain which typically ends at the main one (because they're all prepende to the linked list)
19129   *  - plugin: The TweenPlugin instance that will handle the tweening of any complex values. For example, sometimes we don't want to use normal subt
19129weens (like xfirst refers to) to tween the values - we might want ThrowPropsPlugin or BezierPlugin some other plugin to do the actual tweening, so we create a plugin instance and store a reference here. We need this reference so that if we get a request to round values or disable a tween, we can pass along that request.
19130   *  - data: Arbitrary data that needs to be stored with the CSSPropTween. Typically if we're going to have a plugin handle the tweening of a complex-value tween, we create a generic object that stores the END values that we're tweening to and the CSSPropTween's xs1, xs2, etc. have the starting values. We store that object as data. That way, we can simply pass that object to the plugin and use the CSSPropTween as the target.
19131   *  - setRatio: Only used for type:2 tweens that require custom functionality. In this case, we call the CSSPropTween's setRatio() method and pass the ratio each time the tween updates. This isn't quite as efficient as doing things directly in the CSSPlugin's setRatio() method, but it's very convenient and flexible.
19132   * @param {!Object} t Target object whose property will be tweened. Often a DOM element, but not always. It could be anything.
19133   * @param {string} p Property to tween (name). For example, to tween element.width, p would be "width".
19134   * @param {number} s Starting numeric value
19135   * @param {number} c Change in numeric value over the course of the entire tween. For example, if element.width starts at 5 and should end at 100, c would be 95.
19136   * @param {CSSPropTween=} next The next CSSPropTween in the linked list. If one is defined, we will define its _prev as the new instance, and the new instance's _next will be pointed at it.
19137   * @param {number=} type The type of CSSPropTween where -1 = a non-tweening value, 0 = a standard simple tween, 1 = a complex value (like one that has multiple numbers in a comma- or space-delimited string like border:"1px solid red"), and 2 = one that uses a custom setRatio function that does all of the work of applying the values on each update.
19138   * @param {string=} n Name of the property that should be used for overwriting purposes which is typically the same as p but not always. For example, we may need to create a subtween for the 2nd part of a "clip:rect(...)" tween in which case "p" might be xs1 but "n" is still "clip"
19139   * @param {boolean=} r If true, the value(s) should be rounded
19140   * @param {number=} pr Priority in the linked list order. Higher priority CSSPropTweens will be updated before lower priority ones. The default priority is 0.
19141   * @param {string=} b Beginning value. We store this to ensure that it is EXACTLY what it was when the tween began without any risk of interpretation issues.
19142   * @param {string=} e Ending value. We store this to ensure that it is EXACTLY what the user defined at the end of the tween without any risk of interpretation issues.
19143   */
19144		CSSPropTween = _internals.CSSPropTween = function (t, p, s, c, next, type, n, r, pr, b, e) {
19145			this.t = t; //target
19146			this.p = p; //property
19147			this.s = s; //starting value
19148			this.c = c; //change value
19149			this.n = n || p; //name that this CSSPropTween should be associated to (usually the same as p, but not always - n is what overwriting looks at)
19150			if (!(t instanceof CSSPropTween)) {
19151				_overwriteProps.push(this.n);
19152			}
19153			this.r = r; //round (boolean)
19154			this.type = type || 0; //0 = normal tween, -1 = non-tweening (in which case xs0 will be applied to the target's property, like tp.t[tp.p] = tp.xs0), 1 = complex-value SpecialProp, 2 = custom setRatio() that does all the work
19155			if (pr) {
19156				this.pr = pr;
19157				_hasPriority = true;
19158			}
19159			this.b = b === undefined ? s : b;
19160			this.e = e === undefined ? s + c : e;
19161			if (next) {
19162				this._next = next;
19163				next._prev = this;
19164			}
19165		},
19166		    _addNonTweeningNumericPT = function (target, prop, start, end, next, overwriteProp) {
19167			//cleans up some code redundancies and helps minification. Just a fast way to add a NUMERIC non-tweening CSSPropTween
19168			var pt = new CSSPropTween(target, prop, start, end - start, next, -1, over
19168writeProp);
19169			pt.b = start;
19170			pt.e = pt.xs0 = end;
19171			return pt;
19172		},
19173
19174
19175		/**
19176   * Takes a target, the beginning value and ending value (as strings) and parses them into a CSSPropTween (possibly with child CSSPropTweens) that accommodates multiple numbers, colors, comma-delimited values, etc. For example:
19177   * sp.parseComplex(element, "boxShadow", "5px 10px 20px rgb(255,102,51)", "0px 0px 0px red", true, "0px 0px 0px rgb(0,0,0,0)", pt);
19178   * It will walk through the beginning and ending values (which should be in the same format with the same number and type of values) and figure out which parts are numbers, what strings separate the numeric/tweenable values, and then create the CSSPropTweens accordingly. If a plugin is defined, no child CSSPropTweens will be created. Instead, the ending values will be stored in the "data" property of the returned CSSPropTween like: {s:-5, xn1:-10, xn2:-20, xn3:255, xn4:0, xn5:0} so that it can be fed to any other plugin and it'll be plain numeric tweens but the recomposition of the complex value will be handled inside CSSPlugin's setRatio().
19179   * If a setRatio is defined, the type of the CSSPropTween will be set to 2 and recomposition of the values will be the responsibility of that method.
19180   *
19181   * @param {!Object} t Target whose property will be tweened
19182   * @param {!string} p Property that will be tweened (its name, like "left" or "backgroundColor" or "boxShadow")
19183   * @param {string} b Beginning value
19184   * @param {string} e Ending value
19185   * @param {boolean} clrs If true, the value could contain a color value like "rgb(255,0,0)" or "#F00" or "red". The default is false, so no colors will be recognized (a performance optimization)
19186   * @param {(string|number|Object)} dflt The default beginning value that should be used if no valid beginning value is defined or if the number of values inside the complex beginning and ending values don't match
19187   * @param {?CSSPropTween} pt CSSPropTween instance that is the current head of the linked list (we'll prepend to this).
19188   * @param {number=} pr Priority in the linked list order. Higher priority properties will be updated before lower priority ones. The default priority is 0.
19189   * @param {TweenPlugin=} plugin If a plugin should handle the tweening of extra properties, pass the plugin instance here. If one is defined, then NO subtweens will be created for any extra properties (the properties will be created - just not additional CSSPropTween instances to tween them) because the plugin is expected to do so. However, the end values WILL be populated in the "data" property, like {s:100, xn1:50, xn2:300}
19190   * @param {function(number)=} setRatio If values should be set in a custom function instead of being pieced together in a type:1 (complex-value) CSSPropTween, define that custom function here.
19191   * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parseComplex() call.
19192   */
19193		_parseComplex = CSSPlugin.parseComplex = function (t, p, b, e, clrs, dflt, pt, pr, plugin, setRatio) {
19194			//DEBUG: _log("parseComplex: "+p+", b: "+b+", e: "+e);
19195			b = b || dflt || "";
19196			if (typeof e === "function") {
19197				e = e(_index, _target);
19198			}
19199			pt = new CSSPropTween(t, p, 0, 0, pt, setRatio ? 2 : 1, null, false, pr, b, e);
19200			e += ""; //ensures it's a string
19201			if (clrs && _colorExp.test(e + b)) {
19202				//if colors are found, normalize the formatting to rgba() or hsla().
19203				e = [b, e];
19204				CSSPlugin.colorStringFilter(e);
19205				b = e[0];
19206				e = e[1];
19207			}
19208			var ba = b.split(", ").join(",").split(" "),
19209			    //beginning array
19210			ea = e.split(", ").join(",").split(" "),
19211			    //ending array
19212			l = ba.length,
19213			    autoRound = _autoRound !== false,
19214			    i,
19215			    xi,
19216			    ni,
19217			    bv,
19218			    ev,
19219			    bnums,
19220			    enums,
19221			    bn,
19222			    hasAlpha,
19223			    temp,
19224			    cv,
19225			    str,
19226			    useHSL;
19227			if (e.indexOf(",") !== -1 || b.indexOf(",") !== -1) {
19228				if ((e + b).indexOf("rgb") !== -1 || (e + b).indexOf("hsl") !== -1) {
19229					//keep rgb(), rgba(), hsl(), and hsla() values together! (remember, we're splitting on spaces)
19230					ba = ba.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
19231					ea = ea.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
19232				} else {
19233					ba = ba.join(" ").split(",").join(", ").split(" ");
19234					ea = ea.join(" ").split(",").join(", ").split(" ");
19235				}
19236				l = ba.length;
19237			}
19238			if (l !== ea.length) {
19239				//DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
19240				ba = (dflt || "").split(" ");
19241				l = ba.length;
19242			}
19243			pt.plugin = plugin;
19244			pt.setRatio = setRatio;
19245			_colorExp.lastIndex = 0;
19246			for (i = 0; i < l; i++) {
19247				bv = ba[i];
19248				ev = ea[i];
19249				bn = parseFloat(bv);
19250				//if the value begins with a number (most common). It's fine if it has a suffix like px
19251				if (bn || bn === 0) {
19252					pt.appendXtra("", bn, _parseChange(ev, bn), ev.replace(_relNumExp, ""), autoRound && ev.indexOf("px") !== -1, true);
19253
19254					//if the value is a color
19255				} else if (clrs && _colorExp.test(bv)) {
19256					str = ev.indexOf(")") + 1;
19257					str = ")" + (str ? ev.substr(str) : ""); //if there's a comma or ) at the end, retain it.
19258					useHSL = ev.indexOf("hsl") !== -1 && _supportsOpacity;
19259					temp = ev; //original string value so we can look for any prefix later.
19260					bv = _parseColor(bv, useHSL);
19261					ev = _parseColor(ev, useHSL);
19262					hasAlpha = bv.length + ev.length > 6;
19263					if (hasAlpha && !_supportsOpacity && ev[3] === 0) {
19264						//older versions of IE don't support rgba(), so if the destination alpha is 0, just use "transparent" for the end color
19265						pt["xs" + pt.l] += pt.l ? " transparent" : "transparent";
19266						pt.e = pt.e.split(ea[i]).join("transparent");
19267					} else {
19268						if (!_supportsOpacity) {
19269							//old versions of IE don't support rgba().
19270							hasAlpha = false;
19271						}
19272						if (useHSL) {
19273							pt.appendXtra(temp.substr(0, temp.indexOf("hsl")) + (hasAlpha ? "hsla(" : "hsl("), bv[0], _parseChange(ev[0], bv[0]), ",", false, true).appendXtra("", bv[1], _parseChange(ev[1], bv[1]), "%,", false).appendXtra("", bv[2], _parseChange(ev[2], bv[2]), hasAlpha ? "%," : "%" + str, false);
19274						} else {
19275							pt.appendXtra(temp.substr(0, temp.indexOf("rgb")) + (hasAlpha ? "rgba(" : "rgb("), bv[0], ev[0] - bv[0], ",", true, true).appendXtra("", bv[1], ev[1] - bv[1], ",", true).appendXtra("", bv[2], ev[2] - bv[2], hasAlpha ? "," : str, true);
19276						}
19277
19278						if (hasAlpha) {
19279							bv = bv.length < 4 ? 1 : bv[3];
19280							pt.appendXtra("", bv, (ev.length < 4 ? 1 : ev[3]) - bv, str, false);
19281						}
19282					}
19283					_colorExp.lastIndex = 0; //otherwise the test() on the RegExp could move the lastIndex and taint future results.
19284				} else {
19285					bnums = bv.match(_numExp); //gets each group of numbers in the beginning value string and drops them into an array
19286
19287					//if no number is found, treat it as a non-tweening value and just append the string to the current xs.
19288					if (!bnums) {
19289						pt["xs" + pt.l] += pt.l || pt["xs" + pt.l] ? " " + ev : ev;
19290
19291						//loop through all the numbers that are found and construct the extra values on the pt.
19292					} else {
19293						enums = ev.match(_relNumExp); //get each group of numbers in the end value string and drop them into an array. We allow relative values too, like +=50 or -=.5
19294						if (!enums || enums.length !== bnums.length) {
19295							//DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
19296							return pt;
19297						}
19298						ni = 0;
19299						for (xi = 0; xi < bnums.length; xi++) {
19300							cv = bnums[xi];
19301							temp = bv.indexOf(cv, ni);
19302							pt.appendXtra(bv.substr(ni, temp - ni), Number(cv), _parseChange(enums[xi], cv), "", autoRound && bv.substr(temp + cv.length, 2) === "px", xi === 0);
19303							ni = temp + cv.length;
19304						}
19305						pt["xs" + pt.l] += bv.substr(ni);
19306					}
19307				}
19308			}
19309			//if there are relative values ("+=" or "-=" prefix), we need to adjust the ending value to eliminate the prefixes and combine the values properly.
19310			if (e.indexOf("=") !== -1) if (pt.data) {
19311				str = pt.xs0 + pt.data.s;
19312				for (i = 1; i < pt.l; i++) {
19313					str += pt["xs" + i] + pt.data["xn" + i];
19314				}
19315				pt.e = str + pt["xs" + i];
19316			}
19317			if (!pt.l) {
19318				pt.type = -1;
19319				pt.xs0 = pt.e;
19320			}
19321			return pt.xfirst || pt;
19322		},
19323		    i = 9;
19324
19325		p = CSSPropTween.prototype;
19326		p.l = p.pr = 0; //length (number of extra properties like xn1, xn2, xn3, etc.
19327		while (--i > 0) {
19328			p["xn" + i] = 0;
19329			p["xs" + i] = "";
19330		}
19331		p.xs0 = "";
19332		p._next = p._prev = p.xfirst = p.data = p.plugin = p.setRatio = p.rxp = null;
19333
19334		/**
19335   * Appends and extra tweening value to a CSSPropTween and automatically manages any prefix and suffix strings. The first extra value is stored in the s and c of the main CSSPropTween instance, but thereafter any extras are stored in the xn1, xn2, xn3, etc. The prefixes and suffixes are stored in the xs0, xs1, xs2, etc. properties. For example, if I walk through a clip value like "rect(10px, 5px, 0px, 20px)", the values would be stored like this:
19336   * xs0:"rect(", s:10, xs1:"px, ", xn1:5, xs2:"px, ", xn2:0, xs3:"px, ", xn3:20, xn4:"px)"
19337   * And they'd all get joined together when the CSSPlugin renders (in the setRatio() method).
19338   * @param {string=} pfx Prefix (if any)
19339   * @param {!number} s Starting value
19340   * @param {!number} c Change in numeric value over the course of the entire tween. For example, if the start is 5 and the end is 100, the change would be 95.
19341   * @param {string=} sfx Suffix (if any)
19342   * @param {boolean=} r Round (if true).
19343   * @param {boolean=} pad If true, this extra value should be separated by the previous one by a space. If there is no previous extra and pad is true, it will automatically drop the space.
19344   * @return {CSSPropTween} returns itself so that multiple methods can be chained together.
19345   */
19346		p.appendXtra = function (pfx, s, c, sfx, r, pad) {
19347			var pt = this,
19348			    l = pt.l;
19349			pt["xs" + l] += pad && (l || pt["xs" + l]) ? " " + pfx : pfx || "";
19350			if (!c) if (l !== 0 && !pt.plugin) {
19351				//typically we'll combine non-changing values right into the xs to optimize performance, but we don't combine them when there's a plugin that will be tweening the values because it may depend on the values being split apart, like for a bezier, if a value doesn't change between the first and second iteration but then it does on the 3rd, we'll run into trouble because there's no xn slot for that value!
19352				pt["xs" + l] += s + (sfx || "");
19353				return pt;
19354			}
19355			pt.l++;
19356			pt.type = pt.setRatio ? 2 : 1;
19357			pt["xs" + pt.l] = sfx || "";
19358			if (l > 0) {
19359				pt.data["xn" + l] = s + c;
19360				pt.rxp["xn" + l] = r; //round extra property (we need to tap into this in the _parseToProxy() method)
19361				pt["xn" + l] = s;
19362				if (!pt.plugin) {
19363					pt.xfirst = new CSSPropTween(pt, "xn" + l, s, c, pt.xfirst || pt, 0, pt.n, r, pt.pr);
19364					pt.xfirst.xs0 = 0; //just to ensure that the property stays numeric which helps modern browsers speed up processing. Remember, in the setRatio() method, we do pt.t[pt.p] = val + pt.xs0 so if pt.xs0 is "" (the default), it'll cast the end value as a string. When a property is a number sometimes and a string sometimes, it prevents the compiler from locking in the data type, slowing things down slightly.
19365				}
19366				return pt;
19367			}
19368			pt.data = { s: s + c };
19369			pt.rxp = {};
19370			pt.s = s;
19371			pt.c = c;
19372			pt.r = r;
19373			return pt;
19374		};
19375
19376		/**
19377   * @constructor A SpecialProp is basically a css property that needs to be treated in a non-standard way, like if it may contain a complex value like boxShadow:"5px 10px 15px rgb(255, 102, 51)" or if it is associated with another plugin like ThrowPropsPlugin or BezierPlugin. Every SpecialProp is associated with a particular property name like "boxShadow" or "throwProps" or "bezier" and it will intercept those values in the vars object that's passed to the CSSPlugin and handle them accordingly.
19378   * @param {!string} p Property name (like "boxShadow" or "throwProps")
19379   * @param {Object=}
19379 options An object containing any of the following configuration options:
19380   *                      - defaultValue: the default value
19381   *                      - parser: A function that should be called when the associated property name is found in the vars. This function should return a CSSPropTween instance and it should ensure that it is properly inserted into the linked list. It will receive 4 paramters: 1) The target, 2) The value defined in the vars, 3) The CSSPlugin instance (whose _firstPT should be used for the linked list), and 4) A computed style object if one was calculated (this is a speed optimization that allows retrieval of starting values quicker)
19382   *                      - formatter: a function that formats any value received for this special property (for example, boxShadow could take "5px 5px red" and format it to "5px 5px 0px 0px red" so that both the beginning and ending values have a common order and quantity of values.)
19383   *                      - prefix: if true, we'll determine whether or not this property requires a vendor prefix (like Webkit or Moz or ms or O)
19384   *                      - color: set this to true if the value for this SpecialProp may contain color-related values like rgb(), rgba(), etc.
19385   *                      - priority: priority in the linked list order. Higher priority SpecialProps will be updated before lower priority ones. The default priority is 0.
19386   *                      - multi: if true, the formatter should accommodate a comma-delimited list of values, like boxShadow could have multiple boxShadows listed out.
19387   *                      - collapsible: if true, the formatter should treat the value like it's a top/right/bottom/left value that could be collapsed, like "5px" would apply to all, "5px, 10px" would use 5px for top/bottom and 10px for right/left, etc.
19388   *                      - keyword: a special keyword that can [optionally] be found inside the value (like "inset" for boxShadow). This allows us to validate beginning/ending values to make sure they match (if the keyword is found in one, it'll be added to the other for consistency by default).
19389   */
19390		var SpecialProp = function (p, options) {
19391			options = options || {};
19392			this.p = options.prefix ? _checkPropPrefix(p) || p : p;
19393			_specialProps[p] = _specialProps[this.p] = this;
19394			this.format = options.formatter || _getFormatter(options.defaultValue, options.color, options.collapsible, options.multi);
19395			if (options.parser) {
19396				this.parse = options.parser;
19397			}
19398			this.clrs = options.color;
19399			this.multi = options.multi;
19400			this.keyword = options.keyword;
19401			this.dflt = options.defaultValue;
19402			this.pr = options.priority || 0;
19403		},
19404
19405
19406		//shortcut for creating a new SpecialProp that can accept multiple properties as a comma-delimited list (helps minification). dflt can be an array for multiple values (we don't do a comma-delimited list because the default value may contain commas, like rect(0px,0px,0px,0px)). We attach this method to the SpecialProp class/object instead of using a private _createSpecialProp() method so that we can tap into it externally if necessary, like from another plugin.
19407		_registerComplexSpecialProp = _internals._registerComplexSpecialProp = function (p, options, defaults) {
19408			if (typeof options !== "object") {
19409				options = { parser: defaults }; //to make backwards compatible with older versions of BezierPlugin and ThrowPropsPlugin
19410			}
19411			var a = p.split(","),
19412			    d = options.defaultValue,
19413			    i,
19414			    temp;
19415			defaults = defaults || [d];
19416			for (i = 0; i < a.length; i++) {
19417				options.prefix = i === 0 && options.prefix;
19418				options.defaultValue = defaults[i] || d;
19419				temp = new SpecialProp(a[i], options);
19420			}
19421		},
19422
19423
19424		//creates a placeholder special prop for a plugin so that the property gets caught the first time a tween of it is attempted, and at that time it makes the plugin register itself, thus taking over for all future tweens of that property. This allows us to not mandate that things load in a particular order and it also allows us to log() an error that informs the user when they attempt to tween an external plugin-related property without loading its .js file.
19425		_registerPluginProp = _internals._registerPluginProp = function (p) {
19426			if (!_specialProps[p]) {
19427				var pluginName = p.charAt(0).toUpperCase() + p.substr(1) + "Plugin";
19428				_registerComplexSpecialProp(p, { parser: function (t, e, p, cssp, pt, plugin, vars) {
19429						var pluginClass = _globals.com.greensock.plugins[pluginName];
19430						if (!pluginClass) {
19431							_log("Error: " + pluginName + " js file not loaded.");
19432							return pt;
19433						}
19434						pluginClass._cssRegister();
19435						return _specialProps[p].parse(t, e, p, cssp, pt, plugin, vars);
19436					} });
19437			}
19438		};
19439
19440		p = SpecialProp.prototype;
19441
19442		/**
19443   * Alias for _parseComplex() that automatically plugs in certain values for this SpecialProp, like its property name, whether or not colors should be sensed, the default value, and priority. It also looks for any keyword that the SpecialProp defines (like "inset" for boxSh
19443adow) and ensures that the beginning and ending values have the same number of values for SpecialProps where multi is true (like boxShadow and textShadow can have a comma-delimited list)
19444   * @param {!Object} t target element
19445   * @param {(string|number|object)} b beginning value
19446   * @param {(string|number|object)} e ending (destination) value
19447   * @param {CSSPropTween=} pt next CSSPropTween in the linked list
19448   * @param {TweenPlugin=} plugin If another plugin will be tweening the complex value, that TweenPlugin instance goes here.
19449   * @param {function=} setRatio If a custom setRatio() method should be used to handle this complex value, that goes here.
19450   * @return {CSSPropTween=} First CSSPropTween in the linked list
19451   */
19452		p.parseComplex = function (t, b, e, pt, plugin, setRatio) {
19453			var kwd = this.keyword,
19454			    i,
19455			    ba,
19456			    ea,
19457			    l,
19458			    bi,
19459			    ei;
19460			//if this SpecialProp's value can contain a comma-delimited list of values (like boxShadow or textShadow), we must parse them in a special way, and look for a keyword (like "inset" for boxShadow) and ensure that the beginning and ending BOTH have it if the end defines it as such. We also must ensure that there are an equal number of values specified (we can't tween 1 boxShadow to 3 for example)
19461			if (this.multi) if (_commasOutsideParenExp.test(e) || _commasOutsideParenExp.test(b)) {
19462				ba = b.replace(_commasOutsideParenExp, "|").split("|");
19463				ea = e.replace(_commasOutsideParenExp, "|").split("|");
19464			} else if (kwd) {
19465				ba = [b];
19466				ea = [e];
19467			}
19468			if (ea) {
19469				l = ea.length > ba.length ? ea.length : ba.length;
19470				for (i = 0; i < l; i++) {
19471					b = ba[i] = ba[i] || this.dflt;
19472					e = ea[i] = ea[i] || this.dflt;
19473					if (kwd) {
19474						bi = b.indexOf(kwd);
19475						ei = e.indexOf(kwd);
19476						if (bi !== ei) {
19477							if (ei === -1) {
19478								//if the keyword isn't in the end value, remove it from the beginning one.
19479								ba[i] = ba[i].split(kwd).join("");
19480							} else if (bi === -1) {
19481								//if the keyword isn't in the beginning, add it.
19482								ba[i] += " " + kwd;
19483							}
19484						}
19485					}
19486				}
19487				b = ba.join(", ");
19488				e = ea.join(", ");
19489			}
19490			return _parseComplex(t, this.p, b, e, this.clrs, this.dflt, pt, this.pr, plugin, setRatio);
19491		};
19492
19493		/**
19494   * Accepts a target and end value and spits back a CSSPropTween that has been inserted into the CSSPlugin's linked list and conforms with all the conventions we use internally, like type:-1, 0, 1, or 2, setting up any extra property tweens, priority, etc. For example, if we have a boxShadow SpecialProp and call:
19495   * this._firstPT = sp.parse(element, "5px 10px 20px rgb(2550,102,51)", "boxShadow", this);
19496   * It should figure out the starting value of the element's boxShadow, compare it to the provided end value and create all the necessary CSSPropTweens of the appropriate types to tween the boxShadow. The CSSPropTween that gets spit back should already be inserted into the linked list (the 4th parameter is the current head, so prepend to that).
19497   * @param {!Object} t Target object whose property is being tweened
19498   * @param {Object} e End value as provided in the vars object (typically a string, but not always - like a throwProps would be an object).
19499   * @param {!string} p Property name
19500   * @param {!CSSPlugin} cssp The CSSPlugin instance that should be associated with this tween.
19501   * @param {?CSSPropTween} pt The CSSPropTween that is the current head of the linked list (we'll prepend to it)
19502   * @param {TweenPlugin=} plugin If a plugin will be used to tween the parsed value, this is the plugin instance.
19503   * @param {Object=} vars Original vars object that contains the data for parsing.
19504   * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parse() call.
19505   */
19506		p.parse = function (t, e, p, cssp, pt, plugin, vars) {
19507			return this.parseComplex(t.style, this.format(_getStyle(t, this.p, _cs, false, this.dflt)), this.format(e), pt, plugin);
19508		};
19509
19510		/**
19511   * Registers a special property that should be intercepted from any "css" objects defined in tweens. This allows you to handle them however you want without CSSPlugin doing it for you. The 2nd parameter should be a function that accepts 3 parameters:
19512   *  1) Target object whose property should be tweened (typically a DOM element)
19513   *  2) The end/destination value (could be a string, number, object, or whatever you want)
19514   *  3) The tween instance (you probably don't need to worry about this, but it can be useful for looking up information like the duration)
19515   *
19516   * Then, your function should return a function which will be called each time the tween gets rendered, passing a numeric "ratio" parameter to your function that indicates the change factor (usually between 0 and 1). For example:
19517   *
19518   * CSSPlugin.registerSpecialProp("myCustomProp", function(target, value, tween) {
19519   *      var start = target.style.width;
19520   *      return function(ratio) {
19521   *              target.style.width = (start + value * ratio) + "px";
19522   *              console.log("set width to " + target.style.width);
19523   *          }
19524   * }, 0);
19525   *
19526   * Then, when I do this tween, it will trigger my special property:
19527   *
19528   * TweenLite.to(element, 1, {css:{myCustomProp:100}});
19529   *
19530   * In the example, of course, we're just changing the width, but you can do anything you want.
19531   *
19532   * @param {!string} name Property name (or comma-delimited list of property names) that should be intercepted and handled by your function. For example, if I define "myCustomProp", then it would handle that portion of the following tween: TweenLite.to(element, 1, {css:{myCustomProp:100}})
19533   * @param {!function(Object, Object, Object, string):function(number)} onInitTween The function that will be called when a tween of this special property is performed. The function will receive 4 parameters: 1) Target object that should be tweened, 2) Value that was passed to the tween, 3) The tween instance itself (rarely used), and 4) The property name that's being tweened. Your function should return a function that should be called on every update of the tween. That function will receive a single parameter that is a "change factor" value (typically between 0 and 1) indicating the amount of change as a ratio. You can use this to determine how to set the values appropriately in your function.
19534   * @param {number=} priority Priority that helps the engine determine the order in which to set the properties (default: 0). Higher priority properties will be updated before lower priority ones.
19535   */
19536		CSSPlugin.registerSpecialProp = function (name, onInitTween, priority) {
19537			_registerComplexSpecialProp(name, { parser: function (t, e, p, cssp, pt, plugin, vars) {
19538					var rv = new CSSPropTween(t, p, 0, 0, pt, 2, p, false, priority);
19539					rv.plugin = plugin;
19540					rv.setRatio = onInitTween(t, e, cssp._tween, p);
19541					return rv;
19542				}, priority: priority });
19543		};
19544
19545		//transform-related methods and properties
19546		CSSPlugin.useSVGTransformAttr = true; //Safari and Firefox both have some rendering bugs when applying CSS transforms to SVG elements, so default to using the "transform" attribute instead (users can override this).
19547		var _transformProps = "scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent".split(","),
19548		    _transformProp = _checkPropPrefix("transform"),
19549		    //the Javascript (camelCase) transform property, like msTransform, WebkitTransform, MozTransform, or OTransform.
19550		_transformPropCSS = _prefixCSS + "transform",
19551		    _transformOriginProp = _checkPropPrefix("transformOrigin"),
19552		    _supports3D = _checkPropPrefix("perspective") !== null,
19553		    Transform = _internals.Transform = function () {
19554			this.perspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0;
19555			this.force3D = CSSPlugin.defaultForce3D === false || !_supports3D ? false : CSSPlugin.defaultForce3D || "auto";
19556		},
19557		    _SVGElement = _gsScope.SVGElement,
19558		    _useSVGTransformAttr,
19559
19560		//Some browsers (like Firefox and IE) don't honor transform-origin properly in SVG elements, so we need to manually adjust the matrix accordingly. We feature detect here rather than always doing the conversion for certain browsers because they may fix the problem at some point in the future.
19561
19562		_createSVG = function (type, container, attributes) {
19563			var element = _doc.createElementNS("http://www.w3.org/2000/svg", type),
19564			    reg = /([a-z])([A-Z])/g,
19565			    p;
19566			for (p in attributes) {
19567				element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]);
19568			}
19569			container.appendChild(element);
19570			return element;
19571		},
19572		    _docElement = _doc.documentElement || {},
19573		    _forceSVGTransformAttr = function () {
19574			//IE and Android stock don't support CSS transforms on SVG elements, so we must write them to the "transform" attribute. We populate this variable in the _parseTransform() method, and only if/when we come across an SVG element
19575			var force = _ieVers || /Android/i.test(_agent) && !_gsScope.chrome,
19576			    svg,
19577			    rect,
19578			    width;
19579			if (_doc.createElementNS && !force) {
19580				//IE8 and earlier doesn't support SVG anyway
19581				svg = _createSVG("svg", _docElement);
19582				rect = _createSVG("rect", svg, { width: 100, height: 50, x: 100 });
19583				width = rect.getBoundingClientRect().width;
19584				rect.style[_transformOriginProp] = "50% 50%";
19585				rect.style[_transformProp] = "scaleX(0.5)";
19586				force = width === rect.getBoundingClientRect().width && !(_is
19586Firefox && _supports3D); //note: Firefox fails the test even though it does support CSS transforms in 3D. Since we can't push 3D stuff into the transform attribute, we force Firefox to pass the test here (as long as it does truly support 3D).
19587				_docElement.removeChild(svg);
19588			}
19589			return force;
19590		}(),
19591		    _parseSVGOrigin = function (e, local, decoratee, absolute, smoothOrigin, skipRecord) {
19592			var tm = e._gsTransform,
19593			    m = _getMatrix(e, true),
19594			    v,
19595			    x,
19596			    y,
19597			    xOrigin,
19598			    yOrigin,
19599			    a,
19600			    b,
19601			    c,
19602			    d,
19603			    tx,
19604			    ty,
19605			    determinant,
19606			    xOriginOld,
19607			    yOriginOld;
19608			if (tm) {
19609				xOriginOld = tm.xOrigin; //record the original values before we alter them.
19610				yOriginOld = tm.yOrigin;
19611			}
19612			if (!absolute || (v = absolute.split(" ")).length < 2) {
19613				b = e.getBBox();
19614				if (b.x === 0 && b.y === 0 && b.width + b.height === 0) {
19615					//some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case.
19616					b = { x: parseFloat(e.hasAttribute("x") ? e.getAttribute("x") : e.hasAttribute("cx") ? e.getAttribute("cx") : 0) || 0, y: parseFloat(e.hasAttribute("y") ? e.getAttribute("y") : e.hasAttribute("cy") ? e.getAttribute("cy") : 0) || 0, width: 0, height: 0 };
19617				}
19618				local = _parsePosition(local).split(" ");
19619				v = [(local[0].indexOf("%") !== -1 ? parseFloat(local[0]) / 100 * b.width : parseFloat(local[0])) + b.x, (local[1].indexOf("%") !== -1 ? parseFloat(local[1]) / 100 * b.height : parseFloat(local[1])) + b.y];
19620			}
19621			decoratee.xOrigin = xOrigin = parseFloat(v[0]);
19622			decoratee.yOrigin = yOrigin = parseFloat(v[1]);
19623			if (absolute && m !== _identity2DMatrix) {
19624				//if svgOrigin is being set, we must invert the matrix and determine where the absolute point is, factoring in the current transforms. Otherwise, the svgOrigin would be based on the element's non-transformed position on the canvas.
19625				a = m[0];
19626				b = m[1];
19627				c = m[2];
19628				d = m[3];
19629				tx = m[4];
19630				ty = m[5];
19631				determinant = a * d - b * c;
19632				if (determinant) {
19633					//if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.
19634					x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;
19635					y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;
19636					xOrigin = decoratee.xOrigin = v[0] = x;
19637					yOrigin = decoratee.yOrigin = v[1] = y;
19638				}
19639			}
19640			if (tm) {
19641				//avoid jump when transformOrigin is changed - adjust the x/y values accordingly
19642				if (skipRecord) {
19643					decoratee.xOffset = tm.xOffset;
19644					decoratee.yOffset = tm.yOffset;
19645					tm = decoratee;
19646				}
19647				if (smoothOrigin || smoothOrigin !== false && CSSPlugin.defaultSmoothOrigin !== false) {
19648					x = xOrigin - xOriginOld;
19649					y = yOrigin - yOriginOld;
19650					//originally, we simply adjusted the x and y values, but that would cause problems if, for example, you created a rotational tween part-way through an x/y tween. Managing the offset in a separate variable gives us ultimate flexibility.
19651					//tm.x -= x - (x * m[0] + y * m[2]);
19652					//tm.y -= y - (x * m[1] + y * m[3]);
19653					tm.xOffset += x * m[0] + y * m[2] - x;
19654					tm.yOffset += x * m[1] + y * m[3] - y;
19655				} else {
19656					tm.xOffset = tm.yOffset = 0;
19657				}
19658			}
19659			if (!skipRecord) {
19660				e.setAttribute("data-svg-origin", v.join(" "));
19661			}
19662		},
19663		    _getBBoxHack = function (swapIfPossible) {
19664			//works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a <defs> element and/or <mask>. We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it).
19665			var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"),
19666			    oldParent = this.parentNode,
19667			    oldSibling = this.nextSibling,
19668			    oldCSS = this.style.cssText,
19669			    bbox;
19670			_docElement.appendChild(svg);
19671			svg.appendChild(this);
19672			this.style.display = "block";
19673			if (swapIfPossible) {
19674				try {
19675					bbox = this.getBBox();
19676					this._originalGetBBox = this.getBBox;
19677					this.getBBox = _getBBoxHack;
19678				} catch (e) {}
19679			} else if (this._originalGetBBox) {
19680				bbox = this._originalGetBBox();
19681			}
19682			if (oldSibling) {
19683				oldParent.insertBefore(this, oldSibling);
19684			} else {
19685				oldParent.appendChild(this);
19686			}
19687			_docElement.removeChild(svg);
19688			this.style.cssText = oldCSS;
19689			return bbox;
19690		},
19691		    _getBBox = function (e) {
19692			try {
19693				return e.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a <symbol> or <defs>). https://bugzilla.mozilla.org/show_bug.cgi?id=612118
19694			} catch (error) {
19695				return _getBBoxHack.call(e, true);
19696			}
19697		},
19698		    _isSVG = function (e) {
19699			//reports if the element is an SVG on which getBBox() actually works
19700			return !!(_SVGElement && e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));
19701		},
19702		    _identity2DMatrix = [1, 0, 0, 1, 0, 0],
19703		    _getMatrix = function (e, force2D) {
19704			var tm = e._gsTransform || new Transform(),
19705			    rnd = 100000,
19706			    style = e.style,
19707			    isDefault,
19708			    s,
19709			    m,
19710			    n,
19711			    dec,
19712			    none;
19713			if (_transformProp) {
19714				s = _getStyle(e, _transformPropCSS, null, true);
19715			} else if (e.currentStyle) {
19716				//for older versions of IE, we need to interpret the filter portion that is in the format: progid:DXImageTransform.Microsoft.Matrix(M11=6.123233995736766e-17, M12=-1, M21=1, M22=6.123233995736766e-17, sizingMethod='auto expand') Notice that we need to swap b and c compared to a normal matrix.
19717				s = e.currentStyle.filter.match(_ieGetMatrixExp);
19718				s = s && s.length === 4 ? [s[0].substr(4), Number(s[2].substr(4)), Number(s[1].substr(4)), s[3].substr(4), tm.x || 0, tm.y || 0].join(",") : "";
19719			}
19720			isDefault = !s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)";
19721			if (_transformProp && ((none = !_getComputedStyle(e) || _getComputedStyle(e).display === "none") || !e.parentNode)) {
19722				//note: Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397
19723				if (none) {
19724					//browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not "none". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px).
19725					n = style.display;
19726					style.display = "block";
19727				}
19728				if (!e.parentNode) {
19729					dec = 1; //flag
19730					_docElement.appendChild(e);
19731				}
19732				s = _getStyle(e, _transformPropCSS, null, true);
19733				isDefault = !s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)";
19734				if (n) {
19735					style.display = n;
19736				} else if (none) {
19737					_removeProp(style, "display");
19738				}
19739				if (dec) {
19740					_docElement.removeChild(e);
19741				}
19742			}
19743			if (tm.svg || e.getCTM && _isSVG(e)) {
19744				if (isDefault && (style[_transformProp] + "").indexOf("matrix") !== -1) {
19745					//some browsers (like Chrome 40) don't correctly report transforms that are applied inline on an SVG element (they don't get included in the computed style), so we double-check here and accept matrix values
19746					s = style[_transformProp];
19747					isDefault = 0;
19748				}
19749				m = e.getAttribute("transform");
19750				if (isDefault && m) {
19751					if (m.indexOf("matrix") !== -1) {
19752						//just in case there's a "transform" value specified as an attribute instead of CSS style. Accept either a matrix() or simple translate() value though.
19753						s = m;
19754						isDefault = 0;
19755					} else if (m.indexOf("translate") !== -1) {
19756						s = "matrix(1,0,0,1," + m.match(/(?:\-|\b)[\d\-\.e]+\b/gi).join(",") + ")";
19757						isDefault = 0;
19758					}
19759				}
19760			}
19761			if (isDefault) {
19762				return _identity2DMatrix;
19763			}
19764			//split the matrix values out into an array (m for matrix)
19765			m = (s || "").match(_numExp) || [];
19766			i = m.length;
19767			while (--i > -1) {
19768				n = Number(m[i]);
19769				m[i] = (dec = n - (n |= 0)) ? (dec * rnd + (dec < 0 ? -0.5 : 0.5) | 0) / rnd + n : n; //convert strings to Numbers and round to 5 decimal places to avoid issues with tiny numbers. Roughly 20x faster than Number.toFixed(). We also must make sure to round before dividing so that values like 0.9999999999 become 1 to avoid glitches in browser rendering and interpretation of flipped/rotated 3D matrices. And don't just multiply the number by rnd, floor it, and then divide by rnd because the bitwise operations max out at a 32-bit signed integer, thus it could get clipped at a relatively low value (like 22,000.00000 for example).
19770			}
19771			return force2D && m.length > 6 ? [m[0], m[1], m[4], m[5], m[12], m[13]] : m;
19772		},
19773
19774
19775		/**
19776   * Parses the transform values for an element, returning an object with x, y, z, scaleX, scaleY, scaleZ, rotation, rotationX, rotationY, skewX, and skewY properties. Note: by default (for performance reasons), all skewing is combined into skewX and rotation but skewY still has a place in the transform object so that we can record how much of the skew is attributed to skewX vs skewY. Remember, a skewY of 10 looks the same as a rotation of 10 and skewX of -10.
19777   * @param {!Object} t target element
19778   * @param {Object=} cs computed style object (optional)
19779   * @param {boolean=} rec if true, the transform values will be recorded to the target element's _gsTransform object, like target._gsTransform = {x:0, y:0, z:0, scaleX:1...}
19780   * @param {boolean=} parse if true, we'll ignore any _gsTransform values that already exist on the element, and force a reparsing of the css (calculated style)
19781   * @return {object}
19781 object containing all of the transform properties/values like {x:0, y:0, z:0, scaleX:1...}
19782   */
19783		_getTransform = _internals.getTransform = function (t, cs, rec, parse) {
19784			if (t._gsTransform && rec && !parse) {
19785				return t._gsTransform; //if the element already has a _gsTransform, use that. Note: some browsers don't accurately return the calculated style for the transform (particularly for SVG), so it's almost always safest to just use the values we've already applied rather than re-parsing things.
19786			}
19787			var tm = rec ? t._gsTransform || new Transform() : new Transform(),
19788			    invX = tm.scaleX < 0,
19789			    //in order to interpret things properly, we need to know if the user applied a negative scaleX previously so that we can adjust the rotation and skewX accordingly. Otherwise, if we always interpret a flipped matrix as affecting scaleY and the user only wants to tween the scaleX on multiple sequential tweens, it would keep the negative scaleY without that being the user's intent.
19790			min = 0.00002,
19791			    rnd = 100000,
19792			    zOrigin = _supports3D ? parseFloat(_getStyle(t, _transformOriginProp, cs, false, "0 0 0").split(" ")[2]) || tm.zOrigin || 0 : 0,
19793			    defaultTransformPerspective = parseFloat(CSSPlugin.defaultTransformPerspective) || 0,
19794			    m,
19795			    i,
19796			    scaleX,
19797			    scaleY,
19798			    rotation,
19799			    skewX;
19800
19801			tm.svg = !!(t.getCTM && _isSVG(t));
19802			if (tm.svg) {
19803				_parseSVGOrigin(t, _getStyle(t, _transformOriginProp, cs, false, "50% 50%") + "", tm, t.getAttribute("data-svg-origin"));
19804				_useSVGTransformAttr = CSSPlugin.useSVGTransformAttr || _forceSVGTransformAttr;
19805			}
19806			m = _getMatrix(t);
19807			if (m !== _identity2DMatrix) {
19808
19809				if (m.length === 16) {
19810					//we'll only look at these position-related 6 variables first because if x/y/z all match, it's relatively safe to assume we don't need to re-parse everything which risks losing important rotational information (like rotationX:180 plus rotationY:180 would look the same as rotation:180 - there's no way to know for sure which direction was taken based solely on the matrix3d() values)
19811					var a11 = m[0],
19812					    a21 = m[1],
19813					    a31 = m[2],
19814					    a41 = m[3],
19815					    a12 = m[4],
19816					    a22 = m[5],
19817					    a32 = m[6],
19818					    a42 = m[7],
19819					    a13 = m[8],
19820					    a23 = m[9],
19821					    a33 = m[10],
19822					    a14 = m[12],
19823					    a24 = m[13],
19824					    a34 = m[14],
19825					    a43 = m[11],
19826					    angle = Math.atan2(a32, a33),
19827					    t1,
19828					    t2,
19829					    t3,
19830					    t4,
19831					    cos,
19832					    sin;
19833					//we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari
19834					if (tm.zOrigin) {
19835						a34 = -tm.zOrigin;
19836						a14 = a13 * a34 - m[12];
19837						a24 = a23 * a34 - m[13];
19838						a34 = a33 * a34 + tm.zOrigin - m[14];
19839					}
19840					//note for possible future consolidation: rotationX: Math.atan2(a32, a33), rotationY: Math.atan2(-a31, Math.sqrt(a33 * a33 + a32 * a32)), rotation: Math.atan2(a21, a11), skew: Math.atan2(a12, a22). However, it doesn't seem to be quite as reliable as the full-on backwards rotation procedure.
19841					tm.rotationX = angle * _RAD2DEG;
19842					//rotationX
19843					if (angle) {
19844						cos = Math.cos(-angle);
19845						sin = Math.sin(-angle);
19846						t1 = a12 * cos + a13 * sin;
19847						t2 = a22 * cos + a23 * sin;
19848						t3 = a32 * cos + a33 * sin;
19849						a13 = a12 * -sin + a13 * cos;
19850						a23 = a22 * -sin + a23 * cos;
19851						a33 = a32 * -sin + a33 * cos;
19852						a43 = a42 * -sin + a43 * cos;
19853						a12 = t1;
19854						a22 = t2;
19855						a32 = t3;
19856					}
19857					//rotationY
19858					angle = Math.atan2(-a31, a33);
19859					tm.rotationY = angle * _RAD2DEG;
19860					if (angle) {
19861						cos = Math.cos(-angle);
19862						sin = Math.sin(-angle);
19863						t1 = a11 * cos - a13 * sin;
19864						t2 = a21 * cos - a23 * sin;
19865						t3 = a31 * cos - a33 * sin;
19866						a23 = a21 * sin + a23 * cos;
19867						a33 = a31 * sin + a33 * cos;
19868						a43 = a41 * sin + a43 * cos;
19869						a11 = t1;
19870						a21 = t2;
19871						a31 = t3;
19872					}
19873					//rotationZ
19874					angle = Math.atan2(a21, a11);
19875					tm.rotation = angle * _RAD2DEG;
19876					if (angle) {
19877						cos = Math.cos(angle);
19878						sin = Math.sin(angle);
19879						t1 = a11 * cos + a21 * sin;
19880						t2 = a12 * cos + a22 * sin;
19881						t3 = a13 * cos + a23 * sin;
19882						a21 = a21 * cos - a11 * sin;
19883						a22 = a22 * cos - a12 * sin;
19884						a23 = a23 * cos - a13 * sin;
19885						a11 = t1;
19886						a12 = t2;
19887						a13 = t3;
19888					}
19889
19890					if (tm.rotationX && Math.abs(tm.rotationX) + Math.abs(tm.rotation) > 359.9) {
19891						//when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here.
19892						tm.rotationX = tm.rotation = 0;
19893						tm.rotationY = 180 - tm.rotationY;
19894					}
19895
19896					//skewX
19897					angle = Math.atan2(a12, a22);
19898
19899					//scales
19900					tm.scaleX = (Math.sqrt(a11 * a11 + a21 * a21 + a31 * a31) * rnd + 0.5 | 0) / rnd;
19901					tm.scaleY = (Math.sqrt(a22 * a22 + a32 * a32) * rnd + 0.5 | 0) / rnd;
19902					tm.scaleZ = (Math.sqrt(a13 * a13 + a23 * a23 + a33 * a33) * rnd + 0.5 | 0) / rnd;
19903					a11 /= tm.scaleX;
19904					a12 /= tm.scaleY;
19905					a21 /= tm.scaleX;
19906					a22 /= tm.scaleY;
19907					if (Math.abs(angle) > min) {
19908						tm.skewX = angle * _RAD2DEG;
19909						a12 = 0;
19909 //unskews
19910						if (tm.skewType !== "simple") {
19911							tm.scaleY *= 1 / Math.cos(angle); //by default, we compensate the scale based on the skew so that the element maintains a similar proportion when skewed, so we have to alter the scaleY here accordingly to match the default (non-adjusted) skewing that CSS does (stretching more and more as it skews).
19912						}
19913					} else {
19914						tm.skewX = 0;
19915					}
19916
19917					/* //for testing purposes
19918     var transform = "matrix3d(",
19919     	comma = ",",
19920     	zero = "0";
19921     a13 /= tm.scaleZ;
19922     a23 /= tm.scaleZ;
19923     a31 /= tm.scaleX;
19924     a32 /= tm.scaleY;
19925     a33 /= tm.scaleZ;
19926     transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31);
19927     transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22);
19928     transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13);
19929     transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma;
19930     transform += a14 + comma + a24 + comma + a34 + comma + (tm.perspective ? (1 + (-a34 / tm.perspective)) : 1) + ")";
19931     console.log(transform);
19932     document.querySelector(".test").style[_transformProp] = transform;
19933     */
19934
19935					tm.perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;
19936					tm.x = a14;
19937					tm.y = a24;
19938					tm.z = a34;
19939					if (tm.svg) {
19940						tm.x -= tm.xOrigin - (tm.xOrigin * a11 - tm.yOrigin * a12);
19941						tm.y -= tm.yOrigin - (tm.yOrigin * a21 - tm.xOrigin * a22);
19942					}
19943				} else if (!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || !tm.rotationX && !tm.rotationY) {
19944					//sometimes a 6-element matrix is returned even when we performed 3D transforms, like if rotationX and rotationY are 180. In cases like this, we still need to honor the 3D transforms. If we just rely on the 2D info, it could affect how the data is interpreted, like scaleY might get set to -1 or rotation could get offset by 180 degrees. For example, do a TweenLite.to(element, 1, {css:{rotationX:180, rotationY:180}}) and then later, TweenLite.to(element, 1, {css:{rotationX:0}}) and without this conditional logic in place, it'd jump to a state of being unrotated when the 2nd tween starts. Then again, we need to honor the fact that the user COULD alter the transforms outside of CSSPlugin, like by manually applying new css, so we try to sense that by looking at x and y because if those changed, we know the changes were made outside CSSPlugin and we force a reinterpretation of the matrix values. Also, in Webkit browsers, if the element's "display" is "none", its calculated style value will always return empty, so if we've already recorded the values in the _gsTransform object, we'll just rely on those.
19945					var k = m.length >= 6,
19946					    a = k ? m[0] : 1,
19947					    b = m[1] || 0,
19948					    c = m[2] || 0,
19949					    d = k ? m[3] : 1;
19950					tm.x = m[4] || 0;
19951					tm.y = m[5] || 0;
19952					scaleX = Math.sqrt(a * a + b * b);
19953					scaleY = Math.sqrt(d * d + c * c);
19954					rotation = a || b ? Math.atan2(b, a) * _RAD2DEG : tm.rotation || 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist).
19955					skewX = c || d ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0;
19956					tm.scaleX = scaleX;
19957					tm.scaleY = scaleY;
19958					tm.rotation = rotation;
19959					tm.skewX = skewX;
19960					if (_supports3D) {
19961						tm.rotationX = tm.rotationY = tm.z = 0;
19962						tm.perspective = defaultTransformPerspective;
19963						tm.scaleZ = 1;
19964					}
19965					if (tm.svg) {
19966						tm.x -= tm.xOrigin - (tm.xOrigin * a + tm.yOrigin * c);
19967						tm.y -= tm.yOrigin - (tm.xOrigin * b + tm.yOrigin * d);
19968					}
19969				}
19970				if (Math.abs(tm.skewX) > 90 && Math.abs(tm.skewX) < 270) {
19971					if (invX) {
19972						tm.scaleX *= -1;
19973						tm.skewX += tm.rotation <= 0 ? 180 : -180;
19974						tm.rotation += tm.rotation <= 0 ? 180 : -180;
19975					} else {
19976						tm.scaleY *= -1;
19977						tm.skewX += tm.skewX <= 0 ? 180 : -180;
19978					}
19979				}
19980				tm.zOrigin = zOrigin;
19981				//some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 0 in these cases. The conditional logic here is faster than calling Math.abs(). Also, browsers tend to render a SLIGHTLY rotated object in a fuzzy way, so we need to snap to exactly 0 when appropriate.
19982				for (i in tm) {
19983					if (tm[i] < min) if (tm[i] > -min) {
19984						tm[i] = 0;
19985					}
19986				}
19987			}
19988			//DEBUG: _log("parsed rotation of " + t.getAttribute("id")+": "+(tm.rotationX)+", "+(tm.rotationY)+", "+(tm.rotation)+", scale: "+tm.scaleX+", "+tm.scaleY+", "+tm.scaleZ+", position: "+tm.x+", "+tm.y+", "+tm.z+", perspective: "+tm.perspective+ ", origin: "+ tm.xOrigin+ ","+ tm.yOrigin);
19989			if (rec) {
19990				t._gsTransform = tm; //record to the object's _gsTransform which we use so that tweens can control individual properties independently (we need all the properties to accurately recompose the matrix in the setRatio() method)
19991				if (tm.svg) {
19992					//if we're supposed to apply transforms to the SVG element's "transform" attribute, make sure there aren't any CSS transforms applied or they'll override the attribute ones. Also clear the transform attribute if we're using CSS, just to be clean.
19993					if (_useSVGTransformAttr && t.style[_transformProp]) {
19994						TweenLite.delayedCall(0.001, function () {
19995							//if we apply this right away (before anything has rendered), we risk there being no transforms for a brief moment and it also interferes with adjusting the transformOrigin in a tween with immediateRender:true (it'd try reading the matrix and it wouldn't have the appropriate data in place because we just removed it).
19996							_removeProp(t.style, _transformProp);
19997						});
19998					} else if (!_useSVGTransformAttr && t.getAttribute("transform")) {
19999						TweenLite.delayedCall(0.001, function () {
20000							t.removeAttribute("transform");
20001						});
20002					}
20003				}
20004			}
20005			return tm;
20006		},
20007
20008
20009		//for setting 2D transforms in IE6, IE7, and IE8 (must use a "filter" to emulate the behavior of modern day browser transforms)
20010		_setIETransformRatio = function (v) {
20011			var t = this.data,
20012			    //refers to the element's _gsTransform object
20013			ang = -t.rotation * _DEG2RAD,
20014			    skew = ang + t.skewX * _DEG2RAD,
20015			    rnd = 100000,
20016			    a = (Math.cos(ang) * t.scaleX * rnd | 0) / rnd,
20017			    b = (Math.sin(ang) * t.scaleX * rnd | 0) / rnd,
20018			    c = (Math.sin(skew) * -t.scaleY * rnd | 0) / rnd,
20019			    d = (Math.cos(skew) * t.scaleY * rnd | 0) / rnd,
20020			    style = this.t.style,
20021			    cs = this.t.currentStyle,
20022			    filters,
20023			    val;
20024			if (!cs) {
20025				return;
20026			}
20027			val = b; //just for swapping the variables an inverting them (reused "val" to avoid creating another variable in memory). IE's filter matrix uses a non-standard matrix configuration (angle goes the opposite way, and b and c are reversed and inverted)
20028			b = -c;
20029			c = -val;
20030			filters = cs.filter;
20031			style.filter = ""; //remove filters so that we can accurately measure offsetWidth/offsetHeight
20032			var w = this.t.offsetWidth,
20033			    h = this.t.offsetHeight,
20034			    clip = cs.position !== "absolute",
20035			    m = "progid:DXImageTransform.Microsoft.Matrix(M11=" + a + ", M12=" + b + ", M21=" + c + ", M22=" + d,
20036			    ox = t.x + w * t.xPercent / 100,
20037			    oy = t.y + h * t.yPercent / 100,
20038			    dx,
20039			    dy;
20040
20041			//if transformOrigin is being used, adjust the offset x and y
20042			if (t.ox != null) {
20043				dx = (t.oxp ? w * t.ox * 0.01 : t.ox) - w / 2;
20044				dy = (t.oyp ? h * t.oy * 0.01 : t.oy) - h / 2;
20045				ox += dx - (dx * a + dy * b);
20046				oy += dy - (dx * c + dy * d);
20047			}
20048
20049			if (!clip) {
20050				m += ", sizingMethod='auto expand')";
20051			} else {
20052				dx = w / 2;
20053				dy = h / 2;
20054				//translate to ensure that transformations occur around the correct origin (default is center).
20055				m += ", Dx=" + (dx - (dx * a + dy * b) + ox) + ", Dy=" + (dy - (dx * c + dy * d) + oy) + ")";
20056			}
20057			if (filters.indexOf("DXImageTransform.Microsoft.Matrix(") !== -1) {
20058				style.filter = filters.replace(_ieSetMatrixExp, m);
20059			} else {
20060				style.filter = m + " " + filters;
20060 //we must always put the transform/matrix FIRST (before alpha(opacity=xx)) to avoid an IE bug that slices part of the object when rotation is applied with alpha.
20061			}
20062
20063			//at the end or beginning of the tween, if the matrix is normal (1, 0, 0, 1) and opacity is 100 (or doesn't exist), remove the filter to improve browser performance.
20064			if (v === 0 || v === 1) if (a === 1) if (b === 0) if (c === 0) if (d === 1) if (!clip || m.indexOf("Dx=0, Dy=0") !== -1) if (!_opacityExp.test(filters) || parseFloat(RegExp.$1) === 100) if (filters.indexOf("gradient(" && filters.indexOf("Alpha")) === -1) {
20065				style.removeAttribute("filter");
20066			}
20067
20068			//we must set the margins AFTER applying the filter in order to avoid some bugs in IE8 that could (in rare scenarios) cause them to be ignored intermittently (vibration).
20069			if (!clip) {
20070				var mult = _ieVers < 8 ? 1 : -1,
20071				    //in Internet Explorer 7 and before, the box model is broken, causing the browser to treat the width/height of the actual rotated filtered image as the width/height of the box itself, but Microsoft corrected that in IE8. We must use a negative offset in IE8 on the right/bottom
20072				marg,
20073				    prop,
20074				    dif;
20075				dx = t.ieOffsetX || 0;
20076				dy = t.ieOffsetY || 0;
20077				t.ieOffsetX = Math.round((w - ((a < 0 ? -a : a) * w + (b < 0 ? -b : b) * h)) / 2 + ox);
20078				t.ieOffsetY = Math.round((h - ((d < 0 ? -d : d) * h + (c < 0 ? -c : c) * w)) / 2 + oy);
20079				for (i = 0; i < 4; i++) {
20080					prop = _margins[i];
20081					marg = cs[prop];
20082					//we need to get the current margin in case it is being tweened separately (we want to respect that tween's changes)
20083					val = marg.indexOf("px") !== -1 ? parseFloat(marg) : _convertToPixels(this.t, prop, parseFloat(marg), marg.replace(_suffixExp, "")) || 0;
20084					if (val !== t[prop]) {
20085						dif = i < 2 ? -t.ieOffsetX : -t.ieOffsetY; //if another tween is controlling a margin, we cannot only apply the difference in the ieOffsets, so we essentially zero-out the dx and dy here in that case. We record the margin(s) later so that we can keep comparing them, making this code very flexible.
20086					} else {
20087						dif = i < 2 ? dx - t.ieOffsetX : dy - t.ieOffsetY;
20088					}
20089					style[prop] = (t[prop] = Math.round(val - dif * (i === 0 || i === 2 ? 1 : mult))) + "px";
20090				}
20091			}
20092		},
20093
20094
20095		/* translates a super small decimal to a string WITHOUT scientific notation
20096  _safeDecimal = function(n) {
20097  	var s = (n < 0 ? -n : n) + "",
20098  		a = s.split("e-");
20099  	return (n < 0 ? "-0." : "0.") + new Array(parseInt(a[1], 10) || 0).join("0") + a[0].split(".").join("");
20100  },
20101  */
20102
20103		_setTransformRatio = _internals.set3DTransformRatio = _internals.setTransformRatio = function (v) {
20104			var t = this.data,
20105			    //refers to the element's _gsTransform object
20106			style = this.t.style,
20107			    angle = t.rotation,
20108			    rotationX = t.rotationX,
20109			    rotationY = t.rotationY,
20110			    sx = t.scaleX,
20111			    sy = t.scaleY,
20112			    sz = t.scaleZ,
20113			    x = t.x,
20114			    y = t.y,
20115			    z = t.z,
20116			    isSVG = t.svg,
20117			    perspective = t.perspective,
20118			    force3D = t.force3D,
20119			    skewY = t.skewY,
20120			    skewX = t.skewX,
20121			    t1,
20122			    a11,
20123			    a12,
20124			    a13,
20125			    a21,
20126			    a22,
20127			    a23,
20128			    a31,
20129			    a32,
20130			    a33,
20131			    a41,
20132			    a42,
20133			    a43,
20134			    zOrigin,
20135			    min,
20136			    cos,
20137			    sin,
20138			    t2,
20139			    transform,
20140			    comma,
20141			    zero,
20142			    skew,
20143			    rnd;
20144			if (skewY) {
20145				//for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees.
20146				skewX += skewY;
20147				angle += skewY;
20148			}
20149
20150			//check to see if we should render as 2D (and SVGs must use 2D when _useSVGTransformAttr is true)
20151			if (((v === 1 || v === 0) && force3D === "auto" && (this.tween._totalTime === this.tween._totalDuration || !this.tween._totalTime) || !force3D) && !z && !perspective && !rotationY && !rotationX && sz === 1 || _useSVGTransformAttr && isSVG || !_supports3D) {
20152				//on the final render (which could be 0 for a from tween), if there are no 3D aspects, render in 2D to free up memory and improve performance especially on mobile devices. Check the tween's totalTime/totalDuration too in order to make sure it doesn't happen between repeats if it's a repeating tween.
20153
20154				//2D
20155				if (angle || skewX || isSVG) {
20156					angle *= _DEG2RAD;
20157					skew = skewX * _DEG2RAD;
20158					rnd = 100000;
20159					a11 = Math.cos(angle) * sx;
20160					a21 = Math.sin(angle) * sx;
20161					a12 = Math.sin(angle - skew) * -sy;
20162					a22 = Math.cos(angle - skew) * sy;
20163					if (skew && t.skewType === "simple") {
20164						//by default, we compensate skewing on the other axis to make it look more natural, but you can set the skewType to "simple" to use the uncompensated skewing that CSS does
20165						t1 = Math.tan(skew - skewY * _DEG2RAD);
20166						t1 = Math.sqrt(1 + t1 * t1);
20167						a12 *= t1;
20168						a22 *= t1;
20169						if (skewY) {
20170							t1 = Math.tan(skewY * _DEG2RAD);
20171							t1 = Math.sqrt(1 + t1 * t1);
20172							a11 *= t1;
20173							a21 *= t1;
20174						}
20175					}
20176					if (isSVG) {
20177						x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
20178						y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
20179						if (_useSVGTransformAttr && (t.xPercent || t.yPercent)) {
20180							//The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the matrix to simulate it.
20181							min = this.t.getBBox();
20182							x += t.xPercent * 0.01 * min.width;
20183							y += t.yPercent * 0.01 * min.height;
20184						}
20185						min = 0.000001;
20186						if (x < min) if (x > -min) {
20187							x = 0;
20188						}
20189						if (y < min) if (y > -min) {
20190							y = 0;
20191						}
20192					}
20193					transform = (a11 * rnd | 0) / rnd + "," + (a21 * rnd | 0) / rnd + "," + (a12 * rnd | 0) / rnd + "," + (a22 * rnd | 0) / rnd + "," + x + "," + y + ")";
20194					if (isSVG && _useSVGTransformAttr) {
20195						this.t.setAttribute("transform", "matrix(" + transform);
20196					} else {
20197						//some browsers have a hard time with very small values like 2.4492935982947064e-16 (notice the "e-" towards the end) and would render the object slightly off. So we round to 5 decimal places.
20198						style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + transform;
20199					}
20200				} else {
20201					style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + sx + ",0,0," + sy + "," + x + "," + y + ")";
20202				}
20203				return;
20204			}
20205			if (_isFirefox) {
20206				//Firefox has a bug (at least in v25) that causes it to render the transparent part of 32-bit PNG images as black when displayed inside an iframe and the 3D scale is very small and doesn't change sufficiently enough between renders (like if you use a Power4.easeInOut to scale from 0 to 1 where the beginning values only change a tiny amount to begin the tween before accelerating). In this case, we force the scale to be 0.00002 instead which is visually the same but works around the Firefox issue.
20207				min = 0.0001;
20208				if (sx < min && sx > -min) {
20209					sx = sz = 0.00002;
20210				}
20211				if (sy < min && sy > -min) {
20212					sy = sz = 0.00002;
20213				}
20214				if (perspective && !t.z && !t.rotationX && !t.rotationY) {
20215					//Firefox has a bug that causes elements to have an odd super-thin, broken/dotted black border on elements that have a perspective set but aren't utilizing 3D space (no rotationX, rotationY, or z).
20216					perspective = 0;
20217				}
20218			}
20219			if (angle || skewX) {
20220				angle *= _DEG2RAD;
20221				cos = a11 = Math.cos(angle);
20222				sin = a21 = Math.sin(angle);
20223				if (skewX) {
20224					angle -= skewX * _DEG2RAD;
20225					cos = Math.cos(angle);
20226					sin = Math.sin(angle);
20227					if (t.skewType === "simple") {
20228						//by default, we compensate skewing on the other axis to make it look more natural, but you can set the skewType to "simple" to use the uncompensated skewing that CSS does
20229						t1 = Math.tan((skewX - skewY) * _DEG2RAD);
20230						t1 = Math.sqrt(1 + t1 * t1);
20231						cos *= t1;
20232						sin *= t1;
20233						if (t.skewY) {
20234							t1 = Math.tan(skewY * _DEG2RAD);
20235							t1 = Math.sqrt(1 + t1 * t1);
20236							a11 *= t1;
20237							a21 *= t1;
20238						}
20239					}
20240				}
20241				a12 = -sin;
20242				a22 = cos;
20243			} else if (!rotationY && !rotationX && sz === 1 && !perspective && !isSVG) {
20244				//if we're only translating and/or 2D scaling, this is faster...
20245				style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) translate3d(" : "translate3d(") + x + "px," + y + "px," + z + "px)" + (sx !== 1 || sy !== 1 ? " scale(" + sx + "," + sy + ")" : "");
20246				return;
20247			} else {
20248				a11 = a22 = 1;
20249				a12 = a21 = 0;
20250			}
20251			// KEY  INDEX   AFFECTS a[row][column]
20252			// a11  0       rotation, rotationY, scaleX
20253			// a21  1       rotation, rotationY, scaleX
20254			// a31  2       rotationY, scaleX
20255			// a41  3       rotationY, scaleX
20256			// a12  4       rotation, skewX, rotationX, scaleY
20257			// a22  5       rotation, skewX, rotationX, scaleY
20258			// a32  6       rotationX, scaleY
20259			// a42  7       rotationX, scaleY
20260			// a13  8       rotationY, rotationX, scaleZ
20261			// a23  9       rotationY, rotationX, scaleZ
20262			// a33  10      rotationY, rotationX, scaleZ
20263			// a43  11      rotationY, rotationX, perspective, scaleZ
20264			// a14  12      x, zOrigin, svgOrigin
20265			// a24  13      y, zOrigin, svgOrigin
20266			// a34  14      z, zOrigin
20267			// a44  15
20268			// rotation: Math.atan2(a21, a11)
20269			// rotationY: Math.atan2(a13, a33) (or Math.atan2(a13, a11))
20270			// rotationX: Math.atan2(a32, a33)
20271			a33 = 1;
20272			a13 = a23 = a31 = a32 = a41 = a42 = 0;
20273			a43 = perspective ? -1 / perspective : 0;
20274			zOrigin = t.zOrigin;
20275			min = 0.000001; //threshold below which browsers use scientific notation which won't work.
20276			comma = ",";
20277			zero = "0";
20278			angle = rotationY * _DEG2RAD;
20279			if (angle) {
20280				cos = Math.cos(angle);
20281				sin = Math.sin(angle);
20282				a31 = -sin;
20283				a41 = a43 * -sin;
20284				a13 = a11 * sin;
20285				a23 = a21 * sin;
20286				a33 = cos;
20287				a43 *= cos;
20288				a11 *= cos;
20289				a21 *= cos;
20290			}
20291			angle = rotationX * _DEG2RAD;
20292			if (angle) {
20293				cos = Math.cos(angle);
20294				sin = Math.sin(angle);
20295				t1 = a12 * cos + a13 * sin;
20296				t2 = a22 * cos + a23 * sin;
20297				a32 = a33 * sin;
20298				a42 = a43 * sin;
20299				a13 = a12 * -sin + a13 * cos;
20300				a23 = a22 * -sin + a23 * cos;
20301				a33 = a33 * cos;
20302				a43 = a43 * cos;
20303				a12 = t1;
20304				a22 = t2;
20305			}
20306			if (sz !== 1) {
20307				a13 *= sz;
20308				a23 *= sz;
20309				a33 *= sz;
20310				a43 *= sz;
20311			}
20312			if (sy !== 1) {
20313				a12 *= sy;
20314				a22 *= sy;
20315				a32 *= sy;
20316				a42 *= sy;
20317			}
20318			if (sx !== 1) {
20319				a11 *= sx;
20320				a21 *= sx;
20321				a31 *= sx;
20322				a41 *= sx;
20323			}
20324
20325			if (zOrigin || isSVG) {
20326				if (zOrigin) {
20327					x += a13 * -zOrigin;
20328					y += a23 * -zOrigin;
20329					z += a33 * -zOrigin + zOrigin;
20330				}
20331				if (isSVG) {
20332					//due to bugs in some browsers, we need to manage the transform-origin of SVG manually
20333					x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
20334					y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
20335				}
20336				if (x < min && x > -min) {
20337					x = zero;
20338				}
20339				if (y < min && y > -min) {
20340					y = zero;
20341				}
20342				if (z < min && z > -min) {
20343					z = 0; //don't use string because we calculate perspective later and need the number.
20344				}
20345			}
20346
20347			//optimized way of concatenating all the values into a string. If we do it all in one shot, it's slower because of the way browsers have to create temp strings and the way it affects memory. If we do it piece-by-piece with +=, it's a bit slower too. We found that doing it in these sized chunks works best overall:
20348			transform = t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix3d(" : "matrix3d(";
20349			transform += (a11 < min && a11 > -min ? zero : a11) + comma + (a21 < min && a21 > -min ? zero : a21) + comma + (a31 < min && a31 > -min ? zero : a31);
20350			transform += comma + (a41 < min && a41 > -min ? zero : a41) + comma + (a12 < min && a12 > -min ? zero : a12) + comma + (a22 < min && a22 > -min ? zero : a22);
20351			if (rotationX || rotationY || sz !== 1) {
20352				//performance optimization (often there's no rotationX or rotationY, so we can skip these calculations)
20353				transform += comma + (a32 < min && a32 > -min ? zero : a32) + comma + (a42 < min && a42 > -min ? zero : a42) + comma + (a13 < min && a13 > -min ? zero : a13);
20354				transform += comma + (a23 < min && a23 > -min ? zero : a23) + comma + (a33 < min && a33 > -min ? zero : a33) + comma + (a43 < min && a43 > -min ? zero : a43) + comma;
20355			} else {
20356				transform += ",0,0,0,0,1,0,";
20357			}
20358			transform += x + comma + y + comma + z + comma + (perspective ? 1 + -z / perspective : 1) + ")";
20359
20360			style[_transformProp] = transform;
20361		};
20362
20363		p = Transform.prototype;
20364		p.x = p.y = p.z = p.skewX = p.skewY = p.rotation = p.rotationX = p.rotationY = p.zOrigin = p.xPercent = p.yPercent = p.xOffset = p.yOffset = 0;
20365		p.scaleX = p.scaleY = p.scaleZ = 1;
20366
20367		_registerComplexSpecialProp("transform,scale,scaleX,scaleY,scaleZ,x,y,z,rotation,rotationX,rotationY,rotationZ,skewX,skewY,shortRotation,shortRotationX,shortRotationY,shortRotationZ,transformOrigin,svgOrigin,transformPerspective,directionalRotation,parseTransform,force3D,skewType,xPercent,yPercent,smoothOrigin", { parser: function (t, e, parsingProp, cssp, pt, plugin, vars) {
20368				if (cssp._lastParsedTransform === vars) {
20369					return pt;
20370				} //only need to parse the transform once, and only if the browser supports it.
20371				cssp._lastParsedTransform = vars;
20372				var scaleFunc = vars.scale && typeof vars.scale === "function" ? vars.scale : 0,
20373				    //if there's a function-based "scale" value, swap in the resulting numeric value temporarily. Otherwise, if it's called for both scaleX and scaleY independently, they may not match (like if the function uses Math.random()).
20374				swapFunc;
20375				if (typeof vars[parsingProp] === "function") {
20376					//whatever property triggers the initial parsing might be a function-based value in which case it already got called in parse(), thus we don't want to call it again in here. The most efficient way to avoid this is to temporarily swap the value directly into the vars object, and then after we do all our parsing in this function, we'll swap it back again.
20377					swapFunc = vars[parsingProp];
20378					vars[parsingProp] = e;
20379				}
20380				if (scaleFunc) {
20381					vars.scale = scaleFunc(_index, t);
20382				}
20383				var originalGSTransform = t._gsTransform,
20384				    style = t.style,
20385				    min = 0.000001,
20386				    i = _transformProps.length,
20387				    v = vars,
20388				    endRotations = {},
20389				    transformOriginString = "transformOrigin",
20390				    m1 = _getTransform(t, _cs, true, v.parseTransform),
20391				    orig = v.transform && (typeof v.transform === "function" ? v.transform(_index, _target) : v.transform),
20392				    m2,
20393				    copy,
20394				    has3D,
20395				    hasChange,
20396				    dr,
20397				    x,
20398				    y,
20399				    matrix,
20400				    p;
20401				m1.skewType = v.skewType || m1.skewType || CSSPlugin.defaultSkewType;
20402				cssp._transform = m1;
20403				if (orig && typeof orig === "string" && _transformProp) {
20404					//for values like transform:"rotate(60deg) scale(0.5, 0.8)"
20405					copy = _tempDiv.style; //don't use the original target because it might be SVG in which case some browsers don't report computed style correctly.
20406					copy[_transformProp] = orig;
20407					copy.display = "block"; //if display is "none", the browser often refuses to report the transform properties correctly.
20408					copy.position = "absolute";
20409					_doc.body.appendChild(_tempDiv);
20410					m2 = _getTransform(_tempDiv, null, false);
20411					if (m1.skewType === "simple") {
20412						//the default _getTransform() reports the skewX/scaleY as if skewType is "compensated", thus we need to adjust that here if skewType is "simple".
20413						m2.scaleY *= Math.cos(m2.skewX * _DEG2RAD);
20414					}
20415					if (m1.svg) {
20416						//if it's an SVG element, x/y part of the matrix will be affected by whatever we use as the origin and the offsets, so compensate here...
20417						x = m1.xOrigin;
20418						y = m1.yOrigin;
20419						m2.x -= m1.xOffset;
20420						m2.y -= m1.yOffset;
20421						if (v.transformOrigin || v.svgOrigin) {
20422							//if this tween is altering the origin, we must factor that in here. The actual work of recording the transformOrigin values and setting up the PropTween is done later (still inside this function) so we cannot leave the changes intact here - we only want to update the x/y accordingly.
20423							orig = {};
20424							_parseSVGOrigin(t, _parsePosition(v.transformOrigin), orig, v.svgOrigin, v.smoothOrigin, true);
20425							x = orig.xOrigin;
20426							y = orig.yOrigin;
20427							m2.x -= orig.xOffset - m1.xOffset;
20428							m2.y -= orig.yOffset - m1.yOffset;
20429						}
20430						if (x || y) {
20431							matrix = _getMatrix(_tempDiv, true);
20432							m2.x -= x - (x * matrix[0] + y * matrix[2]);
20433							m2.y -= y - (x * matrix[1] + y * matrix[3]);
20434						}
20435					}
20436					_doc.body.removeChild(_tempDiv);
20437					if (!m2.perspective) {
20438						m2.perspective = m1.perspective; //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.
20439					}
20440					if (v.xPercent != null) {
20441						m2.xPercent = _parseVal(v.xPercent, m1.xPercent);
20442					}
20443					if (v.yPercent != null) {
20444						m2.yPercent = _parseVal(v.yPercent, m1.yPercent);
20445					}
20446				} else if (typeof v === "object") {
20447					//for values like scaleX, scaleY, rotation, x, y, skewX, and skewY or transform:{...} (object)
20448					m2 = { scaleX: _parseVal(v.scaleX != null ? v.scaleX : v.scale, m1.scaleX),
20449						scaleY: _parseVal(v.scaleY != null ? v.scaleY : v.scale, m1.scaleY),
20450						scaleZ: _parseVal(v.scaleZ, m1.scaleZ),
20451						x: _parseVal(v.x, m1.x),
20452						y: _parseVal(v.y, m1.y),
20453						z: _parseVal(v.z, m1.z),
20454						xPercent: _parseVal(v.xPercent, m1.xPercent),
20455						yPercent: _parseVal(v.yPercent, m1.yPercent),
20456						perspective: _parseVal(v.transformPerspective, m1.perspective) };
20457					dr = v.directionalRotation;
20458					if (dr != null) {
20459						if (typeof dr === "object") {
20460							for (copy in dr) {
20461								v[copy] = dr[copy];
20462							}
20463						} else {
20464							v.rotation = dr;
20465						}
20466					}
20467					if (typeof v.x === "string" && v.x.indexOf("%") !== -1) {
20468						m2.x = 0;
20469						m2.xPercent = _parseVal(v.x, m1.xPercent);
20470					}
20471					if (typeof v.y === "string" && v.y.indexOf("%") !== -1) {
20472						m2.y = 0;
20473						m2.yPercent = _parseVal(v.y, m1.yPercent);
20474					}
20475
20476					m2.rotation = _parseAngle("rotation" in v ? v.rotation : "shortRotation" in v ? v.shortRotation + "_short" : "rotationZ" in v ? v.rotationZ : m1.rotation, m1.rotation, "rotation", endRotations);
20477					if (_supports3D) {
20478						m2.rotationX = _parseAngle("rotationX" in v ? v.rotationX : "shortRotationX" in v ? v.shortRotationX + "_short" : m1.rotationX || 0, m1.rotationX, "rotationX", endRotations);
20479						m2.rotationY = _parseAngle("rotationY" in v ? v.rotationY : "shortRotationY" in v ? v.shortRotationY + "_short" : m1.rotationY || 0, m1.rotationY, "rotationY", endRotations);
20480					}
20481					m2.skewX = _parseAngle(v.skewX, m1.skewX);
20482					m2.skewY = _parseAngle(v.skewY, m1.skewY);
20483				}
20484				if (_supports3D && v.force3D != null) {
20485					m1.force3D = v.force3D;
20486					hasChange = true;
20487				}
20488
20489				has3D = m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective;
20490				if (!has3D && v.scale != null) {
20491					m2.scaleZ = 1; //no need to tween scaleZ.
20492				}
20493
20494				while (--i > -1) {
20495					p = _transformProps[i];
20496					orig = m2[p] - m1[p];
20497					if (orig > min || orig < -min || v[p] != null || _forcePT[p] != null) {
20498						hasChange = true;
20499						pt = new CSSPropTween(m1, p, m1[p], orig, pt);
20500						if (p in endRotations) {
20501							pt.e = endRotations[p]; //directional rotations typically have compensated values during the tween, but we need to make sure they end at exactly what the user requested
20502						}
20503						pt.xs0 = 0; //ensures the value stays numeric in setRatio()
20504						pt.plugin = plugin;
20505						cssp._overwriteProps.push(pt.n);
20506					}
20507				}
20508
20509				orig = v.transformOrigin;
20510				if (m1.svg && (orig || v.svgOrigin)) {
20511					x = m1.xOffset; //when we change the origin, in order to prevent things from jumping we adjust the x/y so we must record those here so that we can create PropTweens for them and flip them at the same time as the origin
20512					y = m1.yOffset;
20513					_parseSVGOrigin(t, _parsePosition(orig), m2, v.svgOrigin, v.smoothOrigin);
20514					pt = _addNonTweeningNumericPT(m1, "xOrigin", (originalGSTransform ? m1 : m2).xOrigin, m2.xOrigin, pt, transformOriginString); //note: if there wasn't a transformOrigin defined yet, just start with the destination one; it's wasteful otherwise, and it causes problems with fromTo() tweens. For example, TweenLite.to("#wheel", 3, {rotation:180, transformOrigin:"50% 50%", delay:1}); TweenLite.fromTo("#wheel", 3, {scale:0.5, transformOrigin:"50% 50%"}, {scale:1, delay:2}); would cause a jump when the from values revert at the beginning of the 2nd tween.
20515					pt = _addNonTweeningNumericPT(m1, "yOrigin", (originalGSTransform ? m1 : m2).yOrigin, m2.yOrigin, pt, transformOriginString);
20516					if (x !== m1.xOffset || y !== m1.yOffset) {
20517						pt = _addNonTweeningNumericPT(m1, "xOffset", originalGSTransform ? x : m1.xOffset, m1.xOffset, pt, transformOriginString);
20518						pt = _addNonTweeningNumericPT(m1, "yOffset", originalGSTransform ? y : m1.yOffset, m1.yOffset, pt, transformOriginString);
20519					}
20520					orig = "0px 0px"; //certain browsers (like firefox) completely botch transform-origin, so we must remove it to prevent it from contaminating transforms. We manage it ourselves with xOrigin and yOrigin
20521				}
20522				if (orig || _supports3D && has3D && m1.zOrigin) {
20523					//if anything 3D is happening and there's a transformOrigin with a z component that's non-zero, we must ensure that the transformOrigin's z-component is set to 0 so that we can manually do those calculations to get around Safari bugs. Even if the user didn't specifically define a "transformOrigin" in this particular tween (maybe they did it via css directly).
20524					if (_transformProp) {
20525						hasChange = true;
20526						p = _transformOriginProp;
20527						orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors
20528						pt = new CSSPropTween(style, p, 0, 0, pt, -1, transformOriginString);
20529						pt.b = style[p];
20530						pt.plugin = plugin;
20531						if (_supports3D) {
20532							copy = m1.zOrigin;
20533							orig = orig.split(" ");
20534							m1.zOrigin = (orig.length > 2 && !(copy !== 0 && orig[2] === "0px") ? parseFloat(orig[2]) : copy) || 0; //Safari doesn't handle the z part of transformOrigin correctly, so we'll manually handle it in the _set3DTransformRatio() method.
20535							pt.xs0 = pt.e = orig[0] + " " + (orig[1] || "50%") + " 0px"; //we must define a z value of 0px specifically otherwise iOS 5 Safari will stick with the old one (if one was defined)!
20536							pt = new CSSPropTween(m1, "zOrigin", 0, 0, pt, -1, pt.n); //we must create a CSSPropTween for the _gsTransform.zOrigin so that it gets reset properly at the beginning if the tween runs backward (as opposed to just setting m1.zOrigin here)
20537							pt.b = copy;
20538							pt.xs0 = pt.e = m1.zOrigin;
20539						} else {
20540							pt.xs0 = pt.e = orig;
20541						}
20542
20543						//for older versions of IE (6-8), we need to manually calculate things inside the setRatio() function. We record origin x and y (ox and oy) and whether or not the values are percentages (oxp and oyp).
20544					} else {
20545						_parsePosition(orig + "", m1);
20546					}
20547				}
20548				if (hasChange) {
20549					cssp._transformType = !(m1.svg && _useSVGTransformAttr) && (has3D || this._transformType === 3) ? 3 : 2; //quicker than calling cssp._enableTransforms();
20550				}
20551				if (swapFunc) {
20552					vars[parsingProp] = swapFunc;
20553				}
20554				if (scaleFunc) {
20555					vars.scale = scaleFunc;
20556				}
20557				return pt;
20558			}, prefix: true });
20559
20560		_registerComplexSpecialProp("boxShadow", { defaultValue: "0px 0px 0px 0px #999", prefix: true, color: true, multi: true, keyword: "inset" });
20561
20562		_registerComplexSpecialProp("borderRadius", { defaultValue: "0px", parser: function (t, e, p, cssp, pt, plugin) {
20563				e = this.format(e);
20564				var props = ["borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius"],
20565				    style = t.style,
20566				    ea1,
20567				    i,
20568				    es2,
20569				    bs2,
20570				    bs,
20571				    es,
20572				    bn,
20573				    en,
20574				    w,
20575				    h,
20576				    esfx,
20577				    bsfx,
20578				    rel,
20579				    hn,
20580				    vn,
20581				    em;
20582				w = parseFloat(t.offsetWidth);
20583				h = parseFloat(t.offsetHeight);
20584				ea1 = e.split(" ");
20585				for (i = 0; i < props.length; i++) {
20586					//if we're dealing with percentages, we must convert things separately for the horizontal and vertical axis!
20587					if (this.p.indexOf("border")) {
20588						//older browsers used a prefix
20589						props[i] = _checkPropPrefix(props[i]);
20590					}
20591					bs = bs2 = _getStyle(t, props[i], _cs, false, "0px");
20592					if (bs.indexOf(" ") !== -1) {
20593						bs2 = bs.split(" ");
20594						bs = bs2[0];
20595						bs2 = bs2[1];
20596					}
20597					es = es2 = ea1[i];
20598					bn = parseFloat(bs);
20599					bsfx = bs.substr((bn + "").length);
20600					rel = es.charAt(1) === "=";
20601					if (rel) {
20602						en = parseInt(es.charAt(0) + "1", 10);
20603						es = es.substr(2);
20604						en *= parseFloat(es);
20605						esfx = es.substr((en + "").length - (en < 0 ? 1 : 0)) || "";
20606					} else {
20607						en = parseFloat(es);
20608						esfx = es.substr((en + "").length);
20609					}
20610					if (esfx === "") {
20611						esfx = _suffixMap[p] || bsfx;
20612					}
20613					if (esfx !== bsfx) {
20614						hn = _convertToPixels(t, "borderLeft", bn, bsfx); //horizontal number (we use a bogus "borderLeft" property just because the _convertToPixels() method searches for the keywords "Left", "Right", "Top", and "Bottom" to determine of it's a horizontal or vertical property, and we need "border" in the name so that it knows it should measure relative to the element itself, not its parent.
20615						vn = _convertToPixels(t, "borderTop", bn, bsfx); //vertical number
20616						if (esfx === "%") {
20617							bs = hn / w * 100 + "%";
20618							bs2 = vn / h * 100 + "%";
20619						} else if (esfx === "em") {
20620							em = _convertToPixels(t, "borderLeft", 1, "em");
20621							bs = hn / em + "em";
20622							bs2 = vn / em + "em";
20623						} else {
20624							bs = hn + "px";
20625							bs2 = vn + "px";
20626						}
20627						if (rel) {
20628							es = parseFloat(bs) + en + esfx;
20629							es2 = parseFloat(bs2) + en + esfx;
20630						}
20631					}
20632					pt = _parseComplex(style, props[i], bs + " " + bs2, es + " " + es2, false, "0px", pt);
20633				}
20634				return pt;
20635			}, prefix: true, formatter: _getFormatter("0px 0px 0px 0px", false, true) });
20636		_registerComplexSpecialProp("borderBottomLeftRadius,borderBottomRightRadius,borderTopLeftRadius,borderTopRightRadius", { defaultValue: "0px", parser: function (t, e, p, cssp, pt, plugin) {
20637				return _parseComplex(t.style, p, this.format(_getStyle(t, p, _cs, false, "0px 0px")), this.format(e), false, "0px", pt);
20638			}, prefix: true, formatter: _getFormatter("0px 0px", false, true) });
20639		_registerComplexSpecialProp("backgroundPosition", { defaultValue: "0 0", parser: function (t, e, p, cssp, pt, plugin) {
20640				var bp = "background-position",
20641				    cs = _cs || _getComputedStyle(t, null),
20642				    bs = this.format((cs ? _ieVers ? cs.getPropertyValue(bp + "-x") + " " + cs.getPropertyValue(bp + "-y") : cs.getPropertyValue(bp) : t.currentStyle.backgroundPositionX + " " + t.currentStyle.backgroundPositionY) || "0 0"),
20643				    //Internet Explorer doesn't report background-position correctly - we must query background-position-x and background-position-y and combine them (even in IE10). Before IE9, we must do the same with the currentStyle object and use camelCase
20644				es = this.format(e),
20645				    ba,
20646				    ea,
20647				    i,
20648				    pct,
20649				    overlap,
20650				    src;
20651				if (bs.indexOf("%") !== -1 !== (es.indexOf("%") !== -1) && es.split(",").length < 2) {
20652					src = _getStyle(t, "backgroundImage").replace(_urlExp, "");
20653					if (src && src !== "none") {
20654						ba = bs.split(" ");
20655						ea = es.split(" ");
20656						_tempImg.setAttribute("src", src); //set the temp IMG's src to the background-image so that we can measure its width/height
20657						i = 2;
20658						while (--i > -1) {
20659							bs = ba[i];
20660							pct = bs.indexOf("%") !== -1;
20661							if (pct !== (ea[i].indexOf("%") !== -1)) {
20662								overlap = i === 0 ? t.offsetWidth - _tempImg.width : t.offsetHeight - _tempImg.height;
20663								ba[i] = pct ? parseFloat(bs) / 100 * overlap + "px" : parseFloat(bs) / overlap * 100 + "%";
20664							}
20665						}
20666						bs = ba.join(" ");
20667					}
20668				}
20669				return this.parseComplex(t.style, bs, es, pt, plugin);
20670			}, formatter: _parsePosition });
20671		_registerComplexSpecialProp("backgroundSize", { defaultValue: "0 0", formatter: function (v) {
20672				v += ""; //ensure it's a string
20673				return _parsePosition(v.indexOf(" ") === -1 ? v + " " + v : v); //if set to something like "100% 100%", Safari typically reports the computed style as just "100%" (no 2nd value), but we should ensure that there are two values, so copy the first one. Otherwise, it'd be interpreted as "100% 0" (wrong).
20674			} });
20675		_registerComplexSpecialProp("perspective", { defaultValue: "0px", prefix: true });
20676		_registerComplexSpecialProp("perspectiveOrigin", { defaultValue: "50% 50%", prefix: true });
20677		_registerComplexSpecialProp("transformStyle", { prefix: true });
20678		_registerComplexSpecialProp("backfaceVisibility", { prefix: true });
20679		_registerComplexSpecialProp("userSelect", { prefix: true });
20680		_registerComplexSpecialProp("margin", { parser: _getEdgeParser("marginTop,marginRight,marginBottom,marginLeft") });
20681		_registerComplexSpecialProp("padding", { parser: _getEdgeParser("paddingTop,paddingRight,paddingBottom,paddingLeft") });
20682		_registerComplexSpecialProp("clip", { defaultValue: "rect(0px,0px,0px,0px)", parser: function (t, e, p, cssp, pt, plugin) {
20683				var b, cs, delim;
20684				if (_ieVers < 9) {
20685					//IE8 and earlier don't report a "clip" value in the currentStyle - instead, the values are split apart into clipTop, clipRight, clipBottom, and clipLeft. Also, in IE7 and earlier, the values inside rect() are space-delimited, not comma-delimited.
20686					cs = t.currentStyle;
20687					delim = _ieVers < 8 ? " " : ",";
20688					b = "rect(" + cs.clipTop + delim + cs.clipRight + delim + cs.clipBottom + delim + cs.clipLeft + ")";
20689					e = this.format(e).split(",").join(delim);
20690				} else {
20691					b = this.format(_getStyle(t, this.p, _cs, false, this.dflt));
20692					e = this.format(e);
20693				}
20694				return this.parseComplex(t.style, b, e, pt, plugin);
20695			} });
20696		_registerComplexSpecialProp("textShadow", { defaultValue: "0px 0px 0px #999", color: true, multi: true });
20697		_registerComplexSpecialProp("autoRound,strictUnits", { parser: function (t, e, p, cssp, pt) {
20698				return pt;
20699			} }); //just so that we can ignore these properties (not tween them)
20700		_registerComplexSpecialProp("border", { defaultValue: "0px solid #000", parser: function (t, e, p, cssp, pt, plugin) {
20701				var bw = _getStyle(t, "borderTopWidth", _cs, false, "0px"),
20702				    end = this.format(e).split(" "),
20703				    esfx = end[0].replace(_suffixExp, "");
20704				if (esfx !== "px") {
20705					//if we're animating to a non-px value, we need to convert the beginning width to that unit.
20706					bw = parseFloat(bw) / _convertToPixels(t, "borderTopWidth", 1, esfx) + esfx;
20707				}
20708				return this.parseComplex(t.style, this.format(bw + " " + _getStyle(t, "borderTopStyle", _cs, false, "solid") + " " + _getStyle(t, "borderTopColor", _cs, false, "#000")), end.join(" "), pt, plugin);
20709			}, color: true, formatter: function (v) {
20710				var a = v.split(" ");
20711				return a[0] + " " + (a[1] || "solid") + " " + (v.match(_colorExp) || ["#000"])[0];
20712			} });
20713		_registerComplexSpecialProp("borderWidth", { parser: _getEdgeParser("borderTopWidth,borderRightWidth,borderBottomWidth,borderLeftWidth") }); //Firefox doesn't pick up on borderWidth set in style sheets (only inline).
20714		_registerComplexSpecialProp("float,cssFloat,styleFloat", { parser: function (t, e, p, cssp, pt, plugin) {
20715				var s = t.style,
20716				    prop = "cssFloat" in s ? "cssFloat" : "styleFloat";
20717				return new CSSPropTween(s, prop, 0, 0, pt, -1, p, false, 0, s[prop], e);
20718			} });
20719
20720		//opacity-related
20721		var _setIEOpacityRatio = function (v) {
20722			var t = this.t,
20723			    //refers to the element's style property
20724			filters = t.filter || _getStyle(this.data, "filter") || "",
20725			    val = this.s + this.c * v | 0,
20726			    skip;
20727			if (val === 100) {
20728				//for older versions of IE that need to use a filter to apply opacity, we should remove the filter if opacity hits 1 in order to improve performance, but make sure there isn't a transform (matrix) or gradient in the filters.
20729				if (filters.indexOf("atrix(") === -1 && filters.indexOf("radient(") === -1 && filters.indexOf("oader(") === -1) {
20730					t.removeAttribute("filter");
20731					skip = !_getStyle(this.data, "filter"); //if a class is applied that has an alpha filter, it will take effect (we don't want that), so re-apply our alpha filter in that case. We must first remove it and then check.
20732				} else {
20733					t.filter = filters.replace(_alphaFilterExp, "");
20734					skip = true;
20735				}
20736			}
20737			if (!skip) {
20738				if (this.xn1) {
20739					t.filter = filters = filters || "alpha(opacity=" + val + ")"; //works around bug in IE7/8 that prevents changes to "visibility" from being applied properly if the filter is changed to a different alpha on the same frame.
20740				}
20741				if (filters.indexOf("pacity") === -1) {
20742					//only used if browser doesn't support the standard opacity style property (IE 7 and 8). We omit the "O" to avoid case-sensitivity issues
20743					if (val !== 0 || !this.xn1) {
20744						//bugs in IE7/8 won't render the filter properly if opacity is ADDED on the same frame/render as "visibility" changes (this.xn1 is 1 if this tween is an "autoAlpha" tween)
20745						t.filter = filters + " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly.
20746					}
20747				} else {
20748					t.filter = filters.replace(_opacityExp, "opacity=" + val);
20749				}
20750			}
20751		};
20752		_registerComplexSpecialProp("opacity,alpha,autoAlpha", { defaultValue: "1", parser: function (t, e, p, cssp, pt, plugin) {
20753				var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")),
20754				    style = t.style,
20755				    isAutoAlpha = p === "autoAlpha";
20756				if (typeof e === "string" && e.charAt(1) === "=") {
20757					e = (e.charAt(0) === "-" ? -1 : 1) * parseFloat(e.substr(2)) + b;
20758				}
20759				if (isAutoAlpha && b === 1 && _getStyle(t, "visibility", _cs) === "hidden" && e !== 0) {
20760					//if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience)
20761					b = 0;
20762				}
20763				if (_supportsOpacity) {
20764					pt = new CSSPropTween(style, "opacity", b, e - b, pt);
20765				} else {
20766					pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt);
20767					pt.xn1 = isAutoAlpha ? 1 : 0; //we need to record whether or not this is an autoAlpha so that in the setRatio(), we know to duplicate the setting of the alpha in order to work around a bug in IE7 and IE8 that prevents changes to "visibility" from taking effect if the filter is changed to a different alpha(opacity) at the same time. Setting it to the SAME value first, then the new value works around the IE7/8 bug.
20768					style.zoom = 1; //helps correct an IE issue.
20769					pt.type = 2;
20770					pt.b = "alpha(opacity=" + pt.s + ")";
20771					pt.e = "alpha(opacity=" + (pt.s + pt.c) + ")";
20772					pt.data = t;
20773					pt.plugin = plugin;
20774					pt.setRatio = _setIEOpacityRatio;
20775				}
20776				if (isAutoAlpha) {
20777					//we have to create the "visibility" PropTween after the opacity one in the linked list so that they run in the order that works properly in IE8 and earlier
20778					pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, b !== 0 ? "inherit" : "hidden", e === 0 ? "hidden" : "inherit");
20779					pt.xs0 = "inherit";
20780					cssp._overwriteProps.push(pt.n);
20781					cssp._overwriteProps.push(p);
20782				}
20783				return pt;
20784			} });
20785
20786		var _removeProp = function (s, p) {
20787			if (p) {
20788				if (s.removeProperty) {
20789					if (p.substr(0, 2) === "ms" || p.substr(0, 6) === "webkit") {
20790						//Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash, it's correct (otherwise it'd be "ms-transform" instead of "-ms-transform" for IE9, for example)
20791						p = "-" + p;
20792					}
20793					s.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());
20794				} else {
20795					//note: old versions of IE use "removeAttribute()" instead of "removeProperty()"
20796					s.removeAttribute(p);
20797				}
20798			}
20799		},
20800		    _setClassNameRatio = function (v) {
20801			this.t._gsClassPT = this;
20802			if (v === 1 || v === 0) {
20803				this.t.setAttribute("class", v === 0 ? this.b : this.e);
20804				var mpt = this.data,
20805				    //first MiniPropTween
20806				s = this.t.style;
20807				while (mpt) {
20808					if (!mpt.v) {
20809						_removeProp(s, mpt.p);
20810					} else {
20811						s[mpt.p] = mpt.v;
20812					}
20813					mpt = mpt._next;
20814				}
20815				if (v === 1 && this.t._gsClassPT === this) {
20816					this.t._gsClassPT = null;
20817				}
20818			} else if (this.t.getAttribute("class") !== this.e) {
20819				this.t.setAttribute("class", this.e);
20820			}
20821		};
20822		_registerComplexSpecialProp("className", { parser: function (t, e, p, cssp, pt, plugin, vars) {
20823				var b = t.getAttribute("class") || "",
20824				    //don't use t.className because it doesn't work consistently on SVG elements; getAttribute("class") and setAttribute("class", value") is more reliable.
20825				cssText = t.style.cssText,
20826				    difData,
20827				    bs,
20828				    cnpt,
20829				    cnptLookup,
20830				    mpt;
20831				pt = cssp._classNamePT = new CSSPropTween(t, p, 0, 0, pt, 2);
20832				pt.setRatio = _setClassNameRatio;
20833				pt.pr = -11;
20834				_hasPriority = true;
20835				pt.b = b;
20836				bs = _getAllStyles(t, _cs);
20837				//if there's a className tween already operating on the target, force it to its end so that the necessary inline styles are removed and the class name is applied before we determine the end state (we don't want inline styles interfer
20837ing that were there just for class-specific values)
20838				cnpt = t._gsClassPT;
20839				if (cnpt) {
20840					cnptLookup = {};
20841					mpt = cnpt.data; //first MiniPropTween which stores the inline styles - we need to force these so that the inline styles don't contaminate things. Otherwise, there's a small chance that a tween could start and the inline values match the destination values and they never get cleaned.
20842					while (mpt) {
20843						cnptLookup[mpt.p] = 1;
20844						mpt = mpt._next;
20845					}
20846					cnpt.setRatio(1);
20847				}
20848				t._gsClassPT = pt;
20849				pt.e = e.charAt(1) !== "=" ? e : b.replace(new RegExp("(?:\\s|^)" + e.substr(2) + "(?![\\w-])"), "") + (e.charAt(0) === "+" ? " " + e.substr(2) : "");
20850				t.setAttribute("class", pt.e);
20851				difData = _cssDif(t, bs, _getAllStyles(t), vars, cnptLookup);
20852				t.setAttribute("class", b);
20853				pt.data = difData.firstMPT;
20854				t.style.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity).
20855				pt = pt.xfirst = cssp.parse(t, difData.difs, pt, plugin); //we record the CSSPropTween as the xfirst so that we can handle overwriting propertly (if "className" gets overwritten, we must kill all the properties associated with the className part of the tween, so we can loop through from xfirst to the pt itself)
20856				return pt;
20857			} });
20858
20859		var _setClearPropsRatio = function (v) {
20860			if (v === 1 || v === 0) if (this.data._totalTime === this.data._totalDuration && this.data.data !== "isFromStart") {
20861				//this.data refers to the tween. Only clear at the END of the tween (remember, from() tweens make the ratio go from 1 to 0, so we can't just check that and if the tween is the zero-duration one that's created internally to render the starting values in a from() tween, ignore that because otherwise, for example, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in).
20862				var s = this.t.style,
20863				    transformParse = _specialProps.transform.parse,
20864				    a,
20865				    p,
20866				    i,
20867				    clearTransform,
20868				    transform;
20869				if (this.e === "all") {
20870					s.cssText = "";
20871					clearTransform = true;
20872				} else {
20873					a = this.e.split(" ").join("").split(",");
20874					i = a.length;
20875					while (--i > -1) {
20876						p = a[i];
20877						if (_specialProps[p]) {
20878							if (_specialProps[p].parse === transformParse) {
20879								clearTransform = true;
20880							} else {
20881								p = p === "transformOrigin" ? _transformOriginProp : _specialProps[p].p; //ensures that special properties use the proper browser-specific property name, like "scaleX" might be "-webkit-transform" or "boxShadow" might be "-moz-box-shadow"
20882							}
20883						}
20884						_removeProp(s, p);
20885					}
20886				}
20887				if (clearTransform) {
20888					_removeProp(s, _transformProp);
20889					transform = this.t._gsTransform;
20890					if (transform) {
20891						if (transform.svg) {
20892							this.t.removeAttribute("data-svg-origin");
20893							this.t.removeAttribute("transform");
20894						}
20895						delete this.t._gsTransform;
20896					}
20897				}
20898			}
20899		};
20900		_registerComplexSpecialProp("clearProps", { parser: function (t, e, p, cssp, pt) {
20901				pt = new CSSPropTween(t, p, 0, 0, pt, 2);
20902				pt.setRatio = _setClearPropsRatio;
20903				pt.e = e;
20904				pt.pr = -10;
20905				pt.data = cssp._tween;
20906				_hasPriority = true;
20907				return pt;
20908			} });
20909
20910		p = "bezier,throwProps,physicsProps,physics2D".split(",");
20911		i = p.length;
20912		while (i--) {
20913			_registerPluginProp(p[i]);
20914		}
20915
20916		p = CSSPlugin.prototype;
20917		p._firstPT = p._lastParsedTransform = p._transform = null;
20918
20919		//gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc.
20920		p._onInitTween = function (target, vars, tween, index) {
20921			if (!target.nodeType) {
20922				//css is only for dom elements
20923				return false;
20924			}
20925			this._target = _target = target;
20926			this._tween = tween;
20927			this._vars = vars;
20928			_index = index;
20929			_autoRound = vars.autoRound;
20930			_hasPriority = false;
20931			_suffixMap = vars.suffixMap || CSSPlugin.suffixMap;
20932			_cs = _getComputedStyle(target, "");
20933			_overwriteProps = this._overwriteProps;
20934			var style = target.style,
20935			    v,
20936			    pt,
20937			    pt2,
20938			    first,
20939			    last,
20940			    next,
20941			    zIndex,
20942			    tpt,
20943			    threeD;
20944			if (_reqSafariFix) if (style.zIndex === "") {
20945				v = _getStyle(target, "zIndex", _cs);
20946				if (v === "auto" || v === "") {
20947					//corrects a bug in [non-Android] Safari that prevents it from repainting elements in their new positions if they don't have a zIndex set. We also can't just apply this inside _parseTransform() because anything that's moved in any way (like using "left" or "top" instead of transforms like "x" and "y") can be affected, so it is best to ensure that anything that's tweening has a z-index. Setting "WebkitPerspective" to a non-zero value worked too except that on iOS Safari things would flicker randomly. Plus zIndex is less memory-intensive.
20948					this._addLazySet(style, "zIndex", 0);
20949				}
20950			}
20951
20952			if (typeof vars === "string") {
20953				first = style.cssText;
20954				v = _getAllStyles(target, _cs);
20955				style.cssText = first + ";" + vars;
20956				v = _cssDif(target, v, _getAllStyles(target)).difs;
20957				if (!_supportsOpacity && _opacityValExp.test(vars)) {
20958					v.opacity = parseFloat(RegExp.$1);
20959				}
20960				vars = v;
20961				style.cssText = first;
20962			}
20963
20964			if (vars.className) {
20965				//className tweens will combine any differences they find in the css with the vars that are passed in, so {className:"myClass", scale:0.5, left:20} would work.
20966				this._firstPT = pt = _specialProps.className.parse(target, vars.className, "className", this, null, null, vars);
20967			} else {
20968				this._firstPT = pt = this.parse(target, vars, null);
20969			}
20970
20971			if (this._transformType) {
20972				threeD = this._transformType === 3;
20973				if (!_transformProp) {
20974					style.zoom = 1; //helps correct an IE issue.
20975				} else if (_isSafari) {
20976					_reqSafariFix = true;
20977					//if zIndex isn't set, iOS Safari doesn't repaint things correctly sometimes (seemingly at random).
20978					if (style.zIndex === "") {
20979						zIndex = _getStyle(target, "zIndex", _cs);
20980						if (zIndex === "auto" || zIndex === "") {
20981							this._addLazySet(style, "zIndex", 0);
20982						}
20983					}
20984					//Setting WebkitBackfaceVisibility corrects 3 bugs:
20985					// 1) [non-Android] Safari skips rendering changes to "top" and "left" that are made on the same frame/render as a transform update.
20986					// 2) iOS Safari sometimes neglects to repaint elements in their new positions. Setting "WebkitPerspective" to a non-zero value worked too except that on iOS Safari things would flicker randomly.
20987					// 3) Safari sometimes displayed odd artifacts when tweening the transform (or WebkitTransform) property, like ghosts of the edges of the element remained. Definitely a browser bug.
20988					//Note: we allow the user to override the auto-setting by defining WebkitBackfaceVisibility in the vars of the tween.
20989					if (_isSafariLT6) {
20990						this._addLazySet(style, "WebkitBackfaceVisibility", this._vars.WebkitBackfaceVisibility || (threeD ? "visible" : "hidden"));
20991					}
20992				}
20993				pt2 = pt;
20994				while (pt2 && pt2._next) {
20995					pt2 = pt2._next;
20996				}
20997				tpt = new CSSPropTween(target, "transform", 0, 0, null, 2);
20998				this._linkCSSP(tpt, null, pt2);
20999				tpt.setRatio = _transformProp ? _setTransformRatio : _setIETransformRatio;
21000				tpt.data = this._transform || _getTransform(target, _cs, true);
21001				tpt.tween = tween;
21002				tpt.pr = -1; //ensures that the transforms get applied after the components are updated.
21003				_overwriteProps.pop(); //we don't want to force the overwrite of all "transform" tweens of the target - we only care about individual transform properties like scaleX, rotation, etc. The CSSPropTween constructor automatically adds the property to _overwriteProps which is why we need to pop() here.
21004			}
21005
21006			if (_hasPriority) {
21007				//reorders the linked list in order of pr (priority)
21008				while (pt) {
21009					next = pt._next;
21010					pt2 = first;
21011					while (pt2 && pt2.pr > pt.pr) {
21012						pt2 = pt2._next;
21013					}
21014					if (pt._prev = pt2 ? pt2._prev : last) {
21015						pt._prev._next = pt;
21016					} else {
21017						first = pt;
21018					}
21019					if (pt._next = pt2) {
21020						pt2._prev = pt;
21021					} else {
21022						last = pt;
21023					}
21024					pt = next;
21025				}
21026				this._firstPT = first;
21027			}
21028			return true;
21029		};
21030
21031		p.parse = function (target, vars, pt, plugin) {
21032			var style = target.style,
21033			    p,
21034			    sp,
21035			    bn,
21036			    en,
21037			    bs,
21038			    es,
21039			    bsfx,
21040			    esfx,
21041			    isStr,
21042			    rel;
21043			for (p in vars) {
21044				es = vars[p]; //ending value string
21045				if (typeof es === "function") {
21046					es = es(_index, _target);
21047				}
21048				sp = _specialProps[p]; //SpecialProp lookup.
21049				if (sp) {
21050					pt = sp.parse(target, es, p, this, pt, plugin, vars);
21051				} else if (p.substr(0, 2) === "--") {
21052					//for tweening CSS variables (which always start with "--"). To maximize performance and simplicity, we bypass CSSPlugin altogether and just add a normal property tween to the tween instance itself.
21053					this._tween._propLookup[p] = this._addTween.call(this._tween, target.style, "setProperty", _getComputedStyle(target).getPropertyValue(p) + "", es + "", p, false, p);
21054					continue;
21055				} else {
21056					bs = _getStyle(target, p, _cs) + "";
21057					isStr = typeof es === "string";
21058					if (p === "color" || p === "fill" || p === "stroke" || p.indexOf("Color") !== -1 || isStr && _rgbhslExp.test(es)) {
21059						//Opera uses background: to define color sometimes in addition to backgroundColor:
21060						if (!isStr) {
21061							es = _parseColor(es);
21062							es = (es.length > 3 ? "rgba(" : "rgb(") + es.join(",") + ")";
21063						}
21064						pt = _parseComplex(style, p, bs, es, true, "transparent", pt, 0, plugin);
21065					} else if (isStr && _complexExp.test(es)) {
21066						pt = _parseComplex(style, p, bs, es, true, null, pt, 0, plugin);
21067					} else {
21068						bn = parseFloat(bs);
21069						bsfx = bn || bn === 0 ? bs.substr((bn + "").length) : ""; //remember, bs could be non-numeric like "normal" for fontWeight, so we should default to a blank suffix in that case.
21070
21071						if (bs === "" || bs === "auto") {
21072							if (p === "width" || p === "height") {
21073								bn = _getDimension(target, p, _cs);
21074								bsfx = "px";
21075							} else if (p === "left" || p === "top") {
21076								bn = _calculateOffset(target, p, _cs);
21077								bsfx = "px";
21078							} else {
21079								bn = p !== "opacity" ? 0 : 1;
21080								bsfx = "";
21081							}
21082						}
21083
21084						rel = isStr && es.charAt(1) === "=";
21085						if (rel) {
21086							en = parseInt(es.charAt(0) + "1", 10);
21087							es = es.substr(2);
21088							en *= parseFloat(es);
21089							esfx = es.replace(_suffixExp, "");
21090						} else {
21091							en = parseFloat(es);
21092							esfx = isStr ? es.replace(_suffixExp, "") : "";
21093						}
21094
21095						if (esfx === "") {
21096							esfx = p in _suffixMap ? _suffixMap[p] : bsfx; //populate the end suffix, prioritizing the map, then if none is found, use the beginning suffix.
21097						}
21098
21099						es = en || en === 0 ? (rel ? en + bn : en) + esfx : vars[p]; //ensures that any += or -= prefixes are taken care of. Record the end value before normalizing the suffix because we always want to end the tween on exactly what they intended even if it doesn't match the beginning value's suffix.
21100						//if the beginning/ending suffixes don't match, normalize them...
21101						if (bsfx !== esfx) if (esfx !== "" || p === "lineHeight") if (en || en === 0) if (bn) {
21102							//note: if the beginning value (bn) is 0, we don't need to convert units!
21103							bn = _convertToPixels(target, p, bn, bsfx);
21104							if (esfx === "%") {
21105								bn /= _convertToPixels(target, p, 100, "%") / 100;
21106								if (vars.strictUnits !== true) {
21107									//some browsers report only "px" values instead of allowing "%" with getComputedStyle(), so we assume that if we're tweening to a %, we should start there too unless strictUnits:true is defined. This approach is particularly useful for responsive designs that use from() tweens.
21108									bs = bn + "%";
21109								}
21110							} else if (esfx === "em" || esfx === "rem" || esfx === "vw" || esfx === "vh") {
21111								bn /= _convertToPixels(target, p, 1, esfx);
21112
21113								//otherwise convert to pixels.
21114							} else if (esfx !== "px") {
21115								en = _convertToPixels(target, p, en, esfx);
21116								esfx = "px"; //we don't use bsfx after this, so we don't need to set it to px too.
21117							}
21118							if (rel) if (en || en === 0) {
21119								es = en + bn + esfx; //the changes we made affect relative calculations, so adjust the end value here.
21120							}
21121						}
21122
21123						if (rel) {
21124							en += bn;
21125						}
21126
21127						if ((bn || bn === 0) && (en || en === 0)) {
21128							//faster than isNaN(). Also, previously we required en !== bn but that doesn't really gain much performance and it prevents _parseToProxy() from working properly if beginning and ending values match but need to get tweened by an external plugin anyway. For example, a bezier tween where the target starts at left:0 and has these points: [{left:50},{left:0}] wouldn't work properly because when parsing the last point, it'd match the first (current) one and a non-tweening CSSPropTween would be recorded when we actually need a normal tween (type:0) so that things get updated during the tween properly.
21129							pt = new CSSPropTween(style, p, bn, en - bn, pt, 0, p, _autoRound !== false && (esfx === "px" || p === "zIndex"), 0, bs, es);
21130							pt.xs0 = esfx;
21131							//DEBUG: _log("tween "+p+" from "+pt.b+" ("+bn+esfx+") to "+pt.e+" with suffix: "+pt.xs0);
21132						} else if (style[p] === undefined || !es && (es + "" === "NaN" || es == null)) {
21133							_log("invalid " + p + " tween value: " + vars[p]);
21134						} else {
21135							pt = new CSSPropTween(style, p, en || bn || 0, 0, pt, -1, p, false, 0, bs, es);
21136							pt.xs0 = es === "none" && (p === "display" || p.indexOf("Style") !== -1) ? bs : es; //intermediate value should typically be set immediately (end value) except for "display" or things like borderTopStyle, borderBottomStyle, etc. which should use the beginning value during the tween.
21137							//DEBUG: _log("non-tweening value "+p+": "+pt.xs0);
21138						}
21139					}
21140				}
21141				if (plugin) if (pt && !pt.plugin) {
21142					pt.plugin = plugin;
21143				}
21144			}
21145			return pt;
21146		};
21147
21148		//gets called every time the tween updates, passing the new ratio (typically a value between 0 and 1, but not always (for example, if an Elastic.easeOut is used, the value can jump above 1 mid-tween). It will always start and 0 and end at 1.
21149		p.setRatio = function (v) {
21150			var pt = this._firstPT,
21151			    min = 0.000001,
21152			    val,
21153			    str,
21154			    i;
21155			//at the end of the tween, we set the values to exactly what we received in order to make sure non-tweening values (like "position" or "float" or whatever) are set and so that if the beginning/ending suffixes (units) didn't match and we normalized to px, the value that the user passed in is used here. We check to see if the tween is at its beginning in case it's a from() tween in which case the ratio will actually go from 1 to 0 over the course of the tween (backwards).
21156			if (v === 1 && (this._tween._time === this._tween._duration || this._tween._time === 0)) {
21157				while (pt) {
21158					if (pt.type !== 2) {
21159						if (pt.r && pt.type !== -1) {
21160							val = Math.round(pt.s + pt.c);
21161							if (!pt.type) {
21162								pt.t[pt.p] = val + pt.xs0;
21163							} else if (pt.type === 1) {
21164								//complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
21165								i = pt.l;
21166								str = pt.xs0 + val + pt.xs1;
21167								for (i = 1; i < pt.l; i++) {
21168									str += pt["xn" + i] + pt["xs" + (i + 1)];
21169								}
21170								pt.t[pt.p] = str;
21171							}
21172						} else {
21173							pt.t[pt.p] = pt.e;
21174						}
21175					} else {
21176						pt.setRatio(v);
21177					}
21178					pt = pt._next;
21179				}
21180			} else if (v || !(this._tween._time === this._tween._duration || this._tween._time === 0) || this._tween._rawPrevTime === -0.000001) {
21181				while (pt) {
21182					val = pt.c * v + pt.s;
21183					if (pt.r) {
21184						val = Math.round(val);
21185					} else if (val < min) if (val > -min) {
21186						val = 0;
21187					}
21188					if (!pt.type) {
21189						pt.t[pt.p] = val + pt.xs0;
21190					} else if (pt.type === 1) {
21191						//complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
21192						i = pt.l;
21193						if (i === 2) {
21194							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2;
21195						} else if (i === 3) {
21196							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3;
21197						} else if (i === 4) {
21198							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4;
21199						} else if (i === 5) {
21200							pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4 + pt.xn4 + pt.xs5;
21201						} else {
21202							str = pt.xs0 + val + pt.xs1;
21203							for (i = 1; i < pt.l; i++) {
21204								str += pt["xn" + i] + pt["xs" + (i + 1)];
21205							}
21206							pt.t[pt.p] = str;
21207						}
21208					} else if (pt.type === -1) {
21209						//non-tweening value
21210						pt.t[pt.p] = pt.xs0;
21211					}
21211 else if (pt.setRatio) {
21212						//custom setRatio() for things like SpecialProps, external plugins, etc.
21213						pt.setRatio(v);
21214					}
21215					pt = pt._next;
21216				}
21217
21218				//if the tween is reversed all the way back to the beginning, we need to restore the original values which may have different units (like % instead of px or em or whatever).
21219			} else {
21220				while (pt) {
21221					if (pt.type !== 2) {
21222						pt.t[pt.p] = pt.b;
21223					} else {
21224						pt.setRatio(v);
21225					}
21226					pt = pt._next;
21227				}
21228			}
21229		};
21230
21231		/**
21232   * @private
21233   * Forces rendering of the target's transforms (rotation, scale, etc.) whenever the CSSPlugin's setRatio() is called.
21234   * Basically, this tells the CSSPlugin to create a CSSPropTween (type 2) after instantiation that runs last in the linked
21235   * list and calls the appropriate (3D or 2D) rendering function. We separate this into its own method so that we can call
21236   * it from other plugins like BezierPlugin if, for example, it needs to apply an autoRotation and this CSSPlugin
21237   * doesn't have any transform-related properties of its own. You can call this method as many times as you
21238   * want and it won't create duplicate CSSPropTweens.
21239   *
21240   * @param {boolean} threeD if true, it should apply 3D tweens (otherwise, just 2D ones are fine and typically faster)
21241   */
21242		p._enableTransforms = function (threeD) {
21243			this._transform = this._transform || _getTransform(this._target, _cs, true); //ensures that the element has a _gsTransform property with the appropriate values.
21244			this._transformType = !(this._transform.svg && _useSVGTransformAttr) && (threeD || this._transformType === 3) ? 3 : 2;
21245		};
21246
21247		var lazySet = function (v) {
21248			this.t[this.p] = this.e;
21249			this.data._linkCSSP(this, this._next, null, true); //we purposefully keep this._next even though it'd make sense to null it, but this is a performance optimization, as this happens during the while (pt) {} loop in setRatio() at the bottom of which it sets pt = pt._next, so if we null it, the linked list will be broken in that loop.
21250		};
21251		/** @private Gives us a way to set a value on the first render (and only the first render). **/
21252		p._addLazySet = function (t, p, v) {
21253			var pt = this._firstPT = new CSSPropTween(t, p, 0, 0, this._firstPT, 2);
21254			pt.e = v;
21255			pt.setRatio = lazySet;
21256			pt.data = this;
21257		};
21258
21259		/** @private **/
21260		p._linkCSSP = function (pt, next, prev, remove) {
21261			if (pt) {
21262				if (next) {
21263					next._prev = pt;
21264				}
21265				if (pt._next) {
21266					pt._next._prev = pt._prev;
21267				}
21268				if (pt._prev) {
21269					pt._prev._next = pt._next;
21270				} else if (this._firstPT === pt) {
21271					this._firstPT = pt._next;
21272					remove = true; //just to prevent resetting this._firstPT 5 lines down in case pt._next is null. (optimized for speed)
21273				}
21274				if (prev) {
21275					prev._next = pt;
21276				} else if (!remove && this._firstPT === null) {
21277					this._firstPT = pt;
21278				}
21279				pt._next = next;
21280				pt._prev = prev;
21281			}
21282			return pt;
21283		};
21284
21285		p._mod = function (lookup) {
21286			var pt = this._firstPT;
21287			while (pt) {
21288				if (typeof lookup[pt.p] === "function" && lookup[pt.p] === Math.round) {
21289					//only gets called by RoundPropsPlugin (ModifyPlugin manages all the rendering internally for CSSPlugin properties that need modification). Remember, we handle rounding a bit differently in this plugin for performance reasons, leveraging "r" as an indicator that the value should be rounded internally..
21290					pt.r = 1;
21291				}
21292				pt = pt._next;
21293			}
21294		};
21295
21296		//we need to make sure that if alpha or autoAlpha is killed, opacity is too. And autoAlpha affects the "visibility" property.
21297		p._kill = function (lookup) {
21298			var copy = lookup,
21299			    pt,
21300			    p,
21301			    xfirst;
21302			if (lookup.autoAlpha || lookup.alpha) {
21303				copy = {};
21304				for (p in lookup) {
21305					//copy the lookup so that we're not changing the original which may be passed elsewhere.
21306					copy[p] = lookup[p];
21307				}
21308				copy.opacity = 1;
21309				if (copy.autoAlpha) {
21310					copy.visibility = 1;
21311				}
21312			}
21313			if (lookup.className && (pt = this._classNamePT)) {
21314				//for className tweens, we need to kill any associated CSSPropTweens too; a linked list starts at the className's "xfirst".
21315				xfirst = pt.xfirst;
21316				if (xfirst && xfirst._prev) {
21317					this._linkCSSP(xfirst._prev, pt._next, xfirst._prev._prev); //break off the prev
21318				} else if (xfirst === this._firstPT) {
21319					this._firstPT = pt._next;
21320				}
21321				if (pt._next) {
21322					this._linkCSSP(pt._next, pt._next._next, xfirst._prev);
21323				}
21324				this._classNamePT = null;
21325			}
21326			pt = this._firstPT;
21327			while (pt) {
21328				if (pt.plugin && pt.plugin !== p && pt.plugin._kill) {
21329					//for plugins that are registered with CSSPlugin, we should notify them of the kill.
21330					pt.plugin._kill(lookup);
21331					p = pt.plugin;
21332				}
21333				pt = pt._next;
21334			}
21335			return TweenPlugin.prototype._kill.call(this, copy);
21336		};
21337
21338		//used by cascadeTo() for gathering all the style properties of each child element into an array for c
21338omparison.
21339		var _getChildStyles = function (e, props, targets) {
21340			var children, i, child, type;
21341			if (e.slice) {
21342				i = e.length;
21343				while (--i > -1) {
21344					_getChildStyles(e[i], props, targets);
21345				}
21346				return;
21347			}
21348			children = e.childNodes;
21349			i = children.length;
21350			while (--i > -1) {
21351				child = children[i];
21352				type = child.type;
21353				if (child.style) {
21354					props.push(_getAllStyles(child));
21355					if (targets) {
21356						targets.push(child);
21357					}
21358				}
21359				if ((type === 1 || type === 9 || type === 11) && child.childNodes.length) {
21360					_getChildStyles(child, props, targets);
21361				}
21362			}
21363		};
21364
21365		/**
21366   * Typically only useful for className tweens that may affect child elements, this method creates a TweenLite
21367   * and then compares the style properties of all the target's child elements at the tween's start and end, and
21368   * if any are different, it also creates tweens for those and returns an array containing ALL of the resulting
21369   * tweens (so that you can easily add() them to a TimelineLite, for example). The reason this functionality is
21370   * wrapped into a separate static method of CSSPlugin instead of being integrated into all regular className tweens
21371   * is because it creates entirely new tweens that may have completely different targets than the original tween,
21372   * so if they were all lumped into the original tween instance, it would be inconsistent with the rest of the API
21373   * and it would create other problems. For example:
21374   *  - If I create a tween of elementA, that tween instance may suddenly change its target to include 50 other elements (unintuitive if I specifically defined the target I wanted)
21375   *  - We can't just create new independent tweens because otherwise, what happens if the original/parent tween is reversed or pause or dropped into a TimelineLite for tight control? You'd expect that tween's behavior to affect all the others.
21376   *  - Analyzing every style property of every child before and after the tween is an expensive operation when there are many children, so this behavior shouldn't be imposed on all className tweens by default, especially since it's probably rare that this extra functionality is needed.
21377   *
21378   * @param {Object} target object to be tweened
21379   * @param {number} Duration in seconds (or frames for frames-based tweens)
21380   * @param {Object} Object containing the end values, like {className:"newClass", ease:Linear.easeNone}
21381   * @return {Array} An array of TweenLite instances
21382   */
21383		CSSPlugin.cascadeTo = function (target, duration, vars) {
21384			var tween = TweenLite.to(target, duration, vars),
21385			    results = [tween],
21386			    b = [],
21387			    e = [],
21388			    targets = [],
21389			    _reservedProps = TweenLite._internals.reservedProps,
21390			    i,
21391			    difs,
21392			    p,
21393			    from;
21394			target = tween._targets || tween.target;
21395			_getChildStyles(target, b, targets);
21396			tween.render(duration, true, true);
21397			_getChildStyles(target, e);
21398			tween.render(0, true, true);
21399			tween._enabled(true);
21400			i = targets.length;
21401			while (--i > -1) {
21402				difs = _cssDif(targets[i], b[i], e[i]);
21403				if (difs.firstMPT) {
21404					difs = difs.difs;
21405					for (p in vars) {
21406						if (_reservedProps[p]) {
21407							difs[p] = vars[p];
21408						}
21409					}
21410					from = {};
21411					for (p in difs) {
21412						from[p] = b[i][p];
21413					}
21414					results.push(TweenLite.fromTo(targets[i], duration, from, difs));
21415				}
21416			}
21417			return results;
21418		};
21419
21420		TweenPlugin.activate([CSSPlugin]);
21421		return CSSPlugin;
21422	}, true);
21423
21424	/*
21425  * ----------------------------------------------------------------
21426  * RoundPropsPlugin
21427  * ----------------------------------------------------------------
21428  */
21429	(function () {
21430
21431		var RoundPropsPlugin = _gsScope._gsDefine.plugin({
21432			propName: "roundProps",
21433			version: "1.6.0",
21434			priority: -1,
21435			API: 2,
21436
21437			//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
21438			init: function (target, value, tween) {
21439				this._tween = tween;
21440				return true;
21441			}
21442
21443		}),
21444		    _roundLinkedList = function (node) {
21445			while (node) {
21446				if (!node.f && !node.blob) {
21447					node.m = Math.round;
21448				}
21449				node = node._next;
21450			}
21451		},
21452		    p = RoundPropsPlugin.prototype;
21453
21454		p._onInitAllProps = function () {
21455			var tween = this._tween,
21456			    rp = tween.vars.roundProps.join ? tween.vars.roundProps : tween.vars.roundProps.split(","),
21457			    i = rp.length,
21458			    lookup = {},
21459			    rpt = tween._propLookup.roundProps,
21460			    prop,
21461			    pt,
21462			    next;
21463			while (--i > -1) {
21464				lookup[rp[i]] = Math.round;
21465			}
21466			i = rp.length;
21467			while (--i > -1) {
21468				prop = rp[i];
21469				pt = tween._firstPT;
21470				while (pt) {
21471					next = pt._next; //record here, because it may get removed
21472					if (pt.pg) {
21473						pt.t._mod(lookup);
21474					} else if (pt.n === prop) {
21475						if (pt.f === 2 && pt.t) {
21476							//a blob (text containing multiple numeric values)
21477							_roundLinkedList(pt.t._firstPT);
21478						} else {
21479							this._add(pt.t, prop, pt.s, pt.c);
21480							//remove from linked list
21481							if (next) {
21482								next._prev = pt._prev;
21483							}
21484							if (pt._prev) {
21485								pt._prev._next = next;
21486							} else if (tween._firstPT === pt) {
21487								tween._firstPT = next;
21488							}
21489							pt._next = pt._prev = null;
21490							tween._propLookup[prop] = rpt;
21491						}
21492					}
21493					pt = next;
21494				}
21495			}
21496			return false;
21497		};
21498
21499		p._add = function (target, p, s, c) {
21500			this._addTween(target, p, s, s + c, p, Math.round);
21501			this._overwriteProps.push(p);
21502		};
21503	})();
21504
21505	/*
21506  * ----------------------------------------------------------------
21507  * AttrPlugin
21508  * ----------------------------------------------------------------
21509  */
21510
21511	(function () {
21512
21513		_gsScope._gsDefine.plugin({
21514			propName: "attr",
21515			API: 2,
21516			version: "0.6.1",
21517
21518			//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
21519			init: function (target, value, tween, index) {
21520				var p, end;
21521				if (typeof target.setAttribute !== "function") {
21522					return false;
21523				}
21524				for (p in value) {
21525					end = value[p];
21526					if (typeof end === "function") {
21527						end = end(index, target);
21528					}
21529					this._addTween(target, "setAttribute", target.getAttribute(p) + "", end + "", p, false, p);
21530					this._overwriteProps.push(p);
21531				}
21532				return true;
21533			}
21534
21535		});
21536	})();
21537
21538	/*
21539  * ----------------------------------------------------------------
21540  * DirectionalRotationPlugin
21541  * ----------------------------------------------------------------
21542  */
21543	_gsScope._gsDefine.plugin({
21544		propName: "directionalRotation",
21545		version: "0.3.1",
21546		API: 2,
21547
21548		//called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
21549		init: function (target, value, tween, index) {
21550			if (typeof value !== "object") {
21551				value = { rotation: value };
21552			}
21553			this.finals = {};
21554			var cap = value.useRadians === true ? Math.PI * 2 : 360,
21555			    min = 0.000001,
21556			    p,
21557			    v,
21558			    start,
21559			    end,
21560			    dif,
21561			    split;
21562			for (p in value) {
21563				if (p !== "useRadians") {
21564					end = value[p];
21565					if (typeof end === "function") {
21566						end = end(index, target);
21567					}
21568					split = (end + "").split("_");
21569					v = split[0];
21570					start = parseFloat(typeof target[p] !== "function" ? target[p] : target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)]());
21571					end = this.finals[p] = typeof v === "string" && v.charAt(1) === "=" ? start + parseInt(v.charAt(0) + "1", 10) * Number(v.substr(2)) : Number(v) || 0;
21572					dif = end - start;
21573					if (split.length) {
21574						v = split.join("_");
21575						if (v.indexOf("short") !== -1) {
21576							dif = dif % cap;
21577							if (dif !== dif % (cap / 2)) {
21578								dif = dif < 0 ? dif + cap : dif - cap;
21579							}
21580						}
21581						if (v.indexOf("_cw") !== -1 && dif < 0) {
21582							dif = (dif + cap * 9999999999) % cap - (dif / cap | 0) * cap;
21583						} else if (v.indexOf("ccw") !== -1 && dif > 0) {
21584							dif = (dif - cap * 9999999999) % cap - (dif / cap | 0) * cap;
21585						}
21586					}
21587					if (dif > min || dif < -min) {
21588						this._addTween(target, p, start, start + dif, p);
21589						this._overwriteProps.push(p);
21590					}
21591				}
21592			}
21593			return true;
21594		},
21595
21596		//called each time the values should be updated, and the ratio gets passed as the only parameter (typically it's a value between 0 and 1, but it can exceed those when using an ease like Elastic.easeOut or Back.easeOut, etc.)
21597		set: function (ratio) {
21598			var pt;
21599			if (ratio !== 1) {
21600				this._super.setRatio.call(this, ratio);
21601			} else {
21602				pt = this._firstPT;
21603				while (pt) {
21604					if (pt.f) {
21605						pt.t[pt.p](this.finals[pt.p]);
21606					} else {
21607						pt.t[pt.p] = this.finals[pt.p];
21608					}
21609					pt = pt._next;
21610				}
21611			}
21612		}
21613
21614	})._autoCSS = true;
21615
21616	/*
21617  * ----------------------------------------------------------------
21618  * EasePack
21619  * ----------------------------------------------------------------
21620  */
21621	_gsScope._gsDefine("easing.Back", ["easing.Ease"], function (Ease) {
21622
21623		var w = _gsScope.GreenSockGlobals || _gsScope,
21624		    gs = w.com.greensock,
21625		    _2PI = Math.PI * 2,
21626		    _HALF_PI = Math.PI / 2,
21627		    _class = gs._class,
21628		    _create = function (n, f) {
21629			var C = _class("easing." + n, function () {}, true),
21630			    p = C.prototype = new Ease();
21631			p.constructor = C;
21632			p.getRatio = f;
21633			return C;
21634		},
21635		    _easeReg = Ease.register || function () {},
21636		    //put an empty function in place just as a safety measure in case someone loads an OLD version of TweenLite.js where Ease.register doesn't exist.
21637		_wrap = function (name, EaseOut, EaseIn, EaseInOut, aliases) {
21638			var C = _class("easing." + name, {
21639				easeOut: new EaseOut(),
21640				easeIn: new EaseIn(),
21641				easeInOut: new EaseInOut()
21642			}, true);
21643			_easeReg(C, name);
21644			return C;
21645		},
21646		    EasePoint = function (time, value, next) {
21647			this.t = time;
21648			this.v = value;
21649			if (next) {
21650				this.next = next;
21651				next.prev = this;
21652				this.c = next.v - value;
21653				this.gap = next.t - time;
21654			}
21655		},
21656
21657
21658		//Back
21659		_createBack = function (n, f) {
21660			var C = _class("easing." + n, function (overshoot) {
21661				this._p1 = overshoot || overshoot === 0 ? overshoot : 1.70158;
21662				this._p2 = this._p1 * 1.525;
21663			}, true),
21664			    p = C.prototype = new Ease();
21665			p.constructor = C;
21666			p.getRatio = f;
21667			p.config = function (overshoot) {
21668				return new C(overshoot);
21669			};
21670			return C;
21671		},
21672		    Back = _wrap("Back", _createBack("BackOut", function (p) {
21673			return (p = p - 1) * p * ((this._p1 + 1) * p + this._p1) + 1;
21674		}), _createBack("BackIn", function (p) {
21675			return p * p * ((this._p1 + 1) * p - this._p1);
21676		}), _createBack("BackInOut", function (p) {
21677			return (p *= 2) < 1 ? 0.5 * p * p * ((this._p2 + 1) * p - this._p2) : 0.5 * ((p -= 2) * p * ((this._p2 + 1) * p + this._p2) + 2);
21678		})),
21679
21680
21681		//SlowMo
21682		SlowMo = _class("easing.SlowMo", function (linearRatio, power, yoyoMode) {
21683			power = power || power === 0 ? power : 0.7;
21684			if (linearRatio == null) {
21685				linearRatio = 0.7;
21686			} else if (linearRatio > 1) {
21687				linearRatio = 1;
21688			}
21689			this._p = linearRatio !== 1 ? power : 0;
21690			this._p1 = (1 - linearRatio) / 2;
21691			this._p2 = linearRatio;
21692			this._p3 = this._p1 + this._p2;
21693			this._calcEnd = yoyoMode === true;
21694		}, true),
21695		    p = SlowMo.prototype = new Ease(),
21696		    SteppedEase,
21697		    RoughEase,
21698		    _createElastic;
21699
21700		p.constructor = SlowMo;
21701		p.getRatio = function (p) {
21702			var r = p + (0.5 - p) * this._p;
21703			if (p < this._p1) {
21704				return this._calcEnd ? 1 - (p = 1 - p / this._p1) * p : r - (p = 1 - p / this._p1) * p * p * p * r;
21705			} else if (p > this._p3) {
21706				return this._calcEnd ? p === 1 ? 0 : 1 - (p = (p - this._p3) / this._p1) * p : r + (p - r) * (p = (p - this._p3) / this._p1) * p * p * p; //added p === 1 ? 0 to avoid floating point rounding errors from affecting the final value, like 1 - 0.7 = 0.30000000000000004 instead of 0.3
21707			}
21708			return this._calcEnd ? 1 : r;
21709		};
21710		SlowMo.ease = new SlowMo(0.7, 0.7);
21711
21712		p.config = SlowMo.config = function (linearRatio, power, yoyoMode) {
21713			return new SlowMo(linearRatio, power, yoyoMode);
21714		};
21715
21716		//SteppedEase
21717		SteppedEase = _class("easing.SteppedEase", function (steps, immediateStart) {
21718			steps = steps || 1;
21719			this._p1 = 1 / steps;
21720			this._p2 = steps + (immediateStart ? 0 : 1);
21721			this._p3 = immediateStart ? 1 : 0;
21722		}, true);
21723		p = SteppedEase.prototype = new Ease();
21724		p.constructor = SteppedEase;
21725		p.getRatio = function (p) {
21726			if (p < 0) {
21727				p = 0;
21728			} else if (p >= 1) {
21729				p = 0.999999999;
21730			}
21731			return ((this._p2 * p | 0) + this._p3) * this._p1;
21732		};
21733		p.config = SteppedEase.config = function (steps, immediateStart) {
21734			return new SteppedEase(steps, immediateStart);
21735		};
21736
21737		//RoughEase
21738		RoughEase = _class("easing.RoughEase", function (vars) {
21739			vars = vars || {};
21740			var taper = vars.taper || "none",
21741			    a = [],
21742			    cnt = 0,
21743			    points = (vars.points || 20) | 0,
21744			    i = points,
21745			    randomize = vars.randomize !== false,
21746			    clamp = vars.clamp === true,
21747			    template = vars.template instanceof Ease ? vars.template : null,
21748			    strength = typeof vars.strength === "number" ? vars.strength * 0.4 : 0.4,
21749			    x,
21750			    y,
21751			    bump,
21752			    invX,
21753			    obj,
21754			    pnt;
21755			while (--i > -1) {
21756				x = randomize ? Math.random() : 1 / points * i;
21757				y = template ? template.getRatio(x) : x;
21758				if (taper === "none") {
21759					bump = strength;
21760				} else if (taper === "out") {
21761					invX = 1 - x;
21762					bump = invX * invX * strength;
21763				} else if (taper === "in") {
21764					bump = x * x * strength;
21765				} else if (x < 0.5) {
21766					//"both" (start)
21767					invX = x * 2;
21768					bump = invX * invX * 0.5 * strength;
21769				} else {
21770					//"both" (end)
21771					invX = (1 - x) * 2;
21772					bump = invX * invX * 0.5 * strength;
21773				}
21774				if (randomize) {
21775					y += Math.random() * bump - bump * 0.5;
21776				} else if (i % 2) {
21777					y += bump * 0.5;
21778				} else {
21779					y -= bump * 0.5;
21780				}
21781				if (clamp) {
21782					if (y > 1) {
21783						y = 1;
21784					} else if (y < 0) {
21785						y = 0;
21786					}
21787				}
21788				a[cnt++] = { x: x, y: y };
21789			}
21790			a.sort(function (a, b) {
21791				return a.x - b.x;
21792			});
21793
21794			pnt = new EasePoint(1, 1, null);
21795			i = points;
21796			while (--i > -1) {
21797				obj = a[i];
21798				pnt = new EasePoint(obj.x, obj.y, pnt);
21799			}
21800
21801			this._prev = new EasePoint(0, 0, pnt.t !== 0 ? pnt : pnt.next);
21802		}, true);
21803		p = RoughEase.prototype = new Ease();
21804		p.constructor = RoughEase;
21805		p.getRatio = function (p) {
21806			var pnt = this._prev;
21807			if (p > pnt.t) {
21808				while (pnt.next && p >= pnt.t) {
21809					pnt = pnt.next;
21810				}
21811				pnt = pnt.prev;
21812			} else {
21813				while (pnt.prev && p <= pnt.t) {
21814					pnt = pnt.prev;
21815				}
21816			}
21817			this._prev = pnt;
21818			return pnt.v + (p - pnt.t) / pnt.gap * pnt.c;
21819		};
21820		p.config = function (vars) {
21821			return new RoughEase(vars);
21822		};
21823		RoughEase.ease = new RoughEase();
21824
21825		//Bounce
21826		_wrap("Bounce", _create("BounceOut", function (p) {
21827			if (p < 1 / 2.75) {
21828				return 7.5625 * p * p;
21829			} else if (p < 2 / 2.75) {
21830				return 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;
21831			} else if (p < 2.5 / 2.75) {
21832				return 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;
21833			}
21834			return 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;
21835		}), _create("BounceIn", function (p) {
21836			if ((p = 1 - p) < 1 / 2.75) {
21837				return 1 - 7.5625 * p * p;
21838			} else if (p < 2 / 2.75) {
21839				return 1 - (7.5625 * (p -= 1.5 / 2.75) * p + 0.75);
21840			} else if (p < 2.5 / 2.75) {
21841				return 1 - (7.5625 * (p -= 2.25 / 2.75) * p + 0.9375);
21842			}
21843			return 1 - (7.5625 * (p -= 2.625 / 2.75) * p + 0.984375);
21844		}), _create("BounceInOut", function (p) {
21845			var invert = p < 0.5;
21846			if (invert) {
21847				p = 1 - p * 2;
21848			} else {
21849				p = p * 2 - 1;
21850			}
21851			if (p < 1 / 2.75) {
21852				p = 7.5625 * p * p;
21853			} else if (p < 2 / 2.75) {
21854				p = 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;
21855			} else if (p < 2.5 / 2.75) {
21856				p = 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;
21857			} else {
21858				p = 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;
21859			}
21860			return invert ? (1 - p) * 0.5 : p * 0.5 + 0.5;
21861		}));
21862
21863		//CIRC
21864		_wrap("Circ", _create("CircOut", function (p) {
21865			return Math.sqrt(1 - (p = p - 1) * p);
21866		}), _create("CircIn", function (p) {
21867			return -(Math.sqrt(1 - p * p) - 1);
21868		}), _create("CircInOut", function (p) {
21869			return (p *= 2) < 1 ? -0.5 * (Math.sqrt(1 - p * p) - 1) : 0.5 * (Math.sqrt(1 - (p -= 2) * p) + 1);
21870		}));
21871
21872		//Elastic
21873		_createElastic = function (n, f, def) {
21874			var C = _class("easing." + n, function (amplitude, period) {
21875				this._p1 = amplitude >= 1 ? amplitude : 1;
21875 //note: if amplitude is < 1, we simply adjust the period for a more natural feel. Otherwise the math doesn't work right and the curve starts at 1.
21876				this._p2 = (period || def) / (amplitude < 1 ? amplitude : 1);
21877				this._p3 = this._p2 / _2PI * (Math.asin(1 / this._p1) || 0);
21878				this._p2 = _2PI / this._p2; //precalculate to optimize
21879			}, true),
21880			    p = C.prototype = new Ease();
21881			p.constructor = C;
21882			p.getRatio = f;
21883			p.config = function (amplitude, period) {
21884				return new C(amplitude, period);
21885			};
21886			return C;
21887		};
21888		_wrap("Elastic", _createElastic("ElasticOut", function (p) {
21889			return this._p1 * Math.pow(2, -10 * p) * Math.sin((p - this._p3) * this._p2) + 1;
21890		}, 0.3), _createElastic("ElasticIn", function (p) {
21891			return -(this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin((p - this._p3) * this._p2));
21892		}, 0.3), _createElastic("ElasticInOut", function (p) {
21893			return (p *= 2) < 1 ? -0.5 * (this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin((p - this._p3) * this._p2)) : this._p1 * Math.pow(2, -10 * (p -= 1)) * Math.sin((p - this._p3) * this._p2) * 0.5 + 1;
21894		}, 0.45));
21895
21896		//Expo
21897		_wrap("Expo", _create("ExpoOut", function (p) {
21898			return 1 - Math.pow(2, -10 * p);
21899		}), _create("ExpoIn", function (p) {
21900			return Math.pow(2, 10 * (p - 1)) - 0.001;
21901		}), _create("ExpoInOut", function (p) {
21902			return (p *= 2) < 1 ? 0.5 * Math.pow(2, 10 * (p - 1)) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
21903		}));
21904
21905		//Sine
21906		_wrap("Sine", _create("SineOut", function (p) {
21907			return Math.sin(p * _HALF_PI);
21908		}), _create("SineIn", function (p) {
21909			return -Math.cos(p * _HALF_PI) + 1;
21910		}), _create("SineInOut", function (p) {
21911			return -0.5 * (Math.cos(Math.PI * p) - 1);
21912		}));
21913
21914		_class("easing.EaseLookup", {
21915			find: function (s) {
21916				return Ease.map[s];
21917			}
21918		}, true);
21919
21920		//register the non-standard eases
21921		_easeReg(w.SlowMo, "SlowMo", "ease,");
21922		_easeReg(RoughEase, "RoughEase", "ease,");
21923		_easeReg(SteppedEase, "SteppedEase", "ease,");
21924
21925		return Back;
21926	}, true);
21927});
21928
21929if (_gsScope._gsDefine) {
21930	_gsScope._gsQueue.pop()();
21931} //necessary in case TweenLite was already loaded separately.
21932
21933
21934/*
21935 * ----------------------------------------------------------------
21936 * Base classes like TweenLite, SimpleTimeline, Ease, Ticker, etc.
21937 * ----------------------------------------------------------------
21938 */
21939(function (window, moduleName) {
21940
21941	"use strict";
21942
21943	var _exports = {},
21944	    _doc = window.document,
21945	    _globals = window.GreenSockGlobals = window.GreenSockGlobals || window;
21946	if (_globals.TweenLite) {
21947		return; //in case the core set of classes is already loaded, don't instantiate twice.
21948	}
21949	var _namespace = function (ns) {
21950		var a = ns.split("."),
21951		    p = _globals,
21952		    i;
21953		for (i = 0; i < a.length; i++) {
21954			p[a[i]] = p = p[a[i]] || {};
21955		}
21956		return p;
21957	},
21958	    gs = _namespace("com.greensock"),
21959	    _tinyNum = 0.0000000001,
21960	    _slice = function (a) {
21961		//don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
21962		var b = [],
21963		    l = a.length,
21964		    i;
21965		for (i = 0; i !== l; b.push(a[i++])) {}
21966		return b;
21967	},
21968	    _emptyFunc = function () {},
21969	    _isArray = function () {
21970		//works around issues in iframe environments where the Array global isn't shared, thus if the object originates in a different window/iframe, "(obj instanceof Array)" will evaluate false. We added some speed optimizations to avoid Object.prototype.toString.call() unless it's absolutely necessary because it's VERY slow (like 20x slower)
21971		var toString = Object.prototype.toString,
21972		    array = toString.call([]);
21973		return function (obj) {
21974			return obj != null && (obj instanceof Array || typeof obj === "object" && !!obj.push && toString.call(obj) === array);
21975		};
21976	}(),
21977	    a,
21978	    i,
21979	    p,
21980	    _ticker,
21981	    _tickerActive,
21982	    _defLookup = {},
21983
21984
21985	/**
21986  * @constructor
21987  * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition.
21988  * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is
21989  * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin
21990  * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally.
21991  *
21992  * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found,
21993  * it will go there as of v1.7). For example, TweenLite will be found at window.com.greensock.TweenLite and since it's a global class that should be available anywhere,
21994  * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so
21995  * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything
21996  * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock
21997  * files and put them into distinct objects (imagine a banner ad uses a newer version but the main site uses an older one). In that case, you could
21998  * sandbox the banner one like:
21999  *
22000  * <script>
22001  *     var gs = window.GreenSockGlobals = {}; //the newer version we're about to load could now be referenced in a "gs" object, like gs.TweenLite.to(...). Use whatever alias you want as long as it's unique, "gs" or "banner" or whatever.
22002  * </script>
22003  * <script src="js/greensock/v1.7/TweenMax.js"></script>
22004  * <script>
22005  *     window.GreenSockGlobals = window._gsQueue = window._gsDefine = null; //reset it back to null (along with the special _gsQueue variable) so that the next load of TweenMax affects the window and we can reference things directly like TweenLite.to(...)
22006  * </script>
22007  * <script src="js/greensock/v1.6/TweenMax.js"></script>
22008  * <script>
22009  *     gs.TweenLite.to(...); //would use v1.7
22010  *     TweenLite.to(...); //would use v1.6
22011  * </script>
22012  *
22013  * @param {!string} ns The namespace of the class definition, leaving off "com.greensock." as that's assumed. For example, "TweenLite" or "plugins.CSSPlugin" or "easing.Back".
22014  * @param {!Array.<string>} dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"]
22015  * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition.
22016  * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object)
22017  */
22018	Definition = function (ns, dependencies, func, global) {
22019		this.sc = _defLookup[ns] ? _defLookup[ns].sc : []; //subclasses
22020		_defLookup[ns] = this;
22021		this.gsClass = null;
22022		this.func = func;
22023		var _classes = [];
22024		this.check = function (init) {
22025			var i = dependencies.length,
22026			    missing = i,
22027			    cur,
22028			    a,
22029			    n,
22030			    cl;
22031			while (--i > -1) {
22032				if ((cur = _defLookup[dependencies[i]] || new Definition(dependencies[i], [])).gsClass) {
22033					_classes[i] = cur.gsClass;
22034					missing--;
22035				} else if (init) {
22036					cur.sc.push(this);
22037				}
22038			}
22039			if (missing === 0 && func) {
22040				a = ("com.greensock." + ns).split(".");
22041				n = a.pop();
22042				cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes);
22043
22044				//exports to multiple environments
22045				if (global) {
22046					_globals[n] = _exports[n] = cl; //provides a way to avoid global namespace pollution. By default, the main classes like TweenLite, Power1, Strong, etc. are added to window unless a GreenSockGlobals is defined. So if you want to have things added to a custom object instead, just do something like window.GreenSockGlobals = {} before loading any GreenSock files. You can even set up an alias like window.GreenSockGlobals = windows.gs = {} so that you can access everything like gs.TweenLite. Also remember that ALL classes are added to the window.com.greensock object (in their respective packages, like com.greensock.easing.Power1, com.greensock.TweenLite, etc.)
22047					if (typeof module !== "undefined" && module.exports) {
22048						//node
22049						if (ns === moduleName) {
22050							module.exports = _exports[moduleName] = cl;
22051							for (i in _exports) {
22052								cl[i] = _exports[i];
22053							}
22054						} else if (_exports[moduleName]) {
22055							_exports[moduleName][n] = cl;
22056						}
22057					} else if (true) {
22058						//AMD
22059						!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function () {
22060							return cl;
22061						}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),
22062				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
22063					}
22064				}
22065				for (i = 0; i < this.sc.length; i++) {
22066					this.sc[i].check();
22067				}
22068			}
22069		};
22070		this.check(true);
22071	},
22072
22073
22074	//used to create Definition instances (which basically registers a class that has dependencies).
22075	_gsDefine = window._gsDefine = function (ns, dependencies, func, global) {
22076		return new Definition(ns, dependencies, func, global);
22077	},
22078
22079
22080	//a quick way to create a class that doesn't have any dependencies. Returns the class, but first registers it in the GreenSock namespace so that other classes can grab it (other classes might be dependent on the class).
22081	_class = gs._class = function (ns, func, global) {
22082		func = func || function () {};
22083		_gsDefine(ns, [], function () {
22084			return func;
22085		}, global);
22086		return func;
22087	};
22088
22089	_gsDefine.globals = _globals;
22090
22091	/*
22092  * ----------------------------------------------------------------
22093  * Ease
22094  * ----------------------------------------------------------------
22095  */
22096	var _baseParams = [0, 0, 1, 1],
22097	    Ease = _class("easing.Ease", function (func, extraParams, type, power) {
22098		this._func = func;
22099		this._type = type || 0;
22100		this._power = power || 0;
22101		this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams;
22102	}, true),
22103	    _easeMap = Ease.map = {},
22104	    _easeReg = Ease.register = function (ease, names, types, create) {
22105		var na = names.split(","),
22106		    i = na.length,
22107		    ta = (types || "easeIn,easeOut,easeInOut").split(","),
22108		    e,
22109		    name,
22110		    j,
22111		    type;
22112		while (--i > -1) {
22113			name = na[i];
22114			e = create ? _class("easing." + name, null, true) : gs.easing[name] || {};
22115			j = ta.length;
22116			while (--j > -1) {
22117				type = ta[j];
22118				_easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease();
22119			}
22120		}
22121	};
22122
22123	p = Ease.prototype;
22124	p._calcEnd = false;
22125	p.getRatio = function (p) {
22126		if (this._func) {
22127			this._params[0] = p;
22128			return this._func.apply(null, this._params);
22129		}
22130		var t = this._type,
22131		    pw = this._power,
22132		    r = t === 1 ? 1 - p : t === 2 ? p : p < 0.5 ? p * 2 : (1 - p) * 2;
22133		if (pw === 1) {
22134			r *= r;
22135		} else if (pw === 2) {
22136			r *= r * r;
22137		} else if (pw === 3) {
22138			r *= r * r * r;
22139		} else if (pw === 4) {
22140			r *= r * r * r * r;
22141		}
22142		return t === 1 ? 1 - r : t === 2 ? r : p < 0.5 ? r / 2 : 1 - r / 2;
22143	};
22144
22145	//create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut)
22146	a = ["Linear", "Quad", "Cubic", "Quart", "Quint,Strong"];
22147	i = a.length;
22148	while (--i > -1) {
22149		p = a[i] + ",Power" + i;
22150		_easeReg(new Ease(null, null, 1, i), p, "easeOut", true);
22151		_easeReg(new Ease(null, null, 2, i), p, "easeIn" + (i === 0 ? ",easeNone" : ""));
22152		_easeReg(new Ease(null, null, 3, i), p, "easeInOut");
22153	}
22154	_easeMap.linear = gs.easing.Linear.easeIn;
22155	_easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks
22156
22157
22158	/*
22159  * ----------------------------------------------------------------
22160  * EventDispatcher
22161  * ----------------------------------------------------------------
22162  */
22163	var EventDispatcher = _class("events.EventDispatcher", function (target) {
22164		this._listeners = {};
22165		this._eventTarget = target || this;
22166	});
22167	p = EventDispatcher.prototype;
22168
22169	p.addEventListener = function (type, callback, scope, useParam, priority) {
22170		priority = priority || 0;
22171		var list = this._listeners[type],
22172		    index = 0,
22173		    listener,
22174		    i;
22175		if (this === _ticker && !_tickerActive) {
22176			_ticker.wake();
22177		}
22178		if (list == null) {
22179			this._listeners[type] = list = [];
22180		}
22181		i = list.length;
22182		while (--i > -1) {
22183			listener = list[i];
22184			if (listener.c === callback && listener.s === scope) {
22185				list.splice(i, 1);
22186			} else if (index === 0 && listener.pr < priority) {
22187				index = i + 1;
22188			}
22189		}
22190		list.splice(index, 0, { c: callback, s: scope, up: useParam, pr: priority });
22191	};
22192
22193	p.removeEventListener = function (type, callback) {
22194		var list = this._listeners[type],
22195		    i;
22196		if (list) {
22197			i = list.length;
22198			while (--i > -1) {
22199				if (list[i].c === callback) {
22200					list.splice(i, 1);
22201					return;
22202				}
22203			}
22204		}
22205	};
22206
22207	p.dispatchEvent = function (type) {
22208		var list = this._listeners[type],
22209		    i,
22210		    t,
22211		    listener;
22212		if (list) {
22213			i = list.length;
22214			if (i > 1) {
22215				list = list.slice(0); //in case addEventListener() is called from within a listener/callback (otherwise the index could change, resulting in a skip)
22216			}
22217			t = this._eventTarget;
22218			while (--i > -1) {
22219				listener = list[i];
22220				if (listener) {
22221					if (listener.up) {
22222						listener.c.call(listener.s || t, { type: type, target: t });
22223					} else {
22224						listener.c.call(listener.s || t);
22225					}
22226				}
22227			}
22228		}
22229	};
22230
22231	/*
22232  * ----------------------------------------------------------------
22233  * Ticker
22234  * ----------------------------------------------------------------
22235  */
22236	var _reqAnimFrame = window.requestAnimationFrame,
22237	    _cancelAnimFrame = window.cancelAnimationFrame,
22238	    _getTime = Date.now || function () {
22239		return new Date().getTime();
22240	},
22241	    _lastUpdate = _getTime();
22242
22243	//now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill.
22244	a = ["ms", "moz", "webkit", "o"];
22245	i = a.length;
22246	while (--i > -1 && !_reqAnimFrame) {
22247		_reqAnimFrame = window[a[i] + "RequestAnimationFrame"];
22248		_cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"];
22249	}
22250
22251	_class("Ticker", function (fps, useRAF) {
22252		var _self = this,
22253		    _startTime = _getTime(),
22254		    _useRAF = useRAF !== false && _reqAnimFrame ? "auto" : false,
22255		    _lagThreshold = 500,
22256		    _adjustedLag = 33,
22257		    _tickWord = "tick",
22258		    //helps reduce gc burden
22259		_fps,
22260		    _req,
22261		    _id,
22262		    _gap,
22263		    _nextTime,
22264		    _tick = function (manual) {
22265			var elapsed = _getTime() - _lastUpdate,
22266			    overlap,
22267			    dispatch;
22268			if (elapsed > _lagThreshold) {
22269				_startTime += elapsed - _adjustedLag;
22270			}
22271			_lastUpdate += elapsed;
22272			_self.time = (_lastUpdate - _startTime) / 1000;
22273			overlap = _self.time - _nextTime;
22274			if (!_fps || overlap > 0 || manual === true) {
22275				_self.frame++;
22276				_nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap);
22277				dispatch = true;
22278			}
22279			if (manual !== true) {
22280				//make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise.
22281				_id = _req(_tick);
22282			}
22283			if (dispatch) {
22284				_self.dispatchEvent(_tickWord);
22285			}
22286		};
22287
22288		EventDispatcher.call(_self);
22289		_self.time = _self.frame = 0;
22290		_self.tick = function () {
22291			_tick(true);
22292		};
22293
22294		_self.lagSmoothing = function (threshold, adjustedLag) {
22295			if (!arguments.length) {
22296				//if lagSmoothing() is called with no arguments, treat it like a getter that returns a boolean indicating if it's enabled or not. This is purposely undocumented and is for internal use.
22297				return _lagThreshold < 1 / _tinyNum;
22298			}
22299			_lagThreshold = threshold || 1 / _tinyNum; //zero should be interpreted as basically unlimited
22300			_adjustedLag = Math.min(adjustedLag, _lagThreshold, 0);
22301		};
22302
22303		_self.sleep = function () {
22304			if (_id == null) {
22305				return;
22306			}
22307			if (!_useRAF || !_cancelAnimFrame) {
22308				clearTimeout(_id);
22309			} else {
22310				_cancelAnimFrame(_id);
22311			}
22312			_req = _emptyFunc;
22313			_id = null;
22314			if (_self === _ticker) {
22315				_tickerActive = false;
22316			}
22317		};
22318
22319		_self.wake = function (seamless) {
22320			if (_id !== null) {
22321				_self.sleep();
22322			} else if (seamless) {
22323				_startTime += -_lastUpdate + (_lastUpdate = _getTime());
22324			} else if (_self.frame > 10) {
22325				//don't trigger lagSmoothing if we're just waking up, and make sure that at least 10 frames have elapsed because of the iOS bug that we work around below with the 1.5-second setTimout().
22326				_lastUpdate = _getTime() - _lagThreshold + 5;
22327			}
22328			_req = _fps === 0 ? _emptyFunc : !_useRAF || !_reqAnimFrame ? function (f) {
22329				return setTimeout(f, (_nextTime - _self.time) * 1000 + 1 | 0);
22330			} : _reqAnimFrame;
22331			if (_self === _ticker) {
22332				_tickerActive = true;
22333			}
22334			_tick(2);
22335		};
22336
22337		_self.fps = function (value) {
22338			if (!arguments.length) {
22339				return _fps;
22340			}
22341			_fps = value;
22342			_gap = 1 / (_fps || 60);
22343			_nextTime = this.time + _gap;
22344			_self.wake();
22345		};
22346
22347		_self.useRAF = function (value) {
22348			if (!arguments.length) {
22349				return _useRAF;
22350			}
22351			_self.sleep();
22352			_useRAF = value;
22353			_self.fps(_fps);
22354		};
22355		_self.fps(fps);
22356
22357		//a bug in iOS 6 Safari occasionally prevents the requestAnimationFrame from working initially, so we use a 1.5-second timeout that automatically falls back to setTimeout() if it senses this condition.
22358		setTimeout(function () {
22359			if (_useRAF === "auto" && _self.frame < 5 && _doc.visibilityState !== "hidden") {
22360				_self.useRAF(false);
22361			}
22362		}, 1500);
22363	});
22364
22365	p = gs.Ticker.prototype = new gs.events.EventDispatcher();
22366	p.constructor = gs.Ticker;
22367
22368	/*
22369  * ----------------------------------------------------------------
22370  * Animation
22371  * ----------------------------------------------------------------
22372  */
22373	var Animation = _class("core.Animation", function (duration, vars) {
22374		this.vars = vars = vars || {};
22375		this._duration = this._totalDuration = duration || 0;
22376		this._delay = Number(vars.delay) || 0;
22377		this._timeScale = 1;
22378		this._active = vars.immediateRender === true;
22379		this.data = vars.data;
22380		this._reversed = vars.reversed === true;
22381
22382		if (!_rootTimeline) {
22383			return;
22384		}
22385		if (!_tickerActive) {
22386			//some browsers (like iOS 6 Safari) shut down JavaScript execution when the tab is disabled and they [occasionally] neglect to start up requestAnimationFrame again when returning - this code ensures that the engine starts up again properly.
22387			_ticker.wake();
22388		}
22389
22390		var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline;
22391		tl.add(this, tl._time);
22392
22393		if (this.vars.paused) {
22394			this.paused(true);
22395		}
22396	});
22397
22398	_ticker = Animation.ticker = new gs.Ticker();
22399	p = Animation.prototype;
22400	p._dirty = p._gc = p._initted = p._paused = false;
22401	p._totalTime = p._time = 0;
22402	p._rawPrevTime = -1;
22403	p._next = p._last = p._onUpdate = p._timeline = p.timeline = null;
22404	p._paused = false;
22405
22406	//some browsers (like iOS) occasionally drop the requestAnimationFrame event when the user switches to a different tab and then comes back again, so we use a 2-second setTimeout() to sense if/when that condition occurs and then wake() the ticker.
22407	var _checkTimeout = function () {
22408		if (_tickerActive && _getTime() - _lastUpdate > 2000 && (_doc.visibilityState !== "hidden" || !_ticker.lagSmoothing())) {
22409			//note: if the tab is hidden, we should still wake if lagSmoothing has been disabled.
22410			_ticker.wake();
22411		}
22412		var t = setTimeout(_checkTimeout, 2000);
22413		if (t.unref) {
22414			// allows a node process to exit even if the timeout’s callback hasn't been invoked. Without it, the node process could hang as this function is called every two seconds.
22415			t.unref();
22416		}
22417	};
22418	_checkTimeout();
22419
22420	p.play = function (from, suppressEvents) {
22421		if (from != null) {
22422			this.seek(from, suppressEvents);
22423		}
22424		return this.reversed(false).paused(false);
22425	};
22426
22427	p.pause = function (atTime, suppressEvents) {
22428		if (atTime != null) {
22429			this.seek(atTime, suppressEvents);
22430		}
22431		return this.paused(true);
22432	};
22433
22434	p.resume = function (from, suppressEvents) {
22435		if (from != null) {
22436			this.seek(from, suppressEvents);
22437		}
22438		return this.paused(false);
22439	};
22440
22441	p.seek = function (time, suppressEvents) {
22442		return this.totalTime(Number(time), suppressEvents !== false);
22443	};
22444
22445	p.restart = function (includeDelay, suppressEvents) {
22446		return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, suppressEvents !== false, true);
22447	};
22448
22449	p.reverse = function (from, suppressEvents) {
22450		if (from != null) {
22451			this.seek(from || this.totalDuration(), suppressEvents);
22452		}
22453		return this.reversed(true).paused(false);
22454	};
22455
22456	p.render = function (time, suppressEvents, force) {
22457		//stub - we override this method in subclasses.
22458	};
22459
22460	p.invalidate = function () {
22461		this._time = this._totalTime = 0;
22462		this._initted = this._gc = false;
22463		this._rawPrevTime = -1;
22464		if (this._gc || !this.timeline) {
22465			this._enabled(true);
22466		}
22467		return this;
22468	};
22469
22470	p.isActive = function () {
22471		var tl = this._timeline,
22472		    //the 2 root timelines won't have a _timeline; they're always active.
22473		startTime = this._startTime,
22474		    rawTime;
22475		return !tl || !this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime(true)) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale - 0.0000001;
22476	};
22477
22478	p._enabled = function (enabled, ignoreTimeline) {
22479		if (!_tickerActive) {
22480			_ticker.wake();
22481		}
22482		this._gc = !enabled;
22483		this._active = this.isActive();
22484		if (ignoreTimeline !== true) {
22485			if (enabled && !this.timeline) {
22486				this._timeline.add(this, this._startTime - this._delay);
22487			} else if (!enabled && this.timeline) {
22488				this._timeline._remove(this, true);
22489			}
22490		}
22491		return false;
22492	};
22493
22494	p._kill = function (vars, target) {
22495		return this._enabled(false, false);
22496	};
22497
22498	p.kill = function (vars, target) {
22499		this._kill(vars, target);
22500		return this;
22501	};
22502
22503	p._uncache = function (includeSelf) {
22504		var tween = includeSelf ? this : this.timeline;
22505		while (tween) {
22506			tween._dirty = true;
22507			tween = tween.timeline;
22508		}
22509		return this;
22510	};
22511
22512	p._swapSelfInParams = function (params) {
22513		var i = params.length,
22514		    copy = params.concat();
22515		while (--i > -1) {
22516			if (params[i] === "{self}") {
22517				copy[i] = this;
22518			}
22519		}
22520		return copy;
22521	};
22522
22523	p._callback = function (type) {
22524		var v = this.vars,
22525		    callback = v[type],
22526		    params = v[type + "Params"],
22527		    scope = v[type + "Scope"] || v.callbackScope || this,
22528		    l = params ? params.length : 0;
22529		switch (l) {//speed optimization; call() is faster than apply() so use it when there are only a few parameters (which is by far most common). Previously we simply did var v = this.vars; v[type].apply(v[type + "Scope"] || v.callbackScope || this, v[type + "Params"] || _blankArray);
22530			case 0:
22531				callback.call(scope);break;
22532			case 1:
22533				callback.call(scope, params[0]);break;
22534			case 2:
22535				callback.call(scope, params[0], params[1]);break;
22536			default:
22537				callback.apply(scope, params);
22538		}
22539	};
22540
22541	//----Animation getters/setters --------------------------------------------------------
22542
22543	p.eventCallback = function (type, callback, params, scope) {
22544		if ((type || "").substr(0, 2) === "on") {
22545			var v = this.vars;
22546			if (arguments.length === 1) {
22547				return v[type];
22548			}
22549			if (callback == null) {
22550				delete v[type];
22551			} else {
22552				v[type] = callback;
22553				v[type + "Params"] = _isArray(params) && params.join("").indexOf("{self}") !== -1 ? this._swapSelfInParams(params) : params;
22554				v[type + "Scope"] = scope;
22555			}
22556			if (type === "onUpdate") {
22557				this._onUpdate = callback;
22558			}
22559		}
22560		return this;
22561	};
22562
22563	p.delay = function (value) {
22564		if (!arguments.length) {
22565			return this._delay;
22566		}
22567		if (this._timeline.smoothChildTiming) {
22568			this.startTime(this._startTime + value - this._delay);
22569		}
22570		this._delay = value;
22571		return this;
22572	};
22573
22574	p.duration = function (value) {
22575		if (!arguments.length) {
22576			this._dirty = false;
22577			return this._duration;
22578		}
22579		this._duration = this._totalDuration = value;
22580		this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration.
22581		if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) {
22582			this.totalTime(this._totalTime * (value / this._duration), true);
22583		}
22584		return this;
22585	};
22586
22587	p.totalDuration = function (value) {
22588		this._dirty = false;
22589		return !arguments.length ? this._totalDuration : this.duration(value);
22590	};
22591
22592	p.time = function (value, suppressEvents) {
22593		if (!arguments.length) {
22594			return this._time;
22595		}
22596		if (this._dirty) {
22597			this.totalDuration();
22598		}
22599		return this.totalTime(value > this._duration ? this._duration : value, suppressEvents);
22600	};
22601
22602	p.totalTime = function (time, suppressEvents, uncapped) {
22603		if (!_tickerActive) {
22604			_ticker.wake();
22605		}
22606		if (!arguments.length) {
22607			return this._totalTime;
22608		}
22609		if (this._timeline) {
22610			if (time < 0 && !uncapped) {
22611				time += this.totalDuration();
22612			}
22613			if (this._timeline.smoothChildTiming) {
22614				if (this._dirty) {
22615					this.totalDuration();
22616				}
22617				var totalDuration = this._totalDuration,
22618				    tl = this._timeline;
22619				if (time > totalDuration && !uncapped) {
22620					time = totalDuration;
22621				}
22622				this._startTime = (this._paused ? this._pauseTime : tl._time) - (!this._reversed ? time : totalDuration - time) / this._timeScale;
22623				if (!tl._dirty) {
22624					//for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here.
22625					this._uncache(false);
22626				}
22627				//in case any of the ancestor timelines had completed but should now be enabled, we should reset the
22627ir totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The startTime of that child would get pushed out, but one of the ancestors may have completed.
22628				if (tl._timeline) {
22629					while (tl._timeline) {
22630						if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) {
22631							tl.totalTime(tl._totalTime, true);
22632						}
22633						tl = tl._timeline;
22634					}
22635				}
22636			}
22637			if (this._gc) {
22638				this._enabled(true, false);
22639			}
22640			if (this._totalTime !== time || this._duration === 0) {
22641				if (_lazyTweens.length) {
22642					_lazyRender();
22643				}
22644				this.render(time, suppressEvents, false);
22645				if (_lazyTweens.length) {
22646					//in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render.
22647					_lazyRender();
22648				}
22649			}
22650		}
22651		return this;
22652	};
22653
22654	p.progress = p.totalProgress = function (value, suppressEvents) {
22655		var duration = this.duration();
22656		return !arguments.length ? duration ? this._time / duration : this.ratio : this.totalTime(duration * value, suppressEvents);
22657	};
22658
22659	p.startTime = function (value) {
22660		if (!arguments.length) {
22661			return this._startTime;
22662		}
22663		if (value !== this._startTime) {
22664			this._startTime = value;
22665			if (this.timeline) if (this.timeline._sortChildren) {
22666				this.timeline.add(this, value - this._delay); //ensures that any necessary re-sequencing of Animations in the timeline occurs to make sure the rendering order is correct.
22667			}
22668		}
22669		return this;
22670	};
22671
22672	p.endTime = function (includeRepeats) {
22673		return this._startTime + (includeRepeats != false ? this.totalDuration() : this.duration()) / this._timeScale;
22674	};
22675
22676	p.timeScale = function (value) {
22677		if (!arguments.length) {
22678			return this._timeScale;
22679		}
22680		var pauseTime, t;
22681		value = value || _tinyNum; //can't allow zero because it'll throw the math off
22682		if (this._timeline && this._timeline.smoothChildTiming) {
22683			pauseTime = this._pauseTime;
22684			t = pauseTime || pauseTime === 0 ? pauseTime : this._timeline.totalTime();
22685			this._startTime = t - (t - this._startTime) * this._timeScale / value;
22686		}
22687		this._timeScale = value;
22688		t = this.timeline;
22689		while (t && t.timeline) {
22690			//must update the duration/totalDuration of all ancestor timelines immediately in case in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though.
22691			t._dirty = true;
22692			t.totalDuration();
22693			t = t.timeline;
22694		}
22695		return this;
22696	};
22697
22698	p.reversed = function (value) {
22699		if (!arguments.length) {
22700			return this._reversed;
22701		}
22702		if (value != this._reversed) {
22703			this._reversed = value;
22704			this.totalTime(this._timeline && !this._timeline.smoothChildTiming ? this.totalDuration() - this._totalTime : this._totalTime, true);
22705		}
22706		return this;
22707	};
22708
22709	p.paused = function (value) {
22710		if (!arguments.length) {
22711			return this._paused;
22712		}
22713		var tl = this._timeline,
22714		    raw,
22715		    elapsed;
22716		if (value != this._paused) if (tl) {
22717			if (!_tickerActive && !value) {
22718				_ticker.wake();
22719			}
22720			raw = tl.rawTime();
22721			elapsed = raw - this._pauseTime;
22722			if (!value && tl.smoothChildTiming) {
22723				this._startTime += elapsed;
22724				this._uncache(false);
22725			}
22726			this._pauseTime = value ? raw : null;
22727			this._paused = value;
22728			this._active = this.isActive();
22729			if (!value && elapsed !== 0 && this._initted && this.duration()) {
22730				raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale;
22731				this.render(raw, raw === this._totalTime, true); //in case the target's properties changed via some other tween or manual update by the user, we should force a render.
22732			}
22733		}
22734		if (this._gc && !value) {
22735			this._enabled(true, false);
22736		}
22737		return this;
22738	};
22739
22740	/*
22741  * ----------------------------------------------------------------
22742  * SimpleTimeline
22743  * ----------------------------------------------------------------
22744  */
22745	var SimpleTimeline = _class("core.SimpleTimeline", function (vars) {
22746		Animation.call(this, 0, vars);
22747		this.autoRemoveChildren = this.smoothChildTiming = true;
22748	});
22749
22750	p = SimpleTimeline.prototype = new Animation();
22751	p.constructor = SimpleTimeline;
22752	p.kill()._gc = false;
22753	p._first = p._last = p._recent = null;
22754	p._sortChildren = false;
22755
22756	p.add = p.insert = function (child, position, align, stagger) {
22757		var prevTween, st;
22758		child._startTime = Number(position || 0) + child._delay;
22759		if (child._paused) if (this !== child._timeline) {
22760			//we only adjust the _pauseTime if it wasn't in this timeline already. Remember, sometimes a tween will be inserted again into the same timeline when its startTime is changed so that the tweens in the TimelineLite/Max are re-ordered properly in the linked list (so everything renders in the proper order).
22761			child._pauseTime = child._startTime + (this.rawTime() - child._startTime) / child._timeScale;
22762		}
22763		if (child.timeline) {
22764			child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one.
22765		}
22766		child.timeline = child._timeline = this;
22767		if (child._gc) {
22768			child._enabled(true, true);
22769		}
22770		prevTween = this._last;
22771		if (this._sortChildren) {
22772			st = child._startTime;
22773			while (prevTween && prevTween._startTime > st) {
22774				prevTween = prevTween._prev;
22775			}
22776		}
22777		if (prevTween) {
22778			child._next = prevTween._next;
22779			prevTween._next = child;
22780		} else {
22781			child._next = this._first;
22782			this._first = child;
22783		}
22784		if (child._next) {
22785			child._next._prev = child;
22786		} else {
22787			this._last = child;
22788		}
22789		child._prev = prevTween;
22790		this._recent = child;
22791		if (this._timeline) {
22792			this._uncache(true);
22793		}
22794		return this;
22795	};
22796
22797	p._remove = function (tween, skipDisable) {
22798		if (tween.timeline === this) {
22799			if (!skipDisable) {
22800				tween._enabled(false, true);
22801			}
22802
22803			if (tween._prev) {
22804				tween._prev._next = tween._next;
22805			} else if (this._first === tween) {
22806				this._first = tween._next;
22807			}
22808			if (tween._next) {
22809				tween._next._prev = tween._prev;
22810			} else if (this._last === tween) {
22811				this._last = tween._prev;
22812			}
22813			tween._next = tween._prev = tween.timeline = null;
22814			if (tween === this._recent) {
22815				this._recent = this._last;
22816			}
22817
22818			if (this._timeline) {
22819				this._uncache(true);
22820			}
22821		}
22822		return this;
22823	};
22824
22825	p.render = function (time, suppressEvents, force) {
22826		var tween = this._first,
22827		    next;
22828		this._totalTime = this._time = this._rawPrevTime = time;
22829		while (tween) {
22830			next = tween._next; //record it here because the value could change after rendering...
22831			if (tween._active || time >= tween._startTime && !tween._paused && !tween._gc) {
22832				if (!tween._reversed) {
22833					tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
22834				} else {
22835					tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
22836				}
22837			}
22838			tween = next;
22839		}
22840	};
22841
22842	p.rawTime = function () {
22843		if (!_tickerActive) {
22844			_ticker.wake();
22845		}
22846		return this._totalTime;
22847	};
22848
22849	/*
22850  * ----------------------------------------------------------------
22851  * TweenLite
22852  * ----------------------------------------------------------------
22853  */
22854	var TweenLite = _class("TweenLite", function (target, duration, vars) {
22855		Animation.call(this, duration, vars);
22856		this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
22857
22858		if (target == null) {
22859			throw "Cannot tween a null target.";
22860		}
22861
22862		this.target = target = typeof target !== "string" ? target : TweenLite.selector(target) || target;
22863
22864		var isSelector = target.jquery || target.length && target !== window && target[0] && (target[0] === window || target[0].nodeType && target[0].style && !target.nodeType),
22865		    overwrite = this.vars.overwrite,
22866		    i,
22867		    targ,
22868		    targets;
22869
22870		this._overwrite = overwrite = overwrite == null ? _overwriteLookup[TweenLite.defaultOverwrite] : typeof overwrite === "number" ? overwrite >> 0 : _overwriteLookup[overwrite];
22871
22872		if ((isSelector || target instanceof Array || target.push && _isArray(target)) && typeof target[0] !== "number") {
22873			this._targets = targets = _slice(target); //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
22874			this._propLookup = [];
22875			this._siblings = [];
22876			for (i = 0; i < targets.length; i++) {
22877				targ = targets[i];
22878				if (!targ) {
22879					targets.splice(i--, 1);
22880					continue;
22881				} else if (typeof targ === "string") {
22882					targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings
22883					if (typeof targ === "string") {
22884						targets.splice(i + 1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case)
22885					}
22886					continue;
22887				} else if (targ.length && targ !== window && targ[0] && (targ[0] === window || targ[0].nodeType && targ[0].style && !targ.nodeType)) {
22888					//in case the user is passing in an array of selector objects (like jQuery objects), we need to check one more level and pull things out if necessary. Also note that <select> elements pass all the criteria regarding length and the first child having style, so we must also check to ensure the target isn't an HTML node itself.
22889					targets.splice(i--, 1);
22890					this._targets = targets = targets.concat(_slice(targ));
22891					continue;
22892				}
22893				this._siblings[i] = _register(targ, this, false);
22894				if (overwrite === 1) if (this._siblings[i].length > 1) {
22895					_applyOverwrite(targ, this, null, 1, this._siblings[i]);
22896				}
22897			}
22898		} else {
22899			this._propLookup = {};
22900			this._siblings = _register(target, this, false);
22901			if (overwrite === 1) if (this._siblings.length > 1) {
22902				_applyOverwrite(target, this, null, 1, this._siblings);
22903			}
22904		}
22905		if (this.vars.immediateRender || duration === 0 && this._delay === 0 && this.vars.immediateRender !== false) {
22906			this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render)
22907			this.render(Math.min(0, -this._delay)); //in case delay is negative
22908		}
22909	}, true),
22910	    _isSelector = function (v) {
22911		return v && v.length && v !== window && v[0] && (v[0] === window || v[0].nodeType && v[0].style && !v.nodeType); //we cannot check "nodeType" if the target is window from within an iframe, otherwise it will trigger a security error in some browsers like Firefox.
22912	},
22913	    _autoCSS = function (vars, target) {
22914		var css = {},
22915		    p;
22916		for (p in vars) {
22917			if (!_reservedProps[p] && (!(p in target) || p === "transform" || p === "x" || p === "y" || p === "width" || p === "height" || p === "className" || p === "border") && (!_plugins[p] || _plugins[p] && _plugins[p]._autoCSS)) {
22918				//note: <img> elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties.
22919				css[p] = vars[p];
22920				delete vars[p];
22921			}
22922		}
22923		vars.css = css;
22924	};
22925
22926	p = TweenLite.prototype = new Animation();
22927	p.constructor = TweenLite;
22928	p.kill()._gc = false;
22929
22930	//----TweenLite defaults, overwrite management, and root updates ----------------------------------------------------
22931
22932	p.ratio = 0;
22933	p._firstPT = p._targets = p._overwrittenProps = p._startAt = null;
22934	p._notifyPluginsOfEnabled = p._lazy = false;
22935
22936	TweenLite.version = "1.20.3";
22937	TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1);
22938	TweenLite.defaultOverwrite = "auto";
22939	TweenLite.ticker = _ticker;
22940	TweenLite.autoSleep = 120;
22941	TweenLite.lagSmoothing = function (threshold, adjustedLag) {
22942		_ticker.lagSmoothing(threshold, adjustedLag);
22943	};
22944
22945	TweenLite.selector = window.$ || window.jQuery || function (e) {
22946		var selector = window.$ || window.jQuery;
22947		if (selector) {
22948			TweenLite.selector = selector;
22949			return selector(e);
22950		}
22951		return typeof _doc === "undefined" ? e : _doc.querySelectorAll ? _doc.querySelectorAll(e) : _doc.getElementById(e.charAt(0) === "#" ? e.substr(1) : e);
22952	};
22953
22954	var _lazyTweens = [],
22955	    _lazyLookup = {},
22956	    _numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
22957	    _relExp = /[\+-]=-?[\.\d]/,
22958
22959	//_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig,
22960	_setRatio = function (v) {
22961		var pt = this._firstPT,
22962		    min = 0.000001,
22963		    val;
22964		while (pt) {
22965			val = !pt.blob ? pt.c * v + pt.s : v === 1 && this.end != null ? this.end : v ? this.join("") : this.start;
22966			if (pt.m) {
22967				val = pt.m(val, this._target || pt.t);
22968			} else if (val < min) if (val > -min && !pt.blob) {
22969				//prevents issues with converting very small numbers to strings in the browser
22970				val = 0;
22971			}
22972			if (!pt.f) {
22973				pt.t[pt.p] = val;
22974			} else if (pt.fp) {
22975				pt.t[pt.p](pt.fp, val);
22976			} else {
22977				pt.t[pt.p](val);
22978			}
22979			pt = pt._next;
22980		}
22981	},
22982
22983	//compares two strings (start/end), finds the numbers that are different and spits back an array representing the whole value but with the changing values isolated as elements. For example, "rgb(0,0,0)" and "rgb(100,50,0)" would become ["rgb(", 0, ",", 50, ",0)"]. Notice it merges the parts that are identical (performance optimization). The array also has a linked list of PropTweens attached starting with _firstPT that contain the tweening data (t, p, s, c, f, etc.). It also stores the starting value as a "start" property so that we can revert to it if/when necessary, like when a tween rewinds fully. If the quantity of numbers differs between the start and end, it will always prioritize the end value(s). The pt parameter is optional - it's for a PropTween that will be appended to the end of the linked list and is typically for actually setting the value after all of the elements have been updated (with array.join("")).
22984	_blobDif = function (start, end, filter, pt) {
22985		var a = [],
22986		    charIndex = 0,
22987		    s = "",
22988		    color = 0,
22989		    startNums,
22990		    endNums,
22991		    num,
22992		    i,
22993		    l,
22994		    nonNumbers,
22995		    currentNum;
22996		a.start = start;
22997		a.end = end;
22998		start = a[0] = start + ""; //ensure values are strings
22999		end = a[1] = end + "";
23000		if (filter) {
23001			filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.
23002			start = a[0];
23003			end = a[1];
23004		}
23005		a.length = 0;
23006		startNums = start.match(_numbersExp) || [];
23007		endNums = end.match(_numbersExp) || [];
23008		if (pt) {
23009			pt._next = null;
23010			pt.blob = 1;
23011			a._firstPT = a._applyPT = pt; //apply last in the linked list (which means inserting it first)
23012		}
23013		l = endNums.length;
23014		for (i = 0; i < l; i++) {
23015			currentNum = endNums[i];
23016			nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex) - charIndex);
23017			s += nonNumbers || !i ? nonNumbers : ","; //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case.
23018			charIndex += nonNumbers.length;
23019			if (color) {
23020				//sense rgba() values and round them.
23021				color = (color + 1) % 5;
23022			} else if (nonNumbers.substr(-5) === "rgba(") {
23023				color = 1;
23024			}
23025			if (currentNum === startNums[i] || startNums.length <= i) {
23026				s += currentNum;
23027			} else {
23028				if (s) {
23029					a.push(s);
23030					s = "";
23031				}
23032				num = parseFloat(startNums[i]);
23033				a.push(num);
23034				a._firstPT = { _next: a._firstPT, t: a, p: a.length - 1, s: num, c: (currentNum.charAt(1) === "=" ? parseInt(currentNum.charAt(0) + "1", 10) * parseFloat(currentNum.substr(2)) : parseFloat(currentNum) - num) || 0, f: 0, m: color && color < 4 ? Math.round : 0 };
23035				//note: we don't set _prev because we'll never need to remove individual PropTweens from this list.
23036			}
23037			charIndex += currentNum.length;
23038		}
23039		s += end.substr(charIndex);
23040		if (s) {
23041			a.push(s);
23042		}
23043		a.setRatio = _setRatio;
23044		if (_relExp.test(end)) {
23045			//if the end string contains relative values, delete it so that on the final render (in _setRatio()), we don't actually set it to the string with += or -= characters (forces it to use the calculated value).
23046			a.end = null;
23047		}
23048		return a;
23049	},
23050
23051	//note: "funcParam" is only necessary for function-based getters/setters that require an extra parameter like getAttribute("width") and setAttribute("width", value). In this example, funcParam would be "width". Used by AttrPlugin for example.
23052	_addPropTween = function (target, prop, start, end, overwriteProp, mod, funcParam, stringFilter, index) {
23053		if (typeof end === "function") {
23054			end = end(index || 0, target);
23055		}
23056		var type = typeof target[prop],
23057		    getterName = type !== "function" ? "" : prop.indexOf("set") || typeof target["get" + prop.substr(3)] !== "function" ? prop : "get" + prop.substr(3),
23058		    s = start !== "get" ? start : !getterName ? target[prop] : funcParam ? target[getterName](funcParam) : target[getterName](),
23059		    isRelative = typeof end === "string" && end.charAt(1) === "=",
23060		    pt = { t: target, p: prop, s: s, f: type === "function", pg: 0, n: overwriteProp || prop, m: !mod ? 0 : typeof mod === "function" ? mod : Math.round, pr: 0, c: isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : parseFloat(end) - s || 0 },
23061		    blob;
23062
23063		if (typeof s !== "number" || typeof end !== "number" && !isRelative) {
23064			if (funcParam || isNaN(s) || !isRelative && isNaN(end) || typeof s === "boolean" || typeof end === "boolean") {
23065				//a blob (string that has multiple numbers in it)
23066				pt.fp = funcParam;
23067				blob = _blobDif(s, isRelative ? parseFloat(pt.s) + pt.c : end, stringFilter || TweenLite.defaultStringFilter, pt);
23068				pt = { t: blob, p: "setRatio", s: 0, c: 1, f: 2, pg: 0, n: overwriteProp || prop, pr: 0, m: 0 }; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example.
23069			} else {
23070				pt.s = parseFloat(s);
23071				if (!isRelative) {
23072					pt.c = parseFloat(end) - pt.s || 0;
23073				}
23074			}
23075		}
23076		if (pt.c) {
23077			//only add it to the linked list if there's a change.
23078			if (pt._next = this._firstPT) {
23079				pt._next._prev = pt;
23080			}
23081			this._firstPT = pt;
23082			return pt;
23083		}
23084	},
23085	    _internals = TweenLite._internals = { isArray: _isArray, isSelector: _isSelector, lazyTweens: _lazyTweens, blobDif: _blobDif },
23086	    //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object.
23087	_plugins = TweenLite._plugins = {},
23088	    _tweenLookup = _internals.tweenLookup = {},
23089	    _tweenLookupNum = 0,
23090	    _reservedProps = _internals.reservedProps = { ease: 1, delay: 1, overwrite: 1, onComplete: 1, onCompleteParams: 1, onCompleteScope: 1, useFrames: 1, runBackwards: 1, startAt: 1, onUpdate: 1, onUpdateParams: 1, onUpdateScope: 1, onStart: 1, onStartParams: 1, onStartScope: 1, onReverseComplete: 1, onReverseCompleteParams: 1, onReverseCompleteScope: 1, onRepeat: 1, onRepeatParams: 1, onRepeatScope: 1, easeParams: 1, yoyo: 1, immediateRender: 1, repeat: 1, repeatDelay: 1, data: 1, paused: 1, reversed: 1, autoCSS: 1, lazy: 1, onOverwrite: 1, callbackScope: 1, str
23090ingFilter: 1, id: 1, yoyoEase: 1 },
23091	    _overwriteLookup = { none: 0, all: 1, auto: 2, concurrent: 3, allOnStart: 4, preexisting: 5, "true": 1, "false": 0 },
23092	    _rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(),
23093	    _rootTimeline = Animation._rootTimeline = new SimpleTimeline(),
23094	    _nextGCFrame = 30,
23095	    _lazyRender = _internals.lazyRender = function () {
23096		var i = _lazyTweens.length,
23097		    tween;
23098		_lazyLookup = {};
23099		while (--i > -1) {
23100			tween = _lazyTweens[i];
23101			if (tween && tween._lazy !== false) {
23102				tween.render(tween._lazy[0], tween._lazy[1], true);
23103				tween._lazy = false;
23104			}
23105		}
23106		_lazyTweens.length = 0;
23107	};
23108
23109	_rootTimeline._startTime = _ticker.time;
23110	_rootFramesTimeline._startTime = _ticker.frame;
23111	_rootTimeline._active = _rootFramesTimeline._active = true;
23112	setTimeout(_lazyRender, 1); //on some mobile devices, there isn't a "tick" before code runs which means any lazy renders wouldn't run before the next official "tick".
23113
23114	Animation._updateRoot = TweenLite.render = function () {
23115		var i, a, p;
23116		if (_lazyTweens.length) {
23117			//if code is run outside of the requestAnimationFrame loop, there may be tweens queued AFTER the engine refreshed, so we need to ensure any pending renders occur before we refresh again.
23118			_lazyRender();
23119		}
23120		_rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false);
23121		_rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false);
23122		if (_lazyTweens.length) {
23123			_lazyRender();
23124		}
23125		if (_ticker.frame >= _nextGCFrame) {
23126			//dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to
23127			_nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120);
23128			for (p in _tweenLookup) {
23129				a = _tweenLookup[p].tweens;
23130				i = a.length;
23131				while (--i > -1) {
23132					if (a[i]._gc) {
23133						a.splice(i, 1);
23134					}
23135				}
23136				if (a.length === 0) {
23137					delete _tweenLookup[p];
23138				}
23139			}
23140			//if there are no more tweens in the root timelines, or if they're all paused, make the _timer sleep to reduce load on the CPU slightly
23141			p = _rootTimeline._first;
23142			if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) {
23143				while (p && p._paused) {
23144					p = p._next;
23145				}
23146				if (!p) {
23147					_ticker.sleep();
23148				}
23149			}
23150		}
23151	};
23152
23153	_ticker.addEventListener("tick", Animation._updateRoot);
23154
23155	var _register = function (target, tween, scrub) {
23156		var id = target._gsTweenID,
23157		    a,
23158		    i;
23159		if (!_tweenLookup[id || (target._gsTweenID = id = "t" + _tweenLookupNum++)]) {
23160			_tweenLookup[id] = { target: target, tweens: [] };
23161		}
23162		if (tween) {
23163			a = _tweenLookup[id].tweens;
23164			a[i = a.length] = tween;
23165			if (scrub) {
23166				while (--i > -1) {
23167					if (a[i] === tween) {
23168						a.splice(i, 1);
23169					}
23170				}
23171			}
23172		}
23173		return _tweenLookup[id].tweens;
23174	},
23175	    _onOverwrite = function (overwrittenTween, overwritingTween, target, killedProps) {
23176		var func = overwrittenTween.vars.onOverwrite,
23177		    r1,
23178		    r2;
23179		if (func) {
23180			r1 = func(overwrittenTween, overwritingTween, target, killedProps);
23181		}
23182		func = TweenLite.onOverwrite;
23183		if (func) {
23184			r2 = func(overwrittenTween, overwritingTween, target, killedProps);
23185		}
23186		return r1 !== false && r2 !== false;
23187	},
23188	    _applyOverwrite = function (target, tween, props, mode, siblings) {
23189		var i, changed, curTween, l;
23190		if (mode === 1 || mode >= 4) {
23191			l = siblings.length;
23192			for (i = 0; i < l; i++) {
23193				if ((curTween = siblings[i]) !== tween) {
23194					if (!curTween._gc) {
23195						if (curTween._kill(null, target, tween)) {
23196							changed = true;
23197						}
23198					}
23199				} else if (mode === 5) {
23200					break;
23201				}
23202			}
23203			return changed;
23204		}
23205		//NOTE: Add 0.0000000001 to overcome floating point errors that can cause the startTime to be VERY slightly off (when a tween's time() is set for example)
23206		var startTime = tween._startTime + _tinyNum,
23207		    overlaps = [],
23208		    oCount = 0,
23209		    zeroDur = tween._duration === 0,
23210		    globalStart;
23211		i = siblings.length;
23212		while (--i > -1) {
23213			if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) {
23214				//ignore
23215			} else if (curTween._timeline !== tween._timeline) {
23216				globalStart = globalStart || _checkOverlap(tween, 0, zeroDur);
23217				if (_checkOverlap(curTween, globalStart, zeroDur) === 0) {
23218					overlaps[oCount++] = curTween;
23219				}
23220			} else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) {
23221				overlaps[oCount++] = curTween;
23222			}
23223		}
23224
23225		i = oCount;
23226		while (--i > -1) {
23227			curTween = overlaps[i];
23228			if (mode === 2) if (curTween._kill(props, target, tween)) {
23229				changed = true;
23230			}
23231			if (mode !== 2 || !curTween._firstPT && curTween._initted) {
23232				if (mode !== 2 && !_onOverwrite(curTween, tween)) {
23233					continue;
23234				}
23235				if (curTween._enabled(false, false)) {
23236					//if all property tweens have been overwritten, kill the tween.
23237					changed = true;
23238				}
23239			}
23240		}
23241		return changed;
23242	},
23243	    _checkOverlap = function (tween, reference, zeroDur) {
23244		var tl = tween._timeline,
23245		    ts = tl._timeScale,
23246		    t = tween._startTime;
23247		while (tl._timeline) {
23248			t += tl._startTime;
23249			ts *= tl._timeScale;
23250			if (tl._paused) {
23251				return -100;
23252			}
23253			tl = tl._timeline;
23254		}
23255		t /= ts;
23256		return t > reference ? t - reference : zeroDur && t === reference || !tween._initted && t - reference < 2 * _tinyNum ? _tinyNum : (t += tween.totalDuration() / tween._timeScale / ts) > reference + _tinyNum ? 0 : t - reference - _tinyNum;
23257	};
23258
23259	//---- TweenLite instance methods -----------------------------------------------------------------------------
23260
23261	p._init = function () {
23262		var v = this.vars,
23263		    op = this._overwrittenProps,
23264		    dur = this._duration,
23265		    immediate = !!v.immediateRender,
23266		    ease = v.ease,
23267		    i,
23268		    initPlugins,
23269		    pt,
23270		    p,
23271		    startVars,
23272		    l;
23273		if (v.startAt) {
23274			if (this._startAt) {
23275				this._startAt.render(-1, true); //if we've run a startAt previously (when the tween instantiated), we should revert it so that the values re-instantiate correctly particularly for relative tweens. Without this, a TweenLite.fromTo(obj, 1, {x:"+=100"}, {x:"-=100"}), for example, would actually jump to +=200 because the startAt would run twice, doubling the relative change.
23276				this._startAt.kill();
23277			}
23278			startVars = {};
23279			for (p in v.startAt) {
23280				//copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, 1, from, to).fromTo(e, 1, to, from);
23281				startVars[p] = v.startAt[p];
23282			}
23283			startVars.data = "isStart";
23284			startVars.overwrite = false;
23285			startVars.immediateRender = true;
23286			startVars.lazy = immediate && v.lazy !== false;
23287			startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop).
23288			startVars.onUpdate = v.onUpdate;
23289			startVars.onUpdateParams = v.onUpdateParams;
23290			startVars.onUpdateScope = v.onUpdateScope || v.callbackScope || this;
23291			this._startAt = TweenLite.to(this.target, 0, startVars);
23292			if (immediate) {
23293				if (this._time > 0) {
23294					this._startAt = null; //tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in TimelineLite/Max instances where immediateRender was false (which is the default in the convenience methods like from()).
23295				} else if (dur !== 0) {
23296					return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a TimelineLite or TimelineMax, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting.
23297				}
23298			}
23299		} else if (v.runBackwards && dur !== 0) {
23300			//from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards)
23301			if (this._startAt) {
23302				this._startAt.render(-1, true);
23303				this._startAt.kill();
23304				this._startAt = null;
23305			} else {
23306				if (this._time !== 0) {
23307					//in rare cases (like if a from() tween runs and then is invalidate()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0
23308					immediate = false;
23309				}
23310				pt = {};
23311				for (p in v) {
23312					//copy props into a new object and skip any reserved props, otherwise onComplete or onUpdate or onStart could fire. We should, however, permit autoCSS to go through.
23313					if (!_reservedProps[p] || p === "autoCSS") {
23314						pt[p] = v[p];
23315					}
23316				}
23317				pt.overwrite = 0;
23318				pt.data = "isFromStart"; //we tag the tween with as "isFromStart" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a "from()" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in.
23319				pt.lazy = immediate && v.lazy !== false;
23320				pt.immediateRender = immediate; //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after)
23321				this._startAt = TweenLite.to(this.target, 0, pt);
23322				if (!immediate) {
23323					this._startAt._init(); //ensures that the initial values are recorded
23324					this._startAt._enabled(false); //no need to have the tween render on the next cycle. Disable it because we'll always manually control the renders of the _startAt tween.
23325					if (this.vars.immediateRender) {
23326						this._startAt = null;
23327					}
23328				} else if (this._time === 0) {
23329					return;
23330				}
23331			}
23332		}
23333		this._ease = ease = !ease ? TweenLite.defaultEase : ease instanceof Ease ? ease : typeof ease === "function" ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase;
23334		if (v.easeParams instanceof Array && ease.config) {
23335			this._ease = ease.config.apply(ease, v.easeParams);
23336		}
23337		this._easeType = this._ease._type;
23338		this._easePower = this._ease._power;
23339		this._firstPT = null;
23340
23341		if (this._targets) {
23342			l = this._targets.length;
23343			for (i = 0; i < l; i++) {
23344				if (this._initProps(this._targets[i], this._propLookup[i] = {}, this._siblings[i], op ? op[i] : null, i)) {
23345					initPlugins = true;
23346				}
23347			}
23348		} else {
23349			initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op, 0);
23350		}
23351
23352		if (initPlugins) {
23353			TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite
23354		}
23355		if (op) if (!this._firstPT) if (typeof this.target !== "function") {
23356			//if all tweening properties have been overwritten, kill the tween. If the target is a function, it's probably a delayedCall so let it live.
23357			this._enabled(false, false);
23358		}
23359		if (v.runBackwards) {
23360			pt = this._firstPT;
23361			while (pt) {
23362				pt.s += pt.c;
23363				pt.c = -pt.c;
23364				pt = pt._next;
23365			}
23366		}
23367		this._onUpdate = v.onUpdate;
23368		this._initted = true;
23369	};
23370
23371	p._initProps = function (target, propLookup, siblings, overwrittenProps, index) {
23372		var p, i, initPlugins, plugin, pt, v;
23373		if (target == null) {
23374			return false;
23375		}
23376
23377		if (_lazyLookup[target._gsTweenID]) {
23378			_lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end)
23379		}
23380
23381		if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) {
23382			//it's so common to use TweenLite/Max to animate the css of DOM elements, we assume that if the target is a DOM element, that's what is intended (a convenience so that users don't have to wrap things in css:{}, although we still recommend it for a slight performance boost and better specificity). Note: we cannot check "nodeType" on the window inside an iframe.
23383			_autoCSS(this.vars, target);
23384		}
23385		for (p in this.vars) {
23386			v = this.vars[p];
23387			if (_reservedProps[p]) {
23388				if (v) if (v instanceof Array || v.push && _isArray(v)) if (v.join("").indexOf("{self}") !== -1) {
23389					this.vars[p] = v = this._swapSelfInParams(v, this);
23390				}
23391			} else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this, index)) {
23392
23393				//t - target 		[object]
23394				//p - property 		[string]
23395				//s - start			[number]
23396				//c - change		[number]
23397				//f - isFunction	[boolean]
23398				//n - name			[string]
23399				//pg - isPlugin 	[boolean]
23400				//pr - priority		[number]
23401				//m - mod           [function | 0]
23402				this._firstPT = pt = { _next: this._firstPT, t: plugin, p: "setRatio", s: 0, c: 1, f: 1, n: p, pg: 1, pr: plugin._priority, m: 0 };
23403				i = plugin._overwriteProps.length;
23404				while (--i > -1) {
23405					propLookup[plugin._overwriteProps[i]] = this._firstPT;
23406				}
23407				if (plugin._priority || plugin._onInitAllProps) {
23408					initPlugins = true;
23409				}
23410				if (plugin._onDisable || plugin._onEnable) {
23411					this._notifyPluginsOfEnabled = true;
23412				}
23413				if (pt._next) {
23414					pt._next._prev = pt;
23415				}
23416			} else {
23417				propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter, index);
23418			}
23419		}
23420
23421		if (overwrittenProps) if (this._kill(overwrittenProps, target)) {
23422			//another tween may have tried to overwrite properties of this tween before init() was called (like if two tweens start at the same time, the one created second will run first)
23423			return this._initProps(target, propLookup, siblings, overwrittenProps, index);
23424		}
23425		if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) {
23426			this._kill(propLookup, target);
23427			return this._initProps(target, propLookup, siblings, overwrittenProps, index);
23428		}
23429		if (this._firstPT) if (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration) {
23430			//zero duration tweens don't lazy render by default; everything else does.
23431			_lazyLookup[target._gsTweenID] = true;
23432		}
23433		return initPlugins;
23434	};
23435
23436	p.render = function (time, suppressEvents, force) {
23437		var prevTime = this._time,
23438		    duration = this._duration,
23439		    prevRawPrevTime = this._rawPrevTime,
23440		    isComplete,
23441		    callback,
23442		    pt,
23443		    rawPrevTime;
23444		if (time >= duration - 0.0000001 && time >= 0) {
23445			//to work around occasional floating point math artifacts.
23446			this._totalTime = this._time = duration;
23447			this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
23448			if (!this._reversed) {
23449				isComplete = true;
23450				callback = "onComplete";
23451				force = force || this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
23452			}
23453			if (duration === 0) if (this._initted || !this.vars.lazy || force) {
23454				//zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
23455				if (this._startTime === this._timeline._duration) {
23456					//if a zero-duration tween is at the VERY end of a timeline and that timeline renders at its end, it will typically add a tiny bit of cushion to the render time to prevent roun
23456ding errors from getting in the way of tweens rendering their VERY end. If we then reverse() that timeline, the zero-duration tween will trigger its onReverseComplete even though technically the playhead didn't pass over it again. It's a very specific edge case we must accommodate.
23457					time = 0;
23458				}
23459				if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) {
23460					//note: when this.data is "isPause", it's a callback added by addPause() on a timeline that we should not be triggered when LEAVING its exact start time. In other words, tl.addPause(1).play(1) shouldn't pause.
23461					force = true;
23462					if (prevRawPrevTime > _tinyNum) {
23463						callback = "onReverseComplete";
23464					}
23465				}
23466				this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
23467			}
23468		} else if (time < 0.0000001) {
23469			//to work around occasional floating point math artifacts, round super small values to 0.
23470			this._totalTime = this._time = 0;
23471			this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
23472			if (prevTime !== 0 || duration === 0 && prevRawPrevTime > 0) {
23473				callback = "onReverseComplete";
23474				isComplete = this._reversed;
23475			}
23476			if (time < 0) {
23477				this._active = false;
23478				if (duration === 0) if (this._initted || !this.vars.lazy || force) {
23479					//zero-duration tweens are tricky because we must discern the momentum/direction of time in order to determine whether the starting values should be rendered or the ending values. If the "playhead" of its timeline goes past the zero-duration tween in the forward direction or lands directly on it, the end values should be rendered, but if the timeline's "playhead" moves past it in the backward direction (from a postitive time to a negative time), the starting values must be rendered.
23480					if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) {
23481						force = true;
23482					}
23483					this._rawPrevTime = rawPrevTime = !suppressEvents || time || prevRawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
23484				}
23485			}
23486			if (!this._initted || this._startAt && this._startAt.progress()) {
23487				//if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. Also, we check progress() because if startAt has already rendered at its end, we should force a render at its beginning. Otherwise, if you put the playhead directly on top of where a fromTo({immediateRender:false}) starts, and then move it backwards, the from() won't revert its values.
23488				force = true;
23489			}
23490		} else {
23491			this._totalTime = this._time = time;
23492
23493			if (this._easeType) {
23494				var r = time / duration,
23495				    type = this._easeType,
23496				    pow = this._easePower;
23497				if (type === 1 || type === 3 && r >= 0.5) {
23498					r = 1 - r;
23499				}
23500				if (type === 3) {
23501					r *= 2;
23502				}
23503				if (pow === 1) {
23504					r *= r;
23505				} else if (pow === 2) {
23506					r *= r * r;
23507				} else if (pow === 3) {
23508					r *= r * r * r;
23509				} else if (pow === 4) {
23510					r *= r * r * r * r;
23511				}
23512
23513				if (type === 1) {
23514					this.ratio = 1 - r;
23515				} else if (type === 2) {
23516					this.ratio = r;
23517				} else if (time / duration < 0.5) {
23518					this.ratio = r / 2;
23519				} else {
23520					this.ratio = 1 - r / 2;
23521				}
23522			} else {
23523				this.ratio = this._ease.getRatio(time / duration);
23524			}
23525		}
23526
23527		if (this._time === prevTime && !force) {
23528			return;
23529		} else if (!this._initted) {
23530			this._init();
23531			if (!this._initted || this._gc) {
23532				//immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that over
23532writing occurs properly. Also, if all of the tweening properties have been overwritten (which would cause _gc to be true, as set in _init()), we shouldn't continue otherwise an onStart callback could be called for example.
23533				return;
23534			} else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) {
23535				this._time = this._totalTime = prevTime;
23536				this._rawPrevTime = prevRawPrevTime;
23537				_lazyTweens.push(this);
23538				this._lazy = [time, suppressEvents];
23539				return;
23540			}
23541			//_ease is initially set to defaultEase, so now that init() has run, _ease is set properly and we need to recalculate the ratio. Overall this is faster than using conditional logic earlier in the method to avoid having to set ratio twice because we only init() once but renderTime() gets called VERY frequently.
23542			if (this._time && !isComplete) {
23543				this.ratio = this._ease.getRatio(this._time / duration);
23544			} else if (isComplete && this._ease._calcEnd) {
23545				this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1);
23546			}
23547		}
23548		if (this._lazy !== false) {
23549			//in case a lazy render is pending, we should flush it because the new render is occurring now (imagine a lazy tween instantiating and then immediately the user calls tween.seek(tween.duration()), skipping to the end - the end render would be forced, and then if we didn't flush the lazy render, it'd fire AFTER the seek(), rendering it at the wrong time.
23550			this._lazy = false;
23551		}
23552		if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
23553			this._active = true; //so that if the user renders a tween (as opposed to the timeline rendering it), the timeline is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the tween already finished but the user manually re-renders it as halfway done.
23554		}
23555		if (prevTime === 0) {
23556			if (this._startAt) {
23557				if (time >= 0) {
23558					this._startAt.render(time, true, force);
23559				} else if (!callback) {
23560					callback = "_dummyGS"; //if no callback is defined, use a dummy value just so that the condition at the end evaluates as true because _startAt should render AFTER the normal render loop when the time is negative. We could handle this in a more intuitive way, of course, but the render loop is the MOST important thing to optimize, so this technique allows us to avoid adding extra conditional logic in a high-frequency area.
23561				}
23562			}
23563			if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) {
23564				this._callback("onStart");
23565			}
23566		}
23567		pt = this._firstPT;
23568		while (pt) {
23569			if (pt.f) {
23570				pt.t[pt.p](pt.c * this.ratio + pt.s);
23571			} else {
23572				pt.t[pt.p] = pt.c * this.ratio + pt.s;
23573			}
23574			pt = pt._next;
23575		}
23576
23577		if (this._onUpdate) {
23578			if (time < 0) if (this._startAt && time !== -0.0001) {
23579				//if the tween is positioned at the VERY beginning (_startTime 0) of its parent timeline, it's illegal for the playhead to go back further, so we should not render the recorded startAt values.
23580				this._startAt.render(time, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete.
23581			}
23582			if (!suppressEvents) if (this._time !== prevTime || isComplete || force) {
23583				this._callback("onUpdate");
23584			}
23585		}
23586		if (callback) if (!this._gc || force) {
23587			//check _gc because there's a chance that kill() could be called in an onUpdate
23588			if (time < 0 && this._startAt && !this._onUpdate && time !== -0.0001) {
23589				//-0.0001 is a special value that we use when looping back to the beginning of a repeated TimelineMax, in which case we shouldn't render the _startAt values.
23590				this._startAt.render(time, true, force);
23591			}
23592			if (isComplete) {
23593				if (this._timeline.autoRemoveChildren) {
23594					this._enabled(false, false);
23595				}
23596				this._active = false;
23597			}
23598			if (!suppressEvents && this.vars[callback]) {
23599				this._callback(callback);
23600			}
23601			if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) {
23602				//the onComplete or onReverseComplete could trigger movement of the playhead and for zero-duration tweens (which must discern direction) that land directly back on their start time, we don't want to fire again on the next render. Think of several addPause()'s in a timeline that forces the playhead to a certain spot, but what if it's already paused and another tween is tweening the "time" of the timeline? Each time it moves [forward] past that spot, it would move back, and since suppressEvents is true, it'd reset _rawPrevTime to _tinyNum so that when it begins again, the callback would fire (so ultimately it could bounce back and forth during that tween). Again, this is a very uncommon sce
23602nario, but possible nonetheless.
23603				this._rawPrevTime = 0;
23604			}
23605		}
23606	};
23607
23608	p._kill = function (vars, target, overwritingTween) {
23609		if (vars === "all") {
23610			vars = null;
23611		}
23612		if (vars == null) if (target == null || target === this.target) {
23613			this._lazy = false;
23614			return this._enabled(false, false);
23615		}
23616		target = typeof target !== "string" ? target || this._targets || this.target : TweenLite.selector(target) || target;
23617		var simultaneousOverwrite = overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline,
23618		    i,
23619		    overwrittenProps,
23620		    p,
23621		    pt,
23622		    propLookup,
23623		    changed,
23624		    killProps,
23625		    record,
23626		    killed;
23627		if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") {
23628			i = target.length;
23629			while (--i > -1) {
23630				if (this._kill(vars, target[i], overwritingTween)) {
23631					changed = true;
23632				}
23633			}
23634		} else {
23635			if (this._targets) {
23636				i = this._targets.length;
23637				while (--i > -1) {
23638					if (target === this._targets[i]) {
23639						propLookup = this._propLookup[i] || {};
23640						this._overwrittenProps = this._overwrittenProps || [];
23641						overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all";
23642						break;
23643					}
23644				}
23645			} else if (target !== this.target) {
23646				return false;
23647			} else {
23648				propLookup = this._propLookup;
23649				overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all";
23650			}
23651
23652			if (propLookup) {
23653				killProps = vars || propLookup;
23654				record = vars !== overwrittenProps && overwrittenProps !== "all" && vars !== propLookup && (typeof vars !== "object" || !vars._tempKill); //_tempKill is a super-secret way to delete a particular tweening property but NOT have it remembered as an official overwritten property (like in BezierPlugin)
23655				if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) {
23656					for (p in killProps) {
23657						if (propLookup[p]) {
23658							if (!killed) {
23659								killed = [];
23660							}
23661							killed.push(p);
23662						}
23663					}
23664					if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) {
23665						//if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it).
23666						return false;
23667					}
23668				}
23669
23670				for (p in killProps) {
23671					if (pt = propLookup[p]) {
23672						if (simultaneousOverwrite) {
23673							//if another tween overwrites this one and they both start at exactly the same time, yet this tween has already rendered once (for example, at 0.001) because it's first in the queue, we should revert the values to where they were at 0 so that the starting values aren't contaminated on the overwriting tween.
23674							if (pt.f) {
23675								pt.t[pt.p](pt.s);
23676							} else {
23677								pt.t[pt.p] = pt.s;
23678							}
23679							changed = true;
23680						}
23681						if (pt.pg && pt.t._kill(killProps)) {
23682							changed = true; //some plugins need to be notified so they can perform cleanup tasks first
23683						}
23684						if (!pt.pg || pt.t._overwriteProps.length === 0) {
23685							if (pt._prev) {
23686								pt._prev._next = pt._next;
23687							} else if (pt === this._firstPT) {
23688								this._firstPT = pt._next;
23689							}
23690							if (pt._next) {
23691								pt._next._prev = pt._prev;
23692							}
23693							pt._next = pt._prev = null;
23694						}
23695						delete propLookup[p];
23696					}
23697					if (record) {
23698						overwrittenProps[p] = 1;
23699					}
23700				}
23701				if (!this._firstPT && this._initted) {
23702					//if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening.
23703					this._enabled(false, false);
23704				}
23705			}
23706		}
23707		return changed;
23708	};
23709
23710	p.invalidate = function () {
23711		if (this._notifyPluginsOfEnabled) {
23712			TweenLite._onPluginEvent("_onDisable", this);
23713		}
23714		this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null;
23715		this._notifyPluginsOfEnabled = this._active = this._lazy = false;
23716		this._propLookup = this._targets ? {} : [];
23717		Animation.prototype.invalidate.call(this);
23718		if (this.vars.immediateRender) {
23719			this._time = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render)
23720			this.render(Math.min(0, -this._delay)); //in case delay is negative.
23721		}
23722		return this;
23723	};
23724
23725	p._enabled = function (enabled, ignoreTimeline) {
23726		if (!_tickerActive) {
23727			_ticker.wake();
23728		}
23729		if (enabled && this._gc) {
23730			var targets = this._targets,
23731			    i;
23732			if (targets) {
23733				i = targets.length;
23734				while (--i > -1) {
23735					this._siblings[i] = _register(targets[i], this, true);
23736				}
23737			} else {
23738				this._siblings = _register(this.target, this, true);
23739			}
23740		}
23741		Animation.prototype._enabled.call(this, enabled, ignoreTimeline);
23742		if (this._notifyPluginsOfEnabled) if (this._firstPT) {
23743			return TweenLite._onPluginEvent(enabled ? "_onEnable" : "_onDisable", this);
23744		}
23745		return false;
23746	};
23747
23748	//----TweenLite static methods -----------------------------------------------------
23749
23750	TweenLite.to = function (target, duration, vars) {
23751		return new TweenLite(target, duration, vars);
23752	};
23753
23754	TweenLite.from = function (target, duration, vars) {
23755		vars.runBackwards = true;
23756		vars.immediateRender = vars.immediateRender != false;
23757		return new TweenLite(target, duration, vars);
23758	};
23759
23760	TweenLite.fromTo = function (target, duration, fromVars, toVars) {
23761		toVars.startAt = fromVars;
23762		toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
23763		return new TweenLite(target, duration, toVars);
23764	};
23765
23766	TweenLite.delayedCall = function (delay, callback, params, scope, useFrames) {
23767		return new TweenLite(callback, 0, { delay: delay, onComplete: callback, onCompleteParams: params, callbackScope: scope, onReverseComplete: callback, onReverseCompleteParams: params, immediateRender: false, lazy: false, useFrames: useFrames, overwrite: 0 });
23768	};
23769
23770	TweenLite.set = function (target, vars) {
23771		return new TweenLite(target, 0, vars);
23772	};
23773
23774	TweenLite.getTweensOf = function (target, onlyActive) {
23775		if (target == null) {
23776			return [];
23777		}
23778		target = typeof target !== "string" ? target : TweenLite.selector(target) || target;
23779		var i, a, j, t;
23780		if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") {
23781			i = target.length;
23782			a = [];
23783			while (--i > -1) {
23784				a = a.concat(TweenLite.getTweensOf(target[i], onlyActive));
23785			}
23786			i = a.length;
23787			//now get rid of any duplicates (tweens of arrays of objects could cause duplicates)
23788			while (--i > -1) {
23789				t = a[i];
23790				j = i;
23791				while (--j > -1) {
23792					if (t === a[j]) {
23793						a.splice(i, 1);
23794					}
23795				}
23796			}
23797		} else if (target._gsTweenID) {
23798			a = _register(target).concat();
23799			i = a.length;
23800			while (--i > -1) {
23801				if (a[i]._gc || onlyActive && !a[i].isActive()) {
23802					a.splice(i, 1);
23803				}
23804			}
23805		}
23806		return a || [];
23807	};
23808
23809	TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function (target, onlyActive, vars) {
23810		if (typeof onlyActive === "object") {
23811			vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted)
23812			onlyActive = false;
23813		}
23814		var a = TweenLite.getTweensOf(target, onlyActive),
23815		    i = a.length;
23816		while (--i > -1) {
23817			a[i]._kill(vars, target);
23818		}
23819	};
23820
23821	/*
23822  * ----------------------------------------------------------------
23823  * TweenPlugin   (could easily be split out as a separate file/class, but included for ease of use (so that people don't need to include another script call before loading plugins which is easy to forget)
23824  * ----------------------------------------------------------------
23825  */
23826	var TweenPlugin = _class("plugins.TweenPlugin", function (props, priority) {
23827		this._overwriteProps = (props || "").split(",");
23828		this._propName = this._overwriteProps[0];
23829		this._priority = priority || 0;
23830		this._super = TweenPlugin.prototype;
23831	}, true);
23832
23833	p = TweenPlugin.prototype;
23834	TweenPlugin.version = "1.19.0";
23835	TweenPlugin.API = 2;
23836	p._firstPT = null;
23837	p._addTween = _addPropTween;
23838	p.setRatio = _setRatio;
23839
23840	p._kill = function (lookup) {
23841		var a = this._overwriteProps,
23842		    pt = this._firstPT,
23843		    i;
23844		if (lookup[this._propName] != null) {
23845			this._overwriteProps = [];
23846		} else {
23847			i = a.length;
23848			while (--i > -1) {
23849				if (lookup[a[i]] != null) {
23850					a.splice(i, 1);
23851				}
23852			}
23853		}
23854		while (pt) {
23855			if (lookup[pt.n] != null) {
23856				if (pt._next) {
23857					pt._next._prev = pt._prev;
23858				}
23859				if (pt._prev) {
23860					pt._prev._next = pt._next;
23861					pt._prev = null;
23862				} else if (this._firstPT === pt) {
23863					this._firstPT = pt._next;
23864				}
23865			}
23866			pt = pt._next;
23867		}
23868		return false;
23869	};
23870
23871	p._mod = p._roundProps = function (lookup) {
23872		var pt = this._firstPT,
23873		    val;
23874		while (pt) {
23875			val = lookup[this._propName] || pt.n != null && lookup[pt.n.split(this._propName + "_").join("")];
23876			if (val && typeof val === "function") {
23877				//some properties that are very plugin-specific add a prefix named after the _propName plus an underscore, so we need to ignore that extra stuff here.
23878				if (pt.f === 2) {
23879					pt.t._applyPT.m = val;
23880				} else {
23881					pt.m = val;
23882				}
23883			}
23884			pt = pt._next;
23885		}
23886	};
23887
23888	TweenLite._onPluginEvent = function (type, tween) {
23889		var pt = tween._firstPT,
23890		    changed,
23891		    pt2,
23892		    first,
23893		    last,
23894		    next;
23895		if (type === "_onInitAllProps") {
23896			//sorts the PropTween linked list in order of priority because some plugins need to render earlier/later than others, like MotionBlurPlugin applies its effects after all x/y/alpha tweens have rendered on each frame.
23897			while (pt) {
23898				next = pt._next;
23899				pt2 = first;
23900				while (pt2 && pt2.pr > pt.pr) {
23901					pt2 = pt2._next;
23902				}
23903				if (pt._prev = pt2 ? pt2._prev : last) {
23904					pt._prev._next = pt;
23905				} else {
23906					first = pt;
23907				}
23908				if (pt._next = pt2) {
23909					pt2._prev = pt;
23910				} else {
23911					last = pt;
23912				}
23913				pt = next;
23914			}
23915			pt = tween._firstPT = first;
23916		}
23917		while (pt) {
23918			if (pt.pg) if (typeof pt.t[type] === "function") if (pt.t[type]()) {
23919				changed = true;
23920			}
23921			pt = pt._next;
23922		}
23923		return changed;
23924	};
23925
23926	TweenPlugin.activate = function (plugins) {
23927		var i = plugins.length;
23928		while (--i > -1) {
23929			if (plugins[i].API === TweenPlugin.API) {
23930				_plugins[new plugins[i]()._propName] = plugins[i];
23931			}
23932		}
23933		return true;
23934	};
23935
23936	//provides a more concise way to define plugins that have no dependencies besides TweenPlugin and TweenLite, wrapping common boilerplate stuff into one function (added in 1.9.0). You don't NEED to use this to define a plugin - the old way still works and can be useful in certain (rare) situations.
23937	_gsDefine.plugin = function (config) {
23938		if (!config || !config.propName || !config.init || !config.API) {
23939			throw "illegal plugin definition.";
23940		}
23941		var propName = config.propName,
23942		    priority = config.priority || 0,
23943		    overwriteProps = config.overwriteProps,
23944		    map = { init: "_onInitTween", set: "setRatio", kill: "_kill", round: "_mod", mod: "_mod", initAll: "_onInitAllProps" },
23945		    Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin", function () {
23946			TweenPlugin.call(this, propName, priority);
23947			this._overwriteProps = overwriteProps || [];
23948		}, config.global === true),
23949		    p = Plugin.prototype = new TweenPlugin(propName),
23950		    prop;
23951		p.constructor = Plugin;
23952		Plugin.API = config.API;
23953		for (prop in map) {
23954			if (typeof config[prop] === "function") {
23955				p[map[prop]] = config[prop];
23956			}
23957		}
23958		Plugin.version = config.version;
23959		TweenPlugin.activate([Plugin]);
23960		return Plugin;
23961	};
23962
23963	//now run through all the dependencies discovered and if any are missing, log that to the console as a warning. This is why it's best to have TweenLite load last - it can check all the dependencies for you.
23964	a = window._gsQueue;
23965	if (a) {
23966		for (i = 0; i < a.length; i++) {
23967			a[i]();
23968		}
23969		for (p in _defLookup) {
23970			if (!_defLookup[p].func) {
23971				window.console.log("GSAP encountered missing dependency: " + p);
23972			}
23973		}
23974	}
23975
23976	_tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated
23977})(typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window, "TweenMax");
23978/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5)))
23979
23980/***/ }),
23981/* 8 */
23982/***/ (function(module, exports, __webpack_require__) {
23983
23984/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
23985 * VERSION: 1.20.3
23986 * DATE: 2017-10-02
23987 * UPDATES AND DOCS AT: http://greensock.com
23988 *
23989 * @license Copyright (c) 2008-2017, GreenSock. All rights reserved.
23990 * This work is subject to the terms at http://greensock.com/standard-license or for
23991 * Club GreenSock members, the software agreement that was issued with your membership.
23992 * 
23993 * @author: Jack Doyle, [email protected]
23994 */
23995var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node
23996(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () {
23997
23998	"use strict";
23999
24000	_gsScope._gsDefine("TimelineMax", ["TimelineLite", "TweenLite", "easing.Ease"], function (TimelineLite, TweenLite, Ease) {
24001
24002		var TimelineMax = function (vars) {
24003			TimelineLite.call(this, vars);
24004			this._repeat = this.vars.repeat || 0;
24005			this._repeatDelay = this.vars.repeatDelay || 0;
24006			this._cycle = 0;
24007			this._yoyo = this.vars.yoyo === true;
24008			this._dirty = true;
24009		},
24010		    _tinyNum = 0.0000000001,
24011		    TweenLiteInternals = TweenLite._internals,
24012		    _lazyTweens = TweenLiteInternals.lazyTweens,
24013		    _lazyRender = TweenLiteInternals.lazyRender,
24014		    _globals = _gsScope._gsDefine.globals,
24015		    _easeNone = new Ease(null, null, 1, 0),
24016		    p = TimelineMax.prototype = new TimelineLite();
24017
24018		p.constructor = TimelineMax;
24019		p.kill()._gc = false;
24020		TimelineMax.version = "1.20.3";
24021
24022		p.invalidate = function () {
24023			this._yoyo = this.vars.yoyo === true;
24024			this._repeat = this.vars.repeat || 0;
24025			this._repeatDelay = this.vars.repeatDelay || 0;
24026			this._uncache(true);
24027			return TimelineLite.prototype.invalidate.call(this);
24028		};
24029
24030		p.addCallback = function (callback, position, params, scope) {
24031			return this.add(TweenLite.delayedCall(0, callback, params, scope), position);
24032		};
24033
24034		p.removeCallback = function (callback, position) {
24035			if (callback) {
24036				if (position == null) {
24037					this._kill(null, callback);
24038				} else {
24039					var a = this.getTweensOf(callback, false),
24040					    i = a.length,
24041					    time = this._parseTimeOrLabel(position);
24042					while (--i > -1) {
24043						if (a[i]._startTime === time) {
24044							a[i]._enabled(false, false);
24045						}
24046					}
24047				}
24048			}
24049			return this;
24050		};
24051
24052		p.removePause = function (position) {
24053			return this.removeCallback(TimelineLite._internals.pauseCallback, position);
24054		};
24055
24056		p.tweenTo = function (position, vars) {
24057			vars = vars || {};
24058			var copy = { ease: _easeNone, useFrames: this.usesFrames(), immediateRender: false },
24059			    Engine = vars.repeat && _globals.TweenMax || TweenLite,
24060			    duration,
24061			    p,
24062			    t;
24063			for (p in vars) {
24064				copy[p] = vars[p];
24065			}
24066			copy.time = this._parseTimeOrLabel(position);
24067			duration = Math.abs(Number(copy.time) - this._time) / this._timeScale || 0.001;
24068			t = new Engine(this, duration, copy);
24069			copy.onStart = function () {
24070				t.target.paused(true);
24071				if (t.vars.time !== t.target.time() && duration === t.duration()) {
24072					//don't make the duration zero - if it's supposed to be zero, don't worry because it's already initting the tween and will complete immediately, effectively making the duration zero anyway. If we make duration zero, the tween won't run at all.
24073					t.duration(Math.abs(t.vars.time - t.target.time()) / t.target._timeScale);
24074				}
24075				if (vars.onStart) {
24076					//in case the user had an onStart in the vars - we don't want to overwrite it.
24077					vars.onStart.apply(vars.onStartScope || vars.callbackScope || t, vars.onStartParams || []); //don't use t._callback("onStart") or it'll point to the copy.onStart and we'll get a recursion error.
24078				}
24079			};
24080			return t;
24081		};
24082
24083		p.tweenFromTo = function (fromPosition, toPosition, vars) {
24084			vars = vars || {};
24085			fromPosition = this._parseTimeOrLabel(fromPosition);
24086			vars.startAt = { onComplete: this.seek, onCompleteParams: [fromPosition], callbackScope: this };
24087			vars.immediateRender = vars.immediateRender !== false;
24088			var t = this.tweenTo(toPosition, vars);
24089			return t.duration(Math.abs(t.vars.time - fromPosition) / this._timeScale || 0.001);
24090		};
24091
24092		p.render = function (time, suppressEvents, force) {
24093			if (this._gc) {
24094				this._enabled(true, false);
24095			}
24096			var prevTime = this._time,
24097			    totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
24098			    dur = this._duration,
24099			    prevTotalTime = this._totalTime,
24100			    prevStart = this._startTime,
24101			    prevTimeScale = this._timeScale,
24102			    prevRawPrevTime = this._rawPrevTime,
24103			    prevPaused = this._paused,
24104			    prevCycle = this._cycle,
24105			    tween,
24106			    isComplete,
24107			    next,
24108			    callback,
24109			    internalForce,
24110			    cycleDuration,
24111			    pauseTween,
24112			    curTime;
24113			if (prevTime !== this._time) {
24114				//if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump).
24115				time += this._time - prevTime;
24116			}
24117			if (time >= totalDur - 0.0000001 && time >= 0) {
24118				//to work around occasional floating point math artifacts.
24119				if (!this._locked) {
24120					this._totalTime = totalDur;
24121					this._cycle = this._repeat;
24122				}
24123				if (!this._reversed) if (!this._hasPausedChild()) {
24124					isComplete = true;
24125					callback = "onComplete";
24126					internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
24127					if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && this._first) {
24128						internalForce = true;
24129						if (prevRawPrevTime > _tinyNum) {
24130							callback = "onReverseComplete";
24131						}
24132					}
24133				}
24134				this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
24135				if (this._yoyo && (this._cycle & 1) !== 0) {
24136					this._time = time = 0;
24137				} else {
24138					this._time = dur;
24139					time = dur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7. We cannot do less then 0.0001 because the same issue can occur when the duration is extremely large like 999999999999 in 
24139which case adding 0.00000001, for example, causes it to act like nothing was added.
24140				}
24141			} else if (time < 0.0000001) {
24142				//to work around occasional floating point math artifacts, round super small values to 0.
24143				if (!this._locked) {
24144					this._totalTime = this._cycle = 0;
24145				}
24146				this._time = 0;
24147				if (prevTime !== 0 || dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || time < 0 && prevRawPrevTime >= 0) && !this._locked) {
24148					//edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare)
24149					callback = "onReverseComplete";
24150					isComplete = this._reversed;
24151				}
24152				if (time < 0) {
24153					this._active = false;
24154					if (this._timeline.autoRemoveChildren && this._reversed) {
24155						internalForce = isComplete = true;
24156						callback = "onReverseComplete";
24157					} else if (prevRawPrevTime >= 0 && this._first) {
24158						//when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
24159						internalForce = true;
24160					}
24161					this._rawPrevTime = time;
24162				} else {
24163					this._rawPrevTime = dur || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
24164					if (time === 0 && isComplete) {
24165						//if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
24166						tween = this._first;
24167						while (tween && tween._startTime === 0) {
24168							if (!tween._duration) {
24169								isComplete = false;
24170							}
24171							tween = tween._next;
24172						}
24173					}
24174					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
24175					if (!this._initted) {
24176						internalForce = true;
24177					}
24178				}
24179			} else {
24180				if (dur === 0 && prevRawPrevTime < 0) {
24181					//without this, zero-duration repeating timelines (like with a simple callback nested at the very beginning and a repeatDelay) wouldn't render the first time through.
24182					internalForce = true;
24183				}
24184				this._time = this._rawPrevTime = time;
24185				if (!this._locked) {
24186					this._totalTime = time;
24187					if (this._repeat !== 0) {
24188						cycleDuration = dur + this._repeatDelay;
24189						this._cycle = this._totalTime / cycleDuration >> 0; //originally _totalTime % cycleDuration but floating point errors caused problems, so I normalized it. (4 % 0.8 should be 0 but it gets reported as 0.79999999!)
24190						if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
24191							this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
24192						}
24193						this._time = this._totalTime - this._cycle * cycleDuration;
24194						if (this._yoyo) if ((this._cycle & 1) !== 0) {
24195							this._time = dur - this._time;
24196						}
24197						if (this._time > dur) {
24198							this._time = dur;
24199							time = dur + 0.0001; //to avoid occasional floating point rounding error
24200						} else if (this._time < 0) {
24201							this._time = time = 0;
24202						} else {
24203							time = this._time;
24204						}
24205					}
24206				}
24207
24208				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
24209					time = this._time;
24210					if (time >= prevTime || this._repeat && prevCycle !== this._cycle) {
24211						tween = this._first;
24212						while (tween && tween._startTime <= time && !pauseTween) {
24213							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
24214								pauseTween = tween;
24215							}
24216							tween = tween._next;
24217						}
24218					} else {
24219						tween = this._last;
24220						while (tween && tween._startTime >= time && !pauseTween) {
24221							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
24222								pauseTween = tween;
24223							}
24224							tween = tween._prev;
24225						}
24226					}
24227					if (pauseTween && pauseTween._startTime < dur) {
24228						this._time = time = pauseTween._startTime;
24229						this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay);
24230					}
24231				}
24232			}
24233
24234			if (this._cycle !== prevCycle) if (!this._locked) {
24235				/*
24236    make sure children at the end/beginning of the timeline are rendered properly. If, for example, 
24237    a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
24238    would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there
24239    could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So 
24240    we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must
24241    ensure that zero-duration tweens at the very beginning or end of the TimelineMax work. 
24242    */
24243				var backwards = this._yoyo && (prevCycle & 1) !== 0,
24244				    wrap = backwards === (this._yoyo && (this._cycle & 1) !== 0),
24245				    recTotalTime = this._totalTime,
24246				    recCycle = this._cycle,
24247				    recRawPrevTime = this._rawPrevTime,
24248				    recTime = this._time;
24249
24250				this._totalTime = prevCycle * dur;
24251				if (this._cycle < prevCycle) {
24252					backwards = !backwards;
24253				} else {
24254					this._totalTime += dur;
24255				}
24256				this._time = prevTime; //temporarily revert _time so that render() renders the children in the correct order. Without this, tweens won't rewind correctly. We could arhictect things in a "cleaner" way by splitting out the rendering queue into a separate method but for performance reasons, we kept it all inside this method.
24257
24258				this._rawPrevTime = dur === 0 ? prevRawPrevTime - 0.0001 : prevRawPrevTime;
24259				this._cycle = prevCycle;
24260				this._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render()
24261				prevTime = backwards ? 0 : dur;
24262				this.render(prevTime, suppressEvents, dur === 0);
24263				if (!suppressEvents) if (!this._gc) {
24264					if (this.vars.onRepeat) {
24265						this._cycle = recCycle; //in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle.
24266						this._locked = false;
24267						this._callback("onRepeat");
24268					}
24269				}
24270				if (prevTime !== this._time) {
24271					//in case there's a callback like onComplete in a nested tween/timeline that changes the playhead position, like via seek(), we should just abort.
24272					return;
24273				}
24274				if (wrap) {
24275					this._cycle = prevCycle; //if there's an onRepeat, we reverted this above, so make sure it's set properly again. We also unlocked in that scenario, so reset that too.
24276					this._locked = true;
24277					prevTime = backwards ? dur + 0.0001 : -0.0001;
24278					this.render(prevTime, true, false);
24279				}
24280				this._locked = false;
24281				if (this._paused && !prevPaused) {
24282					//if the render() triggered callback that paused this timeline, we should abort (very rare, but possible)
24283					return;
24284				}
24285				this._time = recTime;
24286				this._totalTime = recTotalTime;
24287				this._cycle = recCycle;
24288				this._rawPrevTime = recRawPrevTime;
24289			}
24290
24291			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
24292				if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) {
24293					//so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
24294					this._callback("onUpdate");
24295				}
24296				return;
24297			} else if (!this._initted) {
24298				this._initted = true;
24299			}
24300
24301			if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) {
24302				this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
24303			}
24304
24305			if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0 || !this._totalDuration) if (!suppressEvents) {
24306				this._callback("onStart");
24307			}
24308
24309			curTime = this._time;
24310			if (curTime >= prevTime) {
24311				tween = this._first;
24312				while (tween) {
24313					next = tween._next; //record it here because the value could change after rendering...
24314					if (curTime !== this._time || this._paused && !prevPaused) {
24315						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
24316						break;
24317					} else if (tween._active || tween._startTime <= this._time && !tween._paused && !tween._gc) {
24318						if (pauseTween === tween) {
24319							this.pause();
24320						}
24321						if (!tween._reversed) {
24322							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
24323						} else {
24324							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
24325						}
24326					}
24327					tween = next;
24328				}
24329			} else {
24330				tween = this._last;
24331				while (tween) {
24332					next = tween._prev; //record it here because the value could change after rendering...
24333					if (curTime !== this._time || this._paused && !prevPaused) {
24334						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
24335						break;
24336					} else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) {
24337						if (pauseTween === tween) {
24338							pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
24339							while (pauseTween && pauseTween.endTime() > this._time) {
24340								pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force);
24341								pauseTween = pauseTween._prev;
24342							}
24343							pauseTween = null;
24344							this.pause();
24345						}
24346						if (!tween._reversed) {
24347							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
24348						} else {
24349							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
24350						}
24351					}
24352					tween = next;
24353				}
24354			}
24355
24356			if (this._onUpdate) if (!suppressEvents) {
24357				if (_lazyTweens.length) {
24358					//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
24359					_lazyRender();
24360				}
24361				this._callback("onUpdate");
24362			}
24363			if (callback) if (!this._locked) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) {
24364				//if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
24365				if (isComplete) {
24366					if (_lazyTweens.length) {
24367						//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
24368						_lazyRender();
24369					}
24370					if (this._timeline.autoRemoveChildren) {
24371						this._enabled(false, false);
24372					}
24373					this._active = false;
24374				}
24375				if (!suppressEvents && this.vars[callback]) {
24376					this._callback(callback);
24377				}
24378			}
24379		};
24380
24381		p.getActive = function (nested, tweens, timelines) {
24382			if (nested == null) {
24383				nested = true;
24384			}
24385			if (tweens == null) {
24386				tweens = true;
24387			}
24388			if (timelines == null) {
24389				timelines = false;
24390			}
24391			var a = [],
24392			    all = this.getChildren(nested, tweens, timelines),
24393			    cnt = 0,
24394			    l = all.length,
24395			    i,
24396			    tween;
24397			for (i = 0; i < l; i++) {
24398				tween = all[i];
24399				if (tween.isActive()) {
24400					a[cnt++] = tween;
24401				}
24402			}
24403			return a;
24404		};
24405
24406		p.getLabelAfter = function (time) {
24407			if (!time) if (time !== 0) {
24408				//faster than isNan()
24409				time = this._time;
24410			}
24411			var labels = this.getLabelsArray(),
24412			    l = labels.length,
24413			    i;
24414			for (i = 0; i < l; i++) {
24415				if (labels[i].time > time) {
24416					return labels[i].name;
24417				}
24418			}
24419			return null;
24420		};
24421
24422		p.getLabelBefore = function (time) {
24423			if (time == null) {
24424				time = this._time;
24425			}
24426			var labels = this.getLabelsArray(),
24427			    i = labels.length;
24428			while (--i > -1) {
24429				if (labels[i].time < time) {
24430					return labels[i].name;
24431				}
24432			}
24433			return null;
24434		};
24435
24436		p.getLabelsArray = function () {
24437			var a = [],
24438			    cnt = 0,
24439			    p;
24440			for (p in this._labels) {
24441				a[cnt++] = { time: this._labels[p], name: p };
24442			}
24443			a.sort(function (a, b) {
24444				return a.time - b.time;
24445			});
24446			return a;
24447		};
24448
24449		p.invalidate = function () {
24450			this._locked = false; //unlock and set cycle in case invalidate() is called from inside an onRepeat
24451			return TimelineLite.prototype.invalidate.call(this);
24452		};
24453
24454		//---- GETTERS / SETTERS -------------------------------------------------------------------------------------------------------
24455
24456		p.progress = function (value, suppressEvents) {
24457			return !arguments.length ? this._time / this.duration() || 0 : this.totalTime(this.duration() * (this._yoyo && (this._cycle & 1) !== 0 ? 1 - value : value) + this._cycle * (this._duration + this._repeatDelay), suppressEvents);
24458		};
24459
24460		p.totalProgress = function (value, suppressEvents) {
24461			return !arguments.length ? this._totalTime / this.totalDuration() || 0 : this.totalTime(this.totalDuration() * value, suppressEvents);
24462		};
24463
24464		p.totalDuration = function (value) {
24465			if (!arguments.length) {
24466				if (this._dirty) {
24467					TimelineLite.prototype.totalDuration.call(this); //just forces refresh
24468					//Instead of Infinity, we use 999999999999 so that we can accommodate reverses.
24469					this._totalDuration = this._repeat === -1 ? 999999999999 : this._duration * (this._repeat + 1) + this._repeatDelay * this._repeat;
24470				}
24471				return this._totalDuration;
24472			}
24473			return this._repeat === -1 || !value ? this : this.timeScale(this.totalDuration() / value);
24474		};
24475
24476		p.time = function (value, suppressEvents) {
24477			if (!arguments.length) {
24478				return this._time;
24479			}
24480			if (this._dirty) {
24481				this.totalDuration();
24482			}
24483			if (value > this._duration) {
24484				value = this._duration;
24485			}
24486			if (this._yoyo && (this._cycle & 1) !== 0) {
24487				value = this._duration - value + this._cycle * (this._duration + this._repeatDelay);
24488			} else if (this._repeat !== 0) {
24489				value += this._cycle * (this._duration + this._repeatDelay);
24490			}
24491			return this.totalTime(value, suppressEvents);
24492		};
24493
24494		p.repeat = function (value) {
24495			if (!arguments.length) {
24496				return this._repeat;
24497			}
24498			this._repeat = value;
24499			return this._uncache(true);
24500		};
24501
24502		p.repeatDelay = function (value) {
24503			if (!arguments.length) {
24504				return this._repeatDelay;
24505			}
24506			this._repeatDelay = value;
24507			return this._uncache(true);
24508		};
24509
24510		p.yoyo = function (value) {
24511			if (!arguments.length) {
24512				return this._yoyo;
24513			}
24514			this._yoyo = value;
24515			return this;
24516		};
24517
24518		p.currentLabel = function (value) {
24519			if (!arguments.length) {
24520				return this.getLabelBefore(this._time + 0.00000001);
24521			}
24522			return this.seek(value, true);
24523		};
24524
24525		return TimelineMax;
24526	}, true);
24527
24528	/*
24529  * ----------------------------------------------------------------
24530  * TimelineLite
24531  * ----------------------------------------------------------------
24532  */
24533
24534	_gsScope._gsDefine("TimelineLite", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) {
24535
24536		var TimelineLite = function (vars) {
24537			SimpleTimeline.call(this, vars);
24538			this._labels = {};
24539			this.autoRemoveChildren = this.vars.autoRemoveChildren === true;
24540			this.smoothChildTiming = this.vars.smoothChildTiming === true;
24541			this._sortChildren = true;
24542			this._onUpdate = this.vars.onUpdate;
24543			var v = this.vars,
24544			    val,
24545			    p;
24546			for (p in v) {
24547				val = v[p];
24548				if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) {
24549					v[p] = this._swapSelfInParams(val);
24550				}
24551			}
24552			if (_isArray(v.tweens)) {
24553				this.add(v.tweens, 0, v.align, v.stagger);
24554			}
24555		},
24556		    _tinyNum = 0.0000000001,
24557		    TweenLiteInternals = TweenLite._internals,
24558		    _internals = TimelineLite._internals = {},
24559		    _isSelector = TweenLiteInternals.isSelector,
24560		    _isArray = TweenLiteInternals.isArray,
24561		    _lazyTweens = TweenLiteInternals.lazyTweens,
24562		    _lazyRender = TweenLiteInternals.lazyRender,
24563		    _globals = _gsScope._gsDefine.globals,
24564		    _copy = function (vars) {
24565			var copy = {},
24566			    p;
24567			for (p in vars) {
24568				copy[p] = vars[p];
24569			}
24570			return copy;
24571		},
24572		    _applyCycle = function (vars, targets, i) {
24573			var alt = vars.cycle,
24574			    p,
24575			    val;
24576			for (p in alt) {
24577				val = alt[p];
24578				vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length];
24579			}
24580			delete vars.cycle;
24581		},
24582		    _pauseCallback = _internals.pauseCallback = function () {},
24583		    _slice = function (a) {
24584			//don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
24585			var b = [],
24586			    l = a.length,
24587			    i;
24588			for (i = 0; i !== l; b.push(a[i++]));
24589			return b;
24590		},
24591		    p = TimelineLite.prototype = new SimpleTimeline();
24592
24593		TimelineLite.version = "1.20.3";
24594		p.constructor = TimelineLite;
24595		p.kill()._gc = p._forcingPlayhead = p._hasPause = false;
24596
24597		/* might use later...
24598  //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales.
24599  function localToGlobal(time, animation) {
24600  	while (animation) {
24601  		time = (time / animation._timeScale) + animation._startTime;
24602  		animation = animation.timeline;
24603  	}
24604  	return time;
24605  }
24606  	//translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales
24607  function globalToLocal(time, animation) {
24608  	var scale = 1;
24609  	time -= localToGlobal(0, animation);
24610  	while (animation) {
24611  		scale *= animation._timeScale;
24612  		animation = animation.timeline;
24613  	}
24614  	return time * scale;
24615  }
24616  */
24617
24618		p.to = function (target, duration, vars, position) {
24619			var Engine = vars.repeat && _globals.TweenMax || TweenLite;
24620			return duration ? this.add(new Engine(target, duration, vars), position) : this.set(target, vars, position);
24621		};
24622
24623		p.from = function (target, duration, vars, position) {
24624			return this.add((vars.repeat && _globals.TweenMax || TweenLite).from(target, duration, vars), position);
24625		};
24626
24627		p.fromTo = function (target, duration, fromVars, toVars, position) {
24628			var Engine = toVars.repeat && _globals.TweenMax || TweenLite;
24629			return duration ? this.add(Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position);
24630		};
24631
24632		p.staggerTo = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
24633			var tl = new TimelineLite({ onComplete: onCompleteAll, onCompleteParams: onCompleteAllParams, callbackScope: onCompleteAllScope, smoothChildTiming: this.smoothChildTiming }),
24634			    cycle = vars.cycle,
24635			    copy,
24636			    i;
24637			if (typeof targets === "string") {
24638				targets = TweenLite.selector(targets) || targets;
24639			}
24640			targets = targets || [];
24641			if (_isSelector(targets)) {
24642				//senses if the targets object is a selector. If it is, we should translate it into an array.
24643				targets = _slice(targets);
24644			}
24645			stagger = stagger || 0;
24646			if (stagger < 0) {
24647				targets = _slice(targets);
24648				targets.reverse();
24649				stagger *= -1;
24650			}
24651			for (i = 0; i < targets.length; i++) {
24652				copy = _copy(vars);
24653				if (copy.startAt) {
24654					copy.startAt = _copy(copy.startAt);
24655					if (copy.startAt.cycle) {
24656						_applyCycle(copy.startAt, targets, i);
24657					}
24658				}
24659				if (cycle) {
24660					_applyCycle(copy, targets, i);
24661					if (copy.duration != null) {
24662						duration = copy.duration;
24663						delete copy.duration;
24664					}
24665				}
24666				tl.to(targets[i], duration, copy, i * stagger);
24667			}
24668			return this.add(tl, position);
24669		};
24670
24671		p.staggerFrom = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
24672			vars.immediateRender = vars.immediateRender != false;
24673			vars.runBackwards = true;
24674			return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
24675		};
24676
24677		p.staggerFromTo = function (targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
24678			toVars.startAt = fromVars;
24679			toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
24680			return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
24681		};
24682
24683		p.call = function (callback, params, scope, position) {
24684			return this.add(TweenLite.delayedCall(0, callback, params, scope), position);
24685		};
24686
24687		p.set = function (target, vars, position) {
24688			position = this._parseTimeOrLabel(position, 0, true);
24689			if (vars.immediateRender == null) {
24690				vars.immediateRender = position === this._time && !this._paused;
24691			}
24692			return this.add(new TweenLite(target, 0, vars), position);
24693		};
24694
24695		TimelineLite.exportRoot = function (vars, ignoreDelayedCalls) {
24696			vars = vars || {};
24697			if (vars.smoothChildTiming == null) {
24698				vars.smoothChildTiming = true;
24699			}
24700			var tl = new TimelineLite(vars),
24701			    root = tl._timeline,
24702			    hasNegativeStart,
24703			    time,
24704			    tween,
24705			    next;
24706			if (ignoreDelayedCalls == null) {
24707				ignoreDelayedCalls = true;
24708			}
24709			root._remove(tl, true);
24710			tl._startTime = 0;
24711			tl._rawPrevTime = tl._time = tl._totalTime = root._time;
24712			tween = root._first;
24713			while (tween) {
24714				next = tween._next;
24715				if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) {
24716					time = tween._startTime - tween._delay;
24717					if (time < 0) {
24718						hasNegativeStart = 1;
24719					}
24720					tl.add(tween, time);
24721				}
24722				tween = next;
24723			}
24724			root.add(tl, 0);
24725			if (hasNegativeStart) {
24726				//calling totalDuration() will force the adjustment necessary to shift the children forward so none of them start before zero, and moves the timeline backwards the same amount, so the playhead is still aligned where it should be globally, but the timeline doesn't have illegal children that start before zero.
24727				tl.totalDuration();
24728			}
24729			return tl;
24730		};
24731
24732		p.add = function (value, position, align, stagger) {
24733			var curTime, l, i, child, tl, beforeRawTime;
24734			if (typeof position !== "number") {
24735				position = this._parseTimeOrLabel(position, 0, true, value);
24736			}
24737			if (!(value instanceof Animation)) {
24738				if (value instanceof Array || value && value.push && _isArray(value)) {
24739					align = align || "normal";
24740					stagger = stagger || 0;
24741					curTime = position;
24742					l = value.length;
24743					for (i = 0; i < l; i++) {
24744						if (_isArray(child = value[i])) {
24745							child = new TimelineLite({ tweens: child });
24746						}
24747						this.add(child, curTime);
24748						if (typeof child !== "string" && typeof child !== "function") {
24749							if (align === "sequence") {
24750								curTime = child._startTime + child.totalDuration() / child._timeScale;
24751							} else if (align === "start") {
24752								child._startTime -= child.delay();
24753							}
24754						}
24755						curTime += stagger;
24756					}
24757					return this._uncache(true);
24758				} else if (typeof value === "string") {
24759					return this.addLabel(value, position);
24760				} else if (typeof value === "function") {
24761					value = TweenLite.delayedCall(0, value);
24762				} else {
24763					throw "Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string.";
24764				}
24765			}
24766
24767			SimpleTimeline.prototype.add.call(this, value, position);
24768
24769			if (value._time) {
24770				//in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning.
24771				value.render((this.rawTime() - value._startTime) * value._timeScale, false, false);
24772			}
24773
24774			//if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate.
24775			if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) {
24776				//in case any of the ancestors had completed but should now be enabled...
24777				tl = this;
24778				beforeRawTime = tl.rawTime() > value._startTime; //if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect.
24779				while (tl._timeline) {
24780					if (beforeRawTime && tl._timeline.smoothChildTiming) {
24781						tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it.
24782					} else if (tl._gc) {
24783						tl._enabled(true, false);
24784					}
24785					tl = tl._timeline;
24786				}
24787			}
24788
24789			return this;
24790		};
24791
24792		p.remove = function (value) {
24793			if (value instanceof Animation) {
24794				this._remove(value, false);
24795				var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline; //now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline.
24796				value._startTime = (value._paused ? value._pauseTime : tl._time) - (!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale; //ensure that if it gets played again, the timing is correct.
24797				return this;
24798			} else if (value instanceof Array || value && value.push && _isArray(value)) {
24799				var i = value.length;
24800				while (--i > -1) {
24801					this.remove(value[i]);
24802				}
24803				return this;
24804			} else if (typeof value === "string") {
24805				return this.removeLabel(value);
24806			}
24807			return this.kill(null, value);
24808		};
24809
24810		p._remove = function (tween, skipDisable) {
24811			SimpleTimeline.prototype._remove.call(this, tween, skipDisable);
24812			var last = this._last;
24813			if (!last) {
24814				this._time = this._totalTime = this._duration = this._totalDuration = 0;
24815			} else if (this._time > this.duration()) {
24816				this._time = this._duration;
24817				this._totalTime = this._totalDuration;
24818			}
24819			return this;
24820		};
24821
24822		p.append = function (value, offsetOrLabel) {
24823			return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value));
24824		};
24825
24826		p.insert = p.insertMultiple = function (value, position, align, stagger) {
24827			return this.add(value, position || 0, align, stagger);
24828		};
24829
24830		p.appendMultiple = function (tweens, offsetOrLabel, align, stagger) {
24831			return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger);
24832		};
24833
24834		p.addLabel = function (label, position) {
24835			this._labels[label] = this._parseTimeOrLabel(position);
24836			return this;
24837		};
24838
24839		p.addPause = function (position, callback, params, scope) {
24840			var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this);
24841			t.vars.onComplete = t.vars.onReverseComplete = callback;
24842			t.data = "isPause";
24843			this._hasPause = true;
24844			return this.add(t, position);
24845		};
24846
24847		p.removeLabel = function (label) {
24848			delete this._labels[label];
24849			return this;
24850		};
24851
24852		p.getLabelTime = function (label) {
24853			return this._labels[label] != null ? this._labels[label] : -1;
24854		};
24855
24856		p._parseTimeOrLabel = function (timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) {
24857			var clippedDuration, i;
24858			//if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration().
24859			if (ignore instanceof Animation && ignore.timeline === this) {
24860				this.remove(ignore);
24861			} else if (ignore && (ignore instanceof Array || ignore.push && _isArray(ignore))) {
24862				i = ignore.length;
24863				while (--i > -1) {
24864					if (ignore[i] instanceof Animation && ignore[i].timeline === this) {
24865						this.remove(ignore[i]);
24866					}
24867				}
24868			}
24869			clippedDuration = typeof timeOrLabel === "number" && !offsetOrLabel ? 0 : this.duration() > 99999999999 ? this.recent().endTime(false) : this._duration; //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead.
24870			if (typeof offsetOrLabel === "string") {
24871				return this._parseTimeOrLabel(offsetOrLabel, appendIfAbsent && typeof timeOrLabel === "number" && this._labels[offsetOrLabel] == null ? timeOrLabel - clippedDuration : 0, appendIfAbsent);
24872			}
24873			offsetOrLabel = offsetOrLabel || 0;
24874			if (typeof timeOrLabel === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) {
24875				//if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value).
24876				i = timeOrLabel.indexOf("=");
24877				if (i === -1) {
24878					if (this._labels[timeOrLabel] == null) {
24879						return appendIfAbsent ? this._labels[timeOrLabel] = clippedDuration + offsetOrLabel : offsetOrLabel;
24880					}
24881					return this._labels[timeOrLabel] + offsetOrLabel;
24882				}
24883				offsetOrLabel = parseInt(timeOrLabel.charAt(i - 1) + "1", 10) * Number(timeOrLabel.substr(i + 1));
24884				timeOrLabel = i > 1 ? this._parseTimeOrLabel(timeOrLabel.substr(0, i - 1), 0, appendIfAbsent) : clippedDuration;
24885			} else if (timeOrLabel == null) {
24886				timeOrLabel = clippedDuration;
24887			}
24888			return Number(timeOrLabel) + offsetOrLabel;
24889		};
24890
24891		p.seek = function (position, suppressEvents) {
24892			return this.totalTime(typeof position === "number" ? position : this._parseTimeOrLabel(position), suppressEvents !== false);
24893		};
24894
24895		p.stop = function () {
24896			return this.paused(true);
24897		};
24898
24899		p.gotoAndPlay = function (position, suppressEvents) {
24900			return this.play(position, suppressEvents);
24901		};
24902
24903		p.gotoAndStop = function (position, suppressEvents) {
24904			return this.pause(position, suppressEvents);
24905		};
24906
24907		p.render = function (time, suppressEvents, force) {
24908			if (this._gc) {
24909				this._enabled(true, false);
24910			}
24911			var totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
24912			    prevTime = this._time,
24913			    prevStart = this._startTime,
24914			    prevTimeScale = this._timeScale,
24915			    prevPaused = this._paused,
24916			    tween,
24917			    isComplete,
24918			    next,
24919			    callback,
24920			    internalForce,
24921			    pauseTween,
24922			    curTime;
24923			if (time >= totalDur - 0.0000001 && time >= 0) {
24924				//to work around occasional floating point math artifacts.
24925				this._totalTime = this._time = totalDur;
24926				if (!this._reversed) if (!this._hasPausedChild()) {
24927					isComplete = true;
24928					callback = "onComplete";
24929					internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
24930					if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) {
24931						internalForce = true;
24932						if (this._rawPrevTime > _tinyNum) {
24933							callback = "onReverseComplete";
24934						}
24935					}
24936				}
24937				this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
24938				time = totalDur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7.
24939			} else if (time < 0.0000001) {
24940				//to work around occasional floating point math artifacts, round super small values to 0.
24941				this._totalTime = this._time = 0;
24942				if (prevTime !== 0 || this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || time < 0 && this._rawPrevTime >= 0)) {
24943					callback = "onReverseComplete";
24944					isComplete = this._reversed;
24945				}
24946				if (time < 0) {
24947					this._active = false;
24948					if (this._timeline.autoRemoveChildren && this._reversed) {
24949						//ensures proper GC if a timeline is resumed after it's finished reversing.
24950						internalForce = isComplete = true;
24951						callback = "onReverseComplete";
24952					} else if (this._rawPrevTime >= 0 && this._first) {
24953						//when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
24954						internalForce = true;
24955					}
24956					this._rawPrevTime = time;
24957				} else {
24958					this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
24959					if (time === 0 && isComplete) {
24960						//if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
24961						tween = this._first;
24962						while (tween && tween._startTime === 0) {
24963							if (!tween._duration) {
24964								isComplete = false;
24965							}
24966							tween = tween._next;
24967						}
24968					}
24969					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
24970					if (!this._initted) {
24971						internalForce = true;
24972					}
24973				}
24974			} else {
24975
24976				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
24977					if (time >= prevTime) {
24978						tween = this._first;
24979						while (tween && tween._startTime <= time && !pauseTween) {
24980							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
24981								pauseTween = tween;
24982							}
24983							tween = tween._next;
24984						}
24985					} else {
24986						tween = this._last;
24987						while (tween && tween._startTime >= time && !pauseTween) {
24988							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
24989								pauseTween = tween;
24990							}
24991							tween = tween._prev;
24992						}
24993					}
24994					if (pauseTween) {
24995						this._time = time = pauseTween._startTime;
24996						this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay);
24997					}
24998				}
24999
25000				this._totalTime = this._time = this._rawPrevTime = time;
25001			}
25002			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
25003				return;
25004			} else if (!this._initted) {
25005				this._initted = true;
25006			}
25007
25008			if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) {
25009				this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
25010			}
25011
25012			if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) {
25013				this._callback("onStart");
25014			}
25015
25016			curTime = this._time;
25017			if (curTime >= prevTime) {
25018				tween = this._first;
25019				while (tween) {
25020					next = tween._next; //record it here because the value could change after rendering...
25021					if (curTime !== this._time || this._paused && !prevPaused) {
25022						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
25023						break;
25024					} else if (tween._active || tween._startTime <= curTime && !tween._paused && !tween._gc) {
25025						if (pauseTween === tween) {
25026							this.pause();
25027						}
25028						if (!tween._reversed) {
25029							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
25030						} else {
25031							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
25032						}
25033					}
25034					tween = next;
25035				}
25036			} else {
25037				tween = this._last;
25038				while (tween) {
25039					next = tween._prev; //record it here because the value could change after rendering...
25040					if (curTime !== this._time || this._paused && !prevPaused) {
25041						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
25042						break;
25043					} else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) {
25044						if (pauseTween === tween) {
25045							pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
25046							while (pauseTween && pauseTween.endTime() > this._time) {
25047								pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force);
25048								pauseTween = pauseTween._prev;
25049							}
25050							pauseTween = null;
25051							this.pause();
25052						}
25053						if (!tween._reversed) {
25054							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
25055						} else {
25056							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
25057						}
25058					}
25059					tween = next;
25060				}
25061			}
25062
25063			if (this._onUpdate) if (!suppressEvents) {
25064				if (_lazyTweens.length) {
25065					//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
25066					_lazyRender();
25067				}
25068				this._callback("onUpdate");
25069			}
25070
25071			if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) {
25072				//if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
25073				if (isComplete) {
25074					if (_lazyTweens.length) {
25075						//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
25076						_lazyRender();
25077					}
25078					if (this._timeline.autoRemoveChildren) {
25079						this._enabled(false, false);
25080					}
25081					this._active = false;
25082				}
25083				if (!suppressEvents && this.vars[callback]) {
25084					this._callback(callback);
25085				}
25086			}
25087		};
25088
25089		p._hasPausedChild = function () {
25090			var tween = this._first;
25091			while (tween) {
25092				if (tween._paused || tween instanceof TimelineLite && tween._hasPausedChild()) {
25093					return true;
25094				}
25095				tween = tween._next;
25096			}
25097			return false;
25098		};
25099
25100		p.getChildren = function (nested, tweens, timelines, ignoreBeforeTime) {
25101			ignoreBeforeTime = ignoreBeforeTime || -9999999999;
25102			var a = [],
25103			    tween = this._first,
25104			    cnt = 0;
25105			while (tween) {
25106				if (tween._startTime < ignoreBeforeTime) {
25107					//do nothing
25108				} else if (tween instanceof TweenLite) {
25109					if (tweens !== false) {
25110						a[cnt++] = tween;
25111					}
25112				} else {
25113					if (timelines !== false) {
25114						a[cnt++] = tween;
25115					}
25116					if (nested !== false) {
25117						a = a.concat(tween.getChildren(true, tweens, timelines));
25118						cnt = a.length;
25119					}
25120				}
25121				tween = tween._next;
25122			}
25123			return a;
25124		};
25125
25126		p.getTweensOf = function (target, nested) {
25127			var disabled = this._gc,
25128			    a = [],
25129			    cnt = 0,
25130			    tweens,
25131			    i;
25132			if (disabled) {
25133				this._enabled(true, true); //getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here.
25134			}
25135			tweens = TweenLite.getTweensOf(target);
25136			i = tweens.length;
25137			while (--i > -1) {
25138				if (tweens[i].timeline === this || nested && this._contains(tweens[i])) {
25139					a[cnt++] = tweens[i];
25140				}
25141			}
25142			if (disabled) {
25143				this._enabled(false, true);
25144			}
25145			return a;
25146		};
25147
25148		p.recent = function () {
25149			return this._recent;
25150		};
25151
25152		p._contains = function (tween) {
25153			var tl = tween.timeline;
25154			while (tl) {
25155				if (tl === this) {
25156					return true;
25157				}
25158				tl = tl.timeline;
25159			}
25160			return false;
25161		};
25162
25163		p.shiftChildren = function (amount, adjustLabels, ignoreBeforeTime) {
25164			ignoreBeforeTime = ignoreBeforeTime || 0;
25165			var tween = this._first,
25166			    labels = this._labels,
25167			    p;
25168			while (tween) {
25169				if (tween._startTime >= ignoreBeforeTime) {
25170					tween._startTime += amount;
25171				}
25172				tween = tween._next;
25173			}
25174			if (adjustLabels) {
25175				for (p in labels) {
25176					if (labels[p] >= ignoreBeforeTime) {
25177						labels[p] += amount;
25178					}
25179				}
25180			}
25181			return this._uncache(true);
25182		};
25183
25184		p._kill = function (vars, target) {
25185			if (!vars && !target) {
25186				return this._enabled(false, false);
25187			}
25188			var tweens = !target ? this.getChildren(true, true, false) : this.getTweensOf(target),
25189			    i = tweens.length,
25190			    changed = false;
25191			while (--i > -1) {
25192				if (tweens[i]._kill(vars, target)) {
25193					changed = true;
25194				}
25195			}
25196			return changed;
25197		};
25198
25199		p.clear = function (labels) {
25200			var tweens = this.getChildren(false, true, true),
25201			    i = tweens.length;
25202			this._time = this._totalTime = 0;
25203			while (--i > -1) {
25204				tweens[i]._enabled(false, false);
25205			}
25206			if (labels !== false) {
25207				this._labels = {};
25208			}
25209			return this._uncache(true);
25210		};
25211
25212		p.invalidate = function () {
25213			var tween = this._first;
25214			while (tween) {
25215				tween.invalidate();
25216				tween = tween._next;
25217			}
25218			return Animation.prototype.invalidate.call(this);;
25219		};
25220
25221		p._enabled = function (enabled, ignoreTimeline) {
25222			if (enabled === this._gc) {
25223				var tween = this._first;
25224				while (tween) {
25225					tween._enabled(enabled, true);
25226					tween = tween._next;
25227				}
25228			}
25229			return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline);
25230		};
25231
25232		p.totalTime = function (time, suppressEvents, uncapped) {
25233			this._forcingPlayhead = true;
25234			var val = Animation.prototype.totalTime.apply(this, arguments);
25235			this._forcingPlayhead = false;
25236			return val;
25237		};
25238
25239		p.duration = function (value) {
25240			if (!arguments.length) {
25241				if (this._dirty) {
25242					this.totalDuration(); //just triggers recalculation
25243				}
25244				return this._duration;
25245			}
25246			if (this.duration() !== 0 && value !== 0) {
25247				this.timeScale(this._duration / value);
25248			}
25249			return this;
25250		};
25251
25252		p.totalDuration = function (value) {
25253			if (!arguments.length) {
25254				if (this._dirty) {
25255					var max = 0,
25256					    tween = this._last,
25257					    prevStart = 999999999999,
25258					    prev,
25259					    end;
25260					while (tween) {
25261						prev = tween._prev; //record it here in case the tween changes position in the sequence...
25262						if (tween._dirty) {
25263							tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it.
25264						}
25265						if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) {
25266							//in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence
25267							this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel().
25268							this.add(tween, tween._startTime - tween._delay);
25269							this._calculatingDuration = 0;
25270						} else {
25271							prevStart = tween._startTime;
25272						}
25273						if (tween._startTime < 0 && !tween._paused) {
25274							//children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.
25275							max -= tween._startTime;
25276							if (this._timeline.smoothChildTiming) {
25277								this._startTime += tween._startTime / this._timeScale;
25278								this._time -= tween._startTime;
25279								this._totalTime -= tween._startTime;
25280								this._rawPrevTime -= tween._startTime;
25281							}
25282							this.shiftChildren(-tween._startTime, false, -9999999999);
25283							prevStart = 0;
25284						}
25285						end = tween._startTime + tween._totalDuration / tween._timeScale;
25286						if (end > max) {
25287							max = end;
25288						}
25289						tween = prev;
25290					}
25291					this._duration = this._totalDuration = max;
25292					this._dirty = false;
25293				}
25294				return this._totalDuration;
25295			}
25296			return value && this.totalDuration() ? this.timeScale(this._totalDuration / value) : this;
25297		};
25298
25299		p.paused = function (value) {
25300			if (!value) {
25301				//if there's a pause directly at the spot from where we're unpausing, skip it.
25302				var tween = this._first,
25303				    time = this._time;
25304				while (tween) {
25305					if (tween._startTime === time && tween.data === "isPause") {
25306						tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire.
25307					}
25308					tween = tween._next;
25309				}
25310			}
25311			return Animation.prototype.paused.apply(this, arguments);
25312		};
25313
25314		p.usesFrames = function () {
25315			var tl = this._timeline;
25316			while (tl._timeline) {
25317				tl = tl._timeline;
25318			}
25319			return tl === Animation._rootFramesTimeline;
25320		};
25321
25322		p.rawTime = function (wrapRepeats) {
25323			return wrapRepeats && (this._paused || this._repeat && this.time() > 0 && this.totalProgress() < 1) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale;
25324		};
25325
25326		return TimelineLite;
25327	}, true);
25328});if (_gsScope._gsDefine) {
25329	_gsScope._gsQueue.pop()();
25330}
25331
25332//export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date)
25333(function (name) {
25334	"use strict";
25335
25336	var getGlobal = function () {
25337		return (_gsScope.GreenSockGlobals || _gsScope)[name];
25338	};
25339	if (typeof module !== "undefined" && module.exports) {
25340		//node
25341		__webpack_require__(1); //dependency
25342		module.exports = getGlobal();
25343	} else if (true) {
25344		//AMD
25345		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_FACTORY__ = (getGlobal),
25346				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
25347				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
25348				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
25349	}
25350})("TimelineMax");
25351/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5)))
25352
25353/***/ }),
25354/* 9 */
25355/***/ (function(module, __webpack_exports__, __webpack_require__) {
25356
25357"use strict";
25358/**
25359 * ------------------------------------------------------------------
25360 * 模组 -
25361 * ------------------------------------------------------------------
25362 */
25363
25364/**
25365* 函数功能简述: 回传画面宽度
25366* 具体描述一些细节:
25367* @date     2017-10-30
25368* @author   Telliex<[email protected]>
25369*           Fish<[email protected]>
25370*/
25371
25372const viewport = () => {
25373  let e = window;
25374  let a = 'inner';
25375  if (!('innerWidth' in window)) {
25376    a = 'client';
25377    e = document.documentElement || document.body;
25378  }
25379  return e[`${a}Width`];
25380};
25381/* harmony default export */ __webpack_exports__["a"] = (viewport);
25382
25383/***/ }),
25384/* 10 */
25385/***/ (function(module, __webpack_exports__, __webpack_require__) {
25386
25387"use strict";
25388/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery__ = __webpack_require__(0);
25389/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_jquery__);
25390/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__browser__ = __webpack_require__(6);
25391/* eslint consistent-return: "off" */
25392/* eslint func-names: ["off"] */
25393/* eslint max-len: ["off", { "code": 200 }] */
25394/* eslint prefer-destructuring: ["off"] */
25395/* eslint no-undef: "off" */
25396
25397/* eslint class-methods-use-this: ["error", { "exceptMethods": ["viewport","ie8Browser"," modernBrowser","modernBrowser","flashSupported"] }] */
25398/**
25399 * ------------------------------------------------------------------
25400 * 模组 -
25401 * ------------------------------------------------------------------
25402 */
25403
25404/**
25405 * 函数功能简述: 回传画面宽度
25406 * 具体描述一些细节:
25407 * @date     2017-10-30
25408 * @author   Telliex<[email protected]>
25409 *           Fish<[email protected]>
25410 */
25411
25412
25413
25414
25415// ------------ 偵測瀏覽器狀態
25416
25417class BrowserChecker {
25418  /*
25419  | 偵測 Desktop / Mobile
25420  */
25421  viewport(windowSize) {
25422    if (windowSize >= 1360) {
25423      return 'max';
25424    } else if (windowSize >= 960 && windowSize < 1360) {
25425      return 'desktop';
25426    } else if (windowSize >= 768 && windowSize < 960) {
25427      return 'tablet';
25428    }
25429    return 'mobile';
25430  }
25431
25432  /*
25433  | 偵測是否為 IE8 以下版本
25434  */
25435  ie8Browser() {
25436    if (__WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE6' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE7' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE8') {
25437      return true;
25438    }
25439    return false;
25440  }
25441
25442  /*
25443  | 偵測是否為 Modern Browser
25444  */
25445  modernBrowser() {
25446    if (__WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE6' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE7' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE8' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE9' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE10') {
25447      return false;
25448    }
25449    return true;
25450  }
25451
25452  /*
25453  | 判斷是否支援/安裝 Flash
25454  */
25455  flashSupported() {
25456    if (__WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE6' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE7' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE8' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE9' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE10' || __WEBPACK_IMPORTED_MODULE_1__browser__["a" /* default */] === 'IE11') {
25457      if (window.ActiveXObject) {
25458        try {
25459          if (new ActiveXObject('ShockwaveFlash.ShockwaveFlash')) {
25460            return true;
25461          }
25462        } catch (e) {
25463          // ..
25464        }
25465      }
25466      if (navigator.plugins) {
25467        for (let i = 0; i < navigator.plugins.length; i += 1) {
25468          if (navigator.plugins[i].name.toLowerCase().indexOf('shockwave flash') >= 0) {
25469            return true;
25470          }
25471        }
25472        return false;
25473      }
25474      return false;
25475    }
25476    return true;
25477  }
25478}
25479
25480// 宣告 各個 Class
25481const globalBrowserChecker = new BrowserChecker();
25482/* harmony default export */ __webpack_exports__["a"] = (globalBrowserChecker);
25483
25484/***/ }),
25485/* 11 */,
25486/* 12 */,
25487/* 13 */,
25488/* 14 */,
25489/* 15 */,
25490/* 16 */,
25491/* 17 */,
25492/* 18 */,
25493/* 19 */,
25494/* 20 */,
25495/* 21 */
25496/***/ (function(module, exports, __webpack_require__) {
25497
25498var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
25499 * ScrollMagic v2.0.5 (2015-04-29)
25500 * The javascript library for magical scroll interactions.
25501 * (c) 2015 Jan Paepke (@janpaepke)
25502 * Project Website: http://scrollmagic.io
25503 * 
25504 * @version 2.0.5
25505 * @license Dual licensed under MIT license and GPL.
25506 * @author Jan Paepke - [email protected]
25507 *
25508 * @file ScrollMagic GSAP Animation Plugin.
25509 *
25510 * requires: GSAP ~1.14
25511 * Powered by the Greensock Animation Platform (GSAP): http://www.greensock.com/js
25512 * Greensock License info at http://www.greensock.com/licensing/
25513 */
25514/**
25515 * This plugin is meant to be used in conjunction with the Greensock Animation Plattform.  
25516 * It offers an easy API to trigger Tweens or synchronize them to the scrollbar movement.
25517 *
25518 * Both the `lite` and the `max` versions of the GSAP library are supported.  
25519 * The most basic requirement is `TweenLite`.
25520 * 
25521 * To have access to this extension, please include `plugins/animation.gsap.js`.
25522 * @requires {@link http://greensock.com/gsap|GSAP ~1.14.x}
25523 * @mixin animation.GSAP
25524 */
25525(function (root, factory) {
25526	if (true) {
25527		// AMD. Register as an anonymous module.
25528		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2), __webpack_require__(7), __webpack_require__(8)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
25529				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
25530				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
25531				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
25532	} else if (typeof exports === 'object') {
25533		// CommonJS
25534		// Loads whole gsap package onto global scope.
25535		require('gsap');
25536		factory(require('scrollmagic'), TweenMax, TimelineMax);
25537	} else {
25538		// Browser globals
25539		factory(root.ScrollMagic || root.jQuery && root.jQuery.ScrollMagic, root.TweenMax || root.TweenLite, root.TimelineMax || root.TimelineLite);
25540	}
25541})(this, function (ScrollMagic, Tween, Timeline) {
25542	"use strict";
25543
25544	var NAMESPACE = "animation.gsap";
25545
25546	var console = window.console || {},
25547	    err = Function.prototype.bind.call(console.error || console.log || function () {}, console);
25548	if (!ScrollMagic) {
25549		err("(" + NAMESPACE + ") -> ERROR: The ScrollMagic main module could not be found. Please make sure it's loaded before this plugin or use an asynchronous loader like requirejs.");
25550	}
25551	if (!Tween) {
25552		err("(" + NAMESPACE + ") -> ERROR: TweenLite or TweenMax could not be found. Please make sure GSAP is loaded before ScrollMagic or use an asynchronous loader like requirejs.");
25553	}
25554
25555	/*
25556 	 * ----------------------------------------------------------------
25557 	 * Extensions for Scene
25558 	 * ----------------------------------------------------------------
25559 	 */
25560	/**
25561  * Every instance of ScrollMagic.Scene now accepts an additional option.  
25562  * See {@link ScrollMagic.Scene} for a complete list of the standard options.
25563  * @memberof! animation.GSAP#
25564  * @method new ScrollMagic.Scene(options)
25565  * @example
25566  * var scene = new ScrollMagic.Scene({tweenChanges: true});
25567  *
25568  * @param {object} [options] - Options for the Scene. The options can be updated at any time.
25569  * @param {boolean} [options.tweenChanges=false] - Tweens Animation to the progress target instead of setting it.  
25570  Does not affect animations where duration is `0`.
25571  */
25572	/**
25573  * **Get** or **Set** the tweenChanges option value.  
25574  * This only affects scenes with a duration. If `tweenChanges` is `true`, the progress update when scrolling will not be immediate, but instead the animation will smoothly animate to the target state.  
25575  * For a better understanding, try enabling and disabling this option in the [Scene Manipulation Example](../examples/basic/scene_manipulation.html).
25576  * @memberof! animation.GSAP#
25577  * @method Scene.tweenChanges
25578  * 
25579  * @example
25580  * // get the current tweenChanges option
25581  * var tweenChanges = scene.tweenChanges();
25582  *
25583  * // set new tweenChanges option
25584  * scene.tweenChanges(true);
25585  *
25586  * @fires {@link Scene.change}, when used as setter
25587  * @param {boolean} [newTweenChanges] - The new tweenChanges setting of the scene.
25588  * @returns {boolean} `get` -  Current tweenChanges option value.
25589  * @returns {Scene} `set` -  Parent object for chaining.
25590  */
25591	// add option (TODO: DOC (private for dev))
25592	ScrollMagic.Scene.addOption("tweenChanges", // name
25593	false, // default
25594
25595
25596	function (val) {
25597		// validation callback
25598		return !!val;
25599	});
25600	// extend scene
25601	ScrollMagic.Scene.extend(function () {
25602		var Scene = this,
25603		    _tween;
25604
25605		var log = function () {
25606			if (Scene._log) {
25607				// not available, when main source minified
25608				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
25609				Scene._log.apply(this, arguments);
25610			}
25611		};
25612
25613		// set listeners
25614		Scene.on("progress.plugin_gsap", function () {
25615			updateTweenProgress();
25616		});
25617		Scene.on("destroy.plugin_gsap", function (e) {
25618			Scene.removeTween(e.reset);
25619		});
25620
25621		/**
25622   * Update the tween progress to current position.
25623   * @private
25624   */
25625		var updateTweenProgress = function () {
25626			if (_tween) {
25627				var progress = Scene.progress(),
25628				    state = Scene.state();
25629				if (_tween.repeat && _tween.repeat() === -1) {
25630					// infinite loop, so not in relation to progress
25631					if (state === 'DURING' && _tween.paused()) {
25632						_tween.play();
25633					} else if (state !== 'DURING' && !_tween.paused()) {
25634						_tween.pause();
25635					}
25636				} else if (progress != _tween.progress()) {
25637					// do we even need to update the progress?
25638					// no infinite loop - so should we just play or go to a specific point in t
25638ime?
25639					if (Scene.duration() === 0) {
25640						// play the animation
25641						if (progress > 0) {
25642							// play from 0 to 1
25643							_tween.play();
25644						} else {
25645							// play from 1 to 0
25646							_tween.reverse();
25647						}
25648					} else {
25649						// go to a specific point in time
25650						if (Scene.tweenChanges() && _tween.tweenTo) {
25651							// go smooth
25652							_tween.tweenTo(progress * _tween.duration());
25653						} else {
25654							// just hard set it
25655							_tween.progress(progress).pause();
25656						}
25657					}
25658				}
25659			}
25660		};
25661
25662		/**
25663   * Add a tween to the scene.  
25664   * If you want to add multiple tweens, add them into a GSAP Timeline object and supply it instead (see example below).  
25665   * 
25666   * If the scene has a duration, the tween's duration will be projected to the scroll distance of the scene, meaning its progress will be synced to scrollbar movement.  
25667   * For a scene with a duration of `0`, the tween will be triggered when scrolling forward past the scene's trigger position and reversed, when scrolling back.  
25668   * To gain better understanding, check out the [Simple Tweening example](../examples/basic/simple_tweening.html).
25669   *
25670   * Instead of supplying a tween this method can also be used as a shorthand for `TweenMax.to()` (see example below).
25671   * @memberof! animation.GSAP#
25672   *
25673   * @example
25674   * // add a single tween directly
25675   * scene.setTween(TweenMax.to("obj"), 1, {x: 100});
25676   *
25677   * // add a single tween via variable
25678   * var tween = TweenMax.to("obj"), 1, {x: 100};
25679   * scene.setTween(tween);
25680   *
25681   * // add multiple tweens, wrapped in a timeline.
25682   * var timeline = new TimelineMax();
25683   * var tween1 = TweenMax.from("obj1", 1, {x: 100});
25684   * var tween2 = TweenMax.to("obj2", 1, {y: 100});
25685   * timeline
25686   *		.add(tween1)
25687   *		.add(tween2);
25688   * scene.addTween(timeline);
25689   *
25690   * // short hand to add a TweenMax.to() tween
25691   * scene.setTween("obj3", 0.5, {y: 100});
25692   *
25693   * // short hand to add a TweenMax.to() tween for 1 second
25694   * // this is useful, when the scene has a duration and the tween duration isn't important anyway
25695   * scene.setTween("obj3", {y: 100});
25696   *
25697   * @param {(object|string)} TweenObject - A TweenMax, TweenLite, TimelineMax or TimelineLite object that should be animated in the scene. Can also be a Dom Element or Selector, when using direct tween definition (see examples).
25698   * @param {(number|object)} duration - A duration for the tween, or tween parameters. If an object containing parameters are supplied, a default duration of 1 will be used.
25699   * @param {object} params - The parameters for the tween
25700   * @returns {Scene} Parent object for chaining.
25701   */
25702		Scene.setTween = function (TweenObject, duration, params) {
25703			var newTween;
25704			if (arguments.length > 1) {
25705				if (arguments.length < 3) {
25706					params = duration;
25707					duration = 1;
25708				}
25709				TweenObject = Tween.to(TweenObject, duration, params);
25710			}
25711			try {
25712				// wrap Tween into a Timeline Object if available to include delay and repeats in the duration and standardize methods.
25713				if (Timeline) {
25714					newTween = new Timeline({
25715						smoothChildTiming: true
25716					}).add(TweenObject);
25717				} else {
25718					newTween = TweenObject;
25719				}
25720				newTween.pause();
25721			} catch (e) {
25722				log(1, "ERROR calling method 'setTween()': Supplied argument is not a valid TweenObject");
25723				return Scene;
25724			}
25725			if (_tween) {
25726				// kill old tween?
25727				Scene.removeTween();
25728			}
25729			_tween = newTween;
25730
25731			// some properties need to be transferred it to the wrapper, otherwise they would get lost.
25732			if (TweenObject.repeat && TweenObject.repeat() === -1) {
25733				// TweenMax or TimelineMax Object?
25734				_tween.repeat(-1);
25735				_tween.yoyo(TweenObject.yoyo());
25736			}
25737			// Some tween validations and debugging helpers
25738			if (Scene.tweenChanges() && !_tween.tweenTo) {
25739				log(2, "WARNING: tweenChanges will only work if the TimelineMax object is available for ScrollMagic.");
25740			}
25741
25742			// check if there are position tweens defined for the trigger and warn about it :)
25743			if (_tween && Scene.controller() && Scene.triggerElement() && Scene.loglevel() >= 2) {
25744				// controller is needed to know scroll direction.
25745				var triggerTweens = Tween.getTweensOf(Scene.triggerElement()),
25746				    vertical = Scene.controller().info("vertical");
25747				triggerTweens.forEach(function (value, index) {
25748					var tweenvars = value.vars.css || value.vars,
25749					    condition = vertical ? tweenvars.top !== undefined || tweenvars.bottom !== undefined : tweenvars.left !== undefined || tweenvars.right !== undefined;
25750					if (condition) {
25751						log(2, "WARNING: Tweening the position of the trigger element affects the scene timing and should be avoided!");
25752						return false;
25753					}
25754				});
25755			}
25756
25757			// warn about tween overwrites, when an element is tweened multiple times
25758			if (parseFloat(TweenLite.version) >= 1.14) {
25759				// onOverwrite only present since GSAP v1.14.0
25760				var list = _tween.getChildren ? _tween.getChildren(true, true, false) : [_tween],
25761
25762				// get all nested tween objects
25763				newCallback = function () {
25764					log(2, "WARNING: tween was overwritten by another. To learn how to avoid this issue see here: https://github.com/janpaepke/ScrollMagic/wiki/WARNING:-tween-was-overwritten-by-another");
25765				};
25766				for (var i = 0, thisTween, oldCallback; i < list.length; i++) {
25767					/*jshint loopfunc: true */
25768					thisTween = list[i];
25769					if (oldCallback !== newCallback) {
25770						// if tweens is added more than once
25771						oldCallback = thisTween.vars.onOverwrite;
25772						thisTween.vars.onOverwrite = function () {
25773							if (oldCallback) {
25774								oldCallback.apply(this, arguments);
25775							}
25776							newCallback.apply(this, arguments);
25777						};
25778					}
25779				}
25780			}
25781			log(3, "added tween");
25782
25783			updateTweenProgress();
25784			return Scene;
25785		};
25786
25787		/**
25788   * Remove the tween from the scene.  
25789   * This will terminate the control of the Scene over the tween.
25790   *
25791   * Using the reset option you can decide if the tween should remain in the current state or be rewound to set the target elements back to the state they were in before the tween was added to the scene.
25792   * @memberof! animation.GSAP#
25793   *
25794   * @example
25795   * // remove the tween from the scene without resetting it
25796   * scene.removeTween();
25797   *
25798   * // remove the tween from the scene and reset it to initial position
25799   * scene.removeTween(true);
25800   *
25801   * @param {boolean} [reset=false] - If `true` the tween will be reset to its initial values.
25802   * @returns {Scene} Parent object for chaining.
25803   */
25804		Scene.removeTween = function (reset) {
25805			if (_tween) {
25806				if (reset) {
25807					_tween.progress(0).pause();
25808				}
25809				_tween.kill();
25810				_tween = undefined;
25811				log(3, "removed tween (reset: " + (reset ? "true" : "false") + ")");
25812			}
25813			return Scene;
25814		};
25815	});
25816});
25817
25818/***/ }),
25819/* 22 */
25820/***/ (function(module, exports, __webpack_require__) {
25821
25822var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
25823 * ScrollMagic v2.0.5 (2015-04-29)
25824 * The javascript library for magical scroll interactions.
25825 * (c) 2015 Jan Paepke (@janpaepke)
25826 * Project Website: http://scrollmagic.io
25827 * 
25828 * @version 2.0.5
25829 * @license Dual licensed under MIT license and GPL.
25830 * @author Jan Paepke - [email protected]
25831 *
25832 * @file Debug Extension for ScrollMagic.
25833 */
25834/**
25835 * This plugin was formerly known as the ScrollMagic debug extension.
25836 *
25837 * It enables you to add visual indicators to your page, to be able to see exactly when a scene is triggered.
25838 *
25839 * To have access to this extension, please include `plugins/debug.addIndicators.js`.
25840 * @mixin debug.addIndicators
25841 */
25842(function (root, factory) {
25843	if (true) {
25844		// AMD. Register as an anonymous module.
25845		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(2)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),
25846				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
25847				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
25848				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
25849	} else if (typeof exports === 'object') {
25850		// CommonJS
25851		factory(require('scrollmagic'));
25852	} else {
25853		// no browser global export needed, just execute
25854		factory(root.ScrollMagic || root.jQuery && root.jQuery.ScrollMagic);
25855	}
25856})(this, function (ScrollMagic) {
25857	"use strict";
25858
25859	var NAMESPACE = "debug.addIndicators";
25860
25861	var console = window.console || {},
25862	    err = Function.prototype.bind.call(console.error || console.log || function () {}, console);
25863	if (!ScrollMagic) {
25864		err("(" + NAMESPACE + ") -> ERROR: The ScrollMagic main module could not be found. Please make sure it's loaded before this plugin or use an asynchronous loader like requirejs.");
25865	}
25866
25867	// plugin settings
25868	var FONT_SIZE = "0.85em",
25869	    ZINDEX = "9999",
25870	    EDGE_OFFSET = 15; // minimum edge distance, added to indentation
25871
25872	// overall vars
25873	var _util = ScrollMagic._util,
25874	    _autoindex = 0;
25875
25876	ScrollMagic.Scene.extend(function () {
25877		var Scene = this,
25878		    _indicator;
25879
25880		var log = function () {
25881			if (Scene._log) {
25882				// not available, when main source minified
25883				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
25884				Scene._log.apply(this, arguments);
25885			}
25886		};
25887
25888		/**
25889   * Add visual indicators for a ScrollMagic.Scene.  
25890   * @memberof! debug.addIndicators#
25891   *
25892   * @example
25893   * // add basic indicators
25894   * scene.addIndicators()
25895   *
25896   * // passing options
25897   * scene.addIndicators({name: "pin scene", colorEnd: "#FFFFFF"});
25898   *
25899   * @param {object}
25899 [options] - An object containing one or more options for the indicators.
25900   * @param {(string|object)} [options.parent=undefined] - A selector, DOM Object or a jQuery object that the indicators should be added to.  
25901   If undefined, the controller's container will be used.
25902   * @param {number} [options.name=""] - This string will be displayed at the start and end indicators of the scene for identification purposes. If no name is supplied an automatic index will be used.
25903   * @param {number} [options.indent=0] - Additional position offset for the indicators (useful, when having multiple scenes starting at the same position).
25904   * @param {string} [options.colorStart=green] - CSS color definition for the start indicator.
25905   * @param {string} [options.colorEnd=red] - CSS color definition for the end indicator.
25906   * @param {string} [options.colorTrigger=blue] - CSS color definition for the trigger indicator.
25907   */
25908		Scene.addIndicators = function (options) {
25909			if (!_indicator) {
25910				var DEFAULT_OPTIONS = {
25911					name: "",
25912					indent: 0,
25913					parent: undefined,
25914					colorStart: "green",
25915					colorEnd: "red",
25916					colorTrigger: "blue"
25917				};
25918
25919				options = _util.extend({}, DEFAULT_OPTIONS, options);
25920
25921				_autoindex++;
25922				_indicator = new Indicator(Scene, options);
25923
25924				Scene.on("add.plugin_addIndicators", _indicator.add);
25925				Scene.on("remove.plugin_addIndicators", _indicator.remove);
25926				Scene.on("destroy.plugin_addIndicators", Scene.removeIndicators);
25927
25928				// it the scene already has a controller we can start right away.
25929				if (Scene.controller()) {
25930					_indicator.add();
25931				}
25932			}
25933			return Scene;
25934		};
25935
25936		/**
25937   * Removes visual indicators from a ScrollMagic.Scene.
25938   * @memberof! debug.addIndicators#
25939   *
25940   * @example
25941   * // remove previously added indicators
25942   * scene.removeIndicators()
25943   *
25944   */
25945		Scene.removeIndicators = function () {
25946			if (_indicator) {
25947				_indicator.remove();
25948				this.off("*.plugin_addIndicators");
25949				_indicator = undefined;
25950			}
25951			return Scene;
25952		};
25953	});
25954
25955	/*
25956 	 * ----------------------------------------------------------------
25957 	 * Extension for controller to store and update related indicators
25958 	 * ----------------------------------------------------------------
25959 	 */
25960	// add option to globally auto-add indicators to scenes
25961	/**
25962  * Every ScrollMagic.Controller instance now accepts an additional option.  
25963  * See {@link ScrollMagic.Controller} for a complete list of the standard options.
25964  * @memberof! debug.addIndicators#
25965  * @method new ScrollMagic.Controller(options)
25966  * @example
25967  * // make a controller and add indicators to all scenes attached
25968  * var controller = new ScrollMagic.Controller({addIndicators: true});
25969  * // this scene will automatically have indicators added to it
25970  * new ScrollMagic.Scene()
25971  *                .addTo(controller);
25972  *
25973  * @param {object} [options] - Options for the Controller.
25974  * @param {boolean} [options.addIndicators=false] - If set to `true` every scene that is added to the controller will automatically get indicators added to it.
25975  */
25976	ScrollMagic.Controller.addOption("addIndicators", false);
25977	// extend Controller
25978	ScrollMagic.Controller.extend(function () {
25979		var Controller = this,
25980		    _info = Controller.info(),
25981		    _container = _info.container,
25982		    _isDocument = _info.isDocument,
25983		    _vertical = _info.vertical,
25984		    _indicators = { // container for all indicators and methods
25985			groups: []
25986		};
25987
25988		var log = function () {
25989			if (Controller._log) {
25990				// not available, when main source minified
25991				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
25992				Controller._log.apply(this, arguments);
25993			}
25994		};
25995		if (Controller._indicators) {
25996			log(2, "WARNING: Scene already has a property '_indicators', which will be overwritten by plugin.");
25997		}
25998
25999		// add indicators container
26000		this._indicators = _indicators;
26001		/*
26002  			needed updates:
26003  			+++++++++++++++
26004  			start/end position on scene shift (handled in Indicator class)
26005  			trigger parameters on triggerHook value change (handled in Indicator class)
26006  			bounds position on container scroll or resize (to keep alignment to bottom/right)
26007  			trigger position on container resize, window resize (if container isn't document) and window scroll (if container isn't document)
26008  		*/
26009
26010		// event handler for when associated bounds markers need to be repositioned
26011		var handleBoundsPositionChange = function () {
26012			_indicators.updateBoundsPositions();
26013		};
26014
26015		// event handler for when associated trigger groups need to be repositioned
26016		var handleTriggerPositionChange = function () {
26017			_indicators.updateTriggerGroupPositions();
26018		};
26019
26020		_container.addEventListener("resize", handleTriggerPositionChange);
26021		if (!_isDocument) {
26022			window.addEventListener("resize", handleTriggerPositionChange);
26023			window.addEventListener("scroll", handleTriggerPositionChange);
26024		}
26025		// update all related bounds containers
26026		_container.addEventListener("resize", handleBoundsPositionChange);
26027		_container.addEventListener("scroll", handleBoundsPositionChange);
26028
26029		// updates the position of the bounds container to aligned to the right for vertical containers and to the bottom for horizontal
26030		this._indicators.updateBoundsPositions = function (specificIndicator) {
26031			var // constant for all bounds
26032			groups = specificIndicator ? [_util.extend({}, specificIndicator.triggerGroup, {
26033				members: [specificIndicator]
26034			})] : // create a group with only one element
26035			_indicators.groups,
26036
26037			// use all
26038			g = groups.length,
26039			    css = {},
26040			    paramPos = _vertical ? "left" : "top",
26041			    paramDimension = _vertical ? "width" : "height",
26042			    edge = _vertical ? _util.get.scrollLeft(_container) + _util.get.width(_container) - EDGE_OFFSET : _util.get.scrollTop(_container) + _util.get.height(_container) - EDGE_OFFSET,
26043			    b,
26044			    triggerSize,
26045			    group;
26046			while (g--) {
26047				// group loop
26048				group = groups[g];
26049				b = group.members.length;
26050				triggerSize = _util.get[paramDimension](group.element.firstChild);
26051				while (b--) {
26052					// indicators loop
26053					css[paramPos] = edge - triggerSize;
26054					_util.css(group.members[b].bounds, css);
26055				}
26056			}
26057		};
26058
26059		// updates the positions of all trigger groups attached to a controller or a specific one, if provided
26060		this._indicators.updateTriggerGroupPositions = function (specificGroup) {
26061			var // constant vars
26062			groups = specificGroup ? [specificGroup] : _indicators.groups,
26063			    i = groups.length,
26064			    container = _isDocument ? document.body : _container,
26065			    containerOffset = _isDocument ? {
26066				top: 0,
26067				left: 0
26068			} : _util.get.offset(container, true),
26069			    edge = _vertical ? _util.get.width(_container) - EDGE_OFFSET : _util.get.height(_container) - EDGE_OFFSET,
26070			    paramDimension = _vertical ? "width" : "height",
26071			    paramTransform = _vertical ? "Y" : "X";
26072			var // changing vars
26073			group, elem, pos, elemSize, transform;
26074			while (i--) {
26075				group = groups[i];
26076				elem = group.element;
26077				pos = group.triggerHook * Controller.info("size");
26078				elemSize = _util.get[paramDimension](elem.firstChild.firstChild);
26079				transform = pos > elemSize ? "translate" + paramTransform + "(-100%)" : "";
26080
26081				_util.css(elem, {
26082					top: containerOffset.top + (_vertical ? pos : edge - group.members[0].options.indent),
26083					left: containerOffset.left + (_vertical ? edge - group.members[0].options.indent : pos)
26084				});
26085				_util.css(elem.firstChild.firstChild, {
26086					"-ms-transform": transform,
26087					"-webkit-transform": transform,
26088					"transform": transform
26089				});
26090			}
26091		};
26092
26093		// updates the label for the group to contain the name, if it only has one member
26094		this._indicators.updateTriggerGroupLabel = function (group) {
26095			var text = "trigger" + (group.members.length > 1 ? "" : " " + group.members[0].options.name),
26096			    elem = group.element.firstChild.firstChild,
26097			    doUpdate = elem.textContent !== text;
26098			if (doUpdate) {
26099				elem.textContent = text;
26100				if (_vertical) {
26101					// bounds position is dependent on text length, so update
26102					_indicators.updateBoundsPositions();
26103				}
26104			}
26105		};
26106
26107		// add indicators if global option is set
26108		this.addScene = function (newScene) {
26109
26110			if (this._options.addIndicators && newScene instanceof ScrollMagic.Scene && newScene.controller() === Controller) {
26111				newScene.addIndicators();
26112			}
26113			// call original destroy method
26114			this.$super.addScene.apply(this, arguments);
26115		};
26116
26117		// remove all previously set listeners on destroy
26118		this.destroy = function () {
26119			_container.removeEventListener("resize", handleTriggerPositionChange);
26120			if (!_isDocument) {
26121				window.removeEventListener("resize", handleTriggerPositionChange);
26122				window.removeEventListener("scroll", handleTriggerPositionChange);
26123			}
26124			_container.removeEventListener("resize", handleBoundsPositionChange);
26125			_container.removeEventListener("scroll", handleBoundsPositionChange);
26126			// call original destroy method
26127			this.$super.destroy.apply(this, arguments);
26128		};
26129		return Controller;
26130	});
26131
26132	/*
26133 	 * ----------------------------------------------------------------
26134 	 * Internal class for the construction of Indicators
26135 	 * ----------------------------------------------------------------
26136 	 */
26137	var Indicator = function (Scene, options) {
26138		var Indicator = this,
26139		    _elemBounds = TPL.bounds(),
26140		    _elemStart = TPL.start(options.colorStart),
26141		    _elemEnd = TPL.end(options.colorEnd),
26142		    _boundsContainer = options.parent && _util.get.elements(options.parent)[0],
26143		    _vertical,
26144		    _ctrl;
26145
26146		var log = function () {
26147			if (Scene._log) {
26148				// not available, when main source minified
26149				Array.prototype.splice.call(arguments, 1, 0, "(" + NAMESPACE + ")", "->");
26150				Scene._log.apply(this, arguments);
26151			}
26152		};
26153
26154		options.name = options.name || _autoindex;
26155
26156		// prepare bounds elements
26157		_elemStart.firstChild.textContent += " " + options.name;
26158		_elemEnd.textContent += " " + options.name;
26159		_elemBounds.appendChild(_elemStart);
26160		_elemBounds.appendChild(_elemEnd);
26161
26162		// set public variables
26163		Indicator.options = options;
26164		Indicator.bounds = _elemBounds;
26165		// will be set later
26166		Indicator.triggerGroup = undefined;
26167
26168		// add indicators to DOM
26169		this.add = function () {
26170			_ctrl = Scene.controller();
26171			_vertical = _ctrl.info("vertical");
26172
26173			var isDocument = _ctrl.info("isDocument");
26174
26175			if (!_boundsContainer) {
26176				// no parent supplied or doesnt exist
26177				_boundsContainer = isDocument ? document.body : _ctrl.info("container"); // check if window/document (then use body)
26178			}
26179			if (!isDocument && _util.css(_boundsContainer, "position") === 'static') {
26180				// position mode needed for correct positioning of indicators
26181				_util.css(_boundsContainer, {
26182					position: "relative"
26183				});
26184			}
26185
26186			// add listeners for updates
26187			Scene.on("change.plugin_addIndicators", handleTriggerParamsChange);
26188			Scene.on("shift.plugin_addIndicators", handleBoundsParamsChange);
26189
26190			// updates trigger & bounds (will add elements if needed)
26191			updateTriggerGroup();
26192			updateBounds();
26193
26194			setTimeout(function () {
26195				// do after all execution is finished otherwise sometimes size calculations are off
26196				_ctrl._indicators.updateBoundsPositions(Indicator);
26197			}, 0);
26198
26199			log(3, "added indicators");
26200		};
26201
26202		// remove indicators from DOM
26203		this.remove = function () {
26204			if (Indicator.triggerGroup) {
26205				// if not set there's nothing to remove
26206				Scene.off("change.plugin_addIndicators", handleTriggerParamsChange);
26207				Scene.off("shift.plugin_addIndicators", handleBoundsParamsChange);
26208
26209				if (Indicator.triggerGroup.members.length > 1) {
26210					// just remove from memberlist of old group
26211					var group = Indicator.triggerGroup;
26212					group.members.splice(group.members.indexOf(Indicator), 1);
26213					_ctrl._indicators.updateTriggerGroupLabel(group);
26214					_ctrl._indicators.updateTriggerGroupPositions(group);
26215					Indicator.triggerGroup = undefined;
26216				} else {
26217					// remove complete group
26218					removeTriggerGroup();
26219				}
26220				removeBounds();
26221
26222				log(3, "removed indicators");
26223			}
26224		};
26225
26226		/*
26227  		 * ----------------------------------------------------------------
26228  		 * internal Event Handlers
26229  		 * ----------------------------------------------------------------
26230  		 */
26231
26232		// event handler for when bounds params change
26233		var handleBoundsParamsChange = function () {
26234			updateBounds();
26235		};
26236
26237		// event handler for when trigger params change
26238		var handleTriggerParamsChange = function (e) {
26239			if (e.what === "triggerHook") {
26240				updateTriggerGroup();
26241			}
26242		};
26243
26244		/*
26245  		 * ----------------------------------------------------------------
26246  		 * Bounds (start / stop) management
26247  		 * ----------------------------------------------------------------
26248  		 */
26249
26250		// adds an new bounds elements to the array and to the DOM
26251		var addBounds = function () {
26252			var v = _ctrl.info("vertical");
26253			// apply stuff we didn't know before...
26254			_util.css(_elemStart.firstChild, {
26255				"border-bottom-width": v ? 1 : 0,
26256				"border-right-width": v ? 0 : 1,
26257				"bottom": v ? -1 : options.indent,
26258				"right": v ? options.indent : -1,
26259				"padding": v ? "0 8px" : "2px 4px"
26260			});
26261			_util.css(_elemEnd, {
26262				"border-top-width": v ? 1 : 0,
26263				"border-left-width": v ? 0 : 1,
26264				"top": v ? "100%" : "",
26265				"right": v ? options.indent : "",
26266				"bottom": v ? "" : options.indent,
26267				"left": v ? "" : "100%",
26268				"padding": v ? "0 8px" : "2px 4px"
26269			});
26270			// append
26271			_boundsContainer.appendChild(_elemBounds);
26272		};
26273
26274		// remove bounds from list and DOM
26275		var removeBounds = function () {
26276			_elemBounds.parentNode.removeChild(_elemBounds);
26277		};
26278
26279		// update the start and end positions of the scene
26280		var updateBounds = function () {
26281			if (_elemBounds.parentNode !== _boundsContainer) {
26282				addBounds(); // Add Bounds elements (start/end)
26283			}
26284			var css = {};
26285			css[_vertical ? "top" : "left"] = Scene.triggerPosition();
26286			css[_vertical ? "height" : "width"] = Scene.duration();
26287			_util.css(_elemBounds, css);
26288			_util.css(_elemEnd, {
26289				display: Scene.duration() > 0 ? "" : "none"
26290			});
26291		};
26292
26293		/*
26294  		 * ----------------------------------------------------------------
26295  		 * trigger and trigger group management
26296  		 * ----------------------------------------------------------------
26297  		 */
26298
26299		// adds an new trigger group to the array and to the DOM
26300		var addTriggerGroup = function () {
26301			var triggerElem = TPL.trigger(options.colorTrigger); // new trigger element
26302			var css = {};
26303			css[_vertical ? "right" : "bottom"] = 0;
26304			css[_vertical ? "border-top-width" : "border-left-width"] = 1;
26305			_util.css(triggerElem.firstChild, css);
26306			_util.css(triggerElem.firstChild.firstChild, {
26307				padding: _vertical ? "0 8px 3px 8px" : "3px 4px"
26308			});
26309			document.body.appendChild(triggerElem); // directly add to body
26310			var newGroup = {
26311				triggerHook: Scene.triggerHook(),
26312				element: triggerElem,
26313				members: [Indicator]
26314			};
26315			_ctrl._indicators.groups.push(newGroup);
26316			Indicator.triggerGroup = newGroup;
26317			// update right away
26318			_ctrl._indicators.updateTriggerGroupLabel(newGroup);
26319			_ctrl._indicators.updateTriggerGroupPositions(newGroup);
26320		};
26321
26322		var removeTriggerGroup = function () {
26323			_ctrl._indicators.groups.splice(_ctrl._indicators.groups.indexOf(Indicator.triggerGroup), 1);
26324			Indicator.triggerGroup.element.parentNode.removeChild(Indicator.triggerGroup.element);
26325			Indicator.triggerGroup = undefined;
26326		};
26327
26328		// updates the trigger group -> either join existing or add new one
26329		/*	
26330  		 * Logic:
26331  		 * 1 if a trigger group exist, check if it's in sync with Scene settings – if so, nothing else needs to happen
26332  		 * 2 try to find an existing one that matches Scene parameters
26333  		 * 	 2.1 If a match is found check if already assigned to an existing group
26334  		 *			 If so:
26335  		 *       A: it was the last member of existing group -> kill whole group
26336  		 *       B: the existing group has other members -> just remove from member list
26337  		 *	 2.2 Assign to matching group
26338  		 * 3 if no new match could be found, check if assigned to existing group
26339  		 *   A: yes, and it's the only member -> just update parameters and positions and keep using this group
26340  		 *   B: yes but there are other members -> remove from member list and create a new one
26341  		 *   C: no, so create a new one
26342  		 */
26343		var updateTriggerGroup = function () {
26344			var triggerHook = Scene.triggerHook(),
26345			    closeEnough = 0.0001;
26346
26347			// Have a group, check if it still matches
26348			if (Indicator.triggerGroup) {
26349				if (Math.abs(Indicator.triggerGroup.triggerHook - triggerHook) < closeEnough) {
26350					// _util.log(0, "trigger", options.name, "->", "no need to change, still in sync");
26351					return; // all good
26352				}
26353			}
26354			// Don't have a group, check if a matching one exists
26355			// _util.log(0, "trigger", options.name, "->", "out of sync!");
26356			var groups = _ctrl._indicators.groups,
26357			    group,
26358			    i = groups.length;
26359			while (i--) {
26360				group = groups[i];
26361				if (Math.abs(group.triggerHook - triggerHook) < closeEnough) {
26362					// found a match!
26363					// _util.log(0, "trigger", options.name, "->", "found match");
26364					if (Indicator.triggerGroup) {
26365						// do I have an old group that is out of sync?
26366						if (Indicator.triggerGroup.members.length === 1) {
26367							// is it the only remaining group?
26368							// _util.log(0, "trigger", options.name, "->", "kill");
26369							// was the last member, remove the whole group
26370							removeTriggerGroup();
26371						} else {
26372							Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group
26373							_ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup);
26374							_ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
26375							// _util.log(0, "trigger", options.name, "->", "removing from previous member list");
26376						}
26377					}
26378					// join new group
26379					group.members.push(Indicator);
26380					Indicator.triggerGroup = group;
26381					_ctrl._indicators.updateTriggerGroupLabel(group);
26382					return;
26383				}
26384			}
26385
26386			// at this point I am obviously out of sync and don't match any other group
26387			if (Indicator.triggerGroup) {
26388				if (Indicator.triggerGroup.members.length === 1) {
26389					// _util.log(0, "trigger", options.name, "->", "updating existing");
26390					// out of sync but i'm the only member => just change and update
26391					Indicator.triggerGroup.triggerHook = triggerHook;
26392					_ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
26393					return;
26394				} else {
26395					// _util.log(0, "trigger", options.name, "->", "removing from previous member list");
26396					Indicator.triggerGroup.members.splice(Indicator.triggerGroup.members.indexOf(Indicator), 1); // just remove from memberlist of old group
26397					_ctrl._indicators.updateTriggerGroupLabel(Indicator.triggerGroup);
26398					_ctrl._indicators.updateTriggerGroupPositions(Indicator.triggerGroup);
26399					Indicator.triggerGroup = undefined; // need a brand new group...
26400				}
26401			}
26402			// _util.log(0, "trigger", options.name, "->", "add a new one");
26403			// did not find any match, make new trigger group
26404			addTriggerGroup();
26405		};
26406	};
26407
26408	/*
26409 	 * ----------------------------------------------------------------
26410 	 * Templates for the indicators
26411 	 * ----------------------------------------------------------------
26412 	 */
26413	var TPL = {
26414		start: function (color) {
26415			// inner element (for bottom offset -1, while keeping top position 0)
26416			var inner = document.createElement("div");
26417			inner.textContent = "start";
26418			_util.css(inner, {
26419				position: "absolute",
26420				overflow: "visible",
26421				"border-width": 0,
26422				"border-style": "solid",
26423				color: color,
26424				"border-color": color
26425			});
26426			var e = document.createElement('div');
26427			// wrapper
26428			_util.css(e, {
26429				position: "absolute",
26430				overflow: "visible",
26431				width: 0,
26432				height: 0
26433			});
26434			e.appendChild(inner);
26435			return e;
26436		},
26437		end: function (color) {
26438			var e = document.createElement('div');
26439			e.textContent = "end";
26440			_util.css(e, {
26441				position: "absolute",
26442				overflow: "visible",
26443				"border-width": 0,
26444				"border-style": "solid",
26445				color: color,
26446				"border-color": color
26447			});
26448			return e;
26449		},
26450		bounds: function () {
26451			var e = document.createElement('div');
26452			_util.css(e, {
26453				position: "absolute",
26454				overflow: "visible",
26455				"white-space": "nowrap",
26456				"pointer-events": "none",
26457				"font-size": FONT_SIZE
26458			});
26459			e.style.zIndex = ZINDEX;
26460			return e;
26461		},
26462		trigger: function (color) {
26463			// inner to be above or below line but keep position
26464			var inner = document.createElement('div');
26465			inner.textContent = "trigger";
26466			_util.css(inner, {
26467				position: "relative"
26468			});
26469			// inner wrapper for right: 0 and main element has no size
26470			var w = document.createElement('div');
26471			_util.css(w, {
26472				position: "absolute",
26473				overflow: "visible",
26474				"border-width": 0,
26475				"border-style": "solid",
26476				color: color,
26477				"border-color": color
26478			});
26479			w.appendChild(inner);
26480			// wrapper
26481			var e = document.createElement('div');
26482			_util.css(e, {
26483				position: "fixed",
26484				overflow: "visible",
26485				"white-space": "nowrap",
26486				"pointer-events": "none",
26487				"font-size": FONT_SIZE
26488			});
26489			e.style.zIndex = ZINDEX;
26490			e.appendChild(w);
26491			return e;
26492		}
26493	};
26494});
26495
26496/***/ }),
26497/* 23 */
26498/***/ (function(module, exports, __webpack_require__) {
26499
26500/* WEBPACK VAR INJECTION */(function(global) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
26501 * VERSION: 1.20.3
26502 * DATE: 2017-10-02
26503 * UPDATES AND DOCS AT: http://greensock.com
26504 *
26505 * @license Copyright (c) 2008-2017, GreenSock. All rights reserved.
26506 * This work is subject to the terms at http://greensock.com/standard-license or for
26507 * Club GreenSock members, the software agreement that was issued with your membership.
26508 * 
26509 * @author: Jack Doyle, [email protected]
26510 */
26511var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : this || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node
26512(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () {
26513
26514	"use strict";
26515
26516	_gsScope._gsDefine("TimelineLite", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) {
26517
26518		var TimelineLite = function (vars) {
26519			SimpleTimeline.call(this, vars);
26520			this._labels = {};
26521			this.autoRemoveChildren = this.vars.autoRemoveChildren === true;
26522			this.smoothChildTiming = this.vars.smoothChildTiming === true;
26523			this._sortChildren = true;
26524			this._onUpdate = this.vars.onUpdate;
26525			var v = this.vars,
26526			    val,
26527			    p;
26528			for (p in v) {
26529				val = v[p];
26530				if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) {
26531					v[p] = this._swapSelfInParams(val);
26532				}
26533			}
26534			if (_isArray(v.tweens)) {
26535				this.add(v.tweens, 0, v.align, v.stagger);
26536			}
26537		},
26538		    _tinyNum = 0.0000000001,
26539		    TweenLiteInternals = TweenLite._internals,
26540		    _internals = TimelineLite._internals = {},
26541		    _isSelector = TweenLiteInternals.isSelector,
26542		    _isArray = TweenLiteInternals.isArray,
26543		    _lazyTweens = TweenLiteInternals.lazyTweens,
26544		    _lazyRender = TweenLiteInternals.lazyRender,
26545		    _globals = _gsScope._gsDefine.globals,
26546		    _copy = function (vars) {
26547			var copy = {},
26548			    p;
26549			for (p in vars) {
26550				copy[p] = vars[p];
26551			}
26552			return copy;
26553		},
26554		    _applyCycle = function (vars, targets, i) {
26555			var alt = vars.cycle,
26556			    p,
26557			    val;
26558			for (p in alt) {
26559				val = alt[p];
26560				vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length];
26561			}
26562			delete vars.cycle;
26563		},
26564		    _pauseCallback = _internals.pauseCallback = function () {},
26565		    _slice = function (a) {
26566			//don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
26567			var b = [],
26568			    l = a.length,
26569			    i;
26570			for (i = 0; i !== l; b.push(a[i++]));
26571			return b;
26572		},
26573		    p = TimelineLite.prototype = new SimpleTimeline();
26574
26575		TimelineLite.version = "1.20.3";
26576		p.constructor = TimelineLite;
26577		p.kill()._gc = p._forcingPlayhead = p._hasPause = false;
26578
26579		/* might use later...
26580  //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales.
26581  function localToGlobal(time, animation) {
26582  	while (animation) {
26583  		time = (time / animation._timeScale) + animation._startTime;
26584  		animation = animation.timeline;
26585  	}
26586  	return time;
26587  }
26588  	//translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales
26589  function globalToLocal(time, animation) {
26590  	var scale = 1;
26591  	time -= localToGlobal(0, animation);
26592  	while (animation) {
26593  		scale *= animation._timeScale;
26594  		animation = animation.timeline;
26595  	}
26596  	return time * scale;
26597  }
26598  */
26599
26600		p.to = function (target, duration, vars, position) {
26601			var Engine = vars.repeat && _globals.TweenMax || TweenLite;
26602			return duration ? this.add(new Engine(target, duration, vars), position) : this.set(target, vars, position);
26603		};
26604
26605		p.from = function (target, duration, vars, position) {
26606			return this.add((vars.repeat && _globals.TweenMax || TweenLite).from(target, duration, vars), position);
26607		};
26608
26609		p.fromTo = function (target, duration, fromVars, toVars, position) {
26610			var Engine = toVars.repeat && _globals.TweenMax || TweenLite;
26611			return duration ? this.add(Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position);
26612		};
26613
26614		p.staggerTo = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
26615			var tl = new TimelineLite({ onComplete: onCompleteAll, onCompleteParams: onCompleteAllParams, callbackScope: onCompleteAllScope, smoothChildTiming: this.smoothChildTiming }),
26616			    cycle = vars.cycle,
26617			    copy,
26618			    i;
26619			if (typeof targets === "string") {
26620				targets = TweenLite.selector(targets) || targets;
26621			}
26622			targets = targets || [];
26623			if (_isSelector(targets)) {
26624				//senses if the targets object is a selector. If it is, we should translate it into an array.
26625				targets = _slice(targets);
26626			}
26627			stagger = stagger || 0;
26628			if (stagger < 0) {
26629				targets = _slice(targets);
26630				targets.reverse();
26631				stagger *= -1;
26632			}
26633			for (i = 0; i < targets.length; i++) {
26634				copy = _copy(vars);
26635				if (copy.startAt) {
26636					copy.startAt = _copy(copy.startAt);
26637					if (copy.startAt.cycle) {
26638						_applyCycle(copy.startAt, targets, i);
26639					}
26640				}
26641				if (cycle) {
26642					_applyCycle(copy, targets, i);
26643					if (copy.duration != null) {
26644						duration = copy.duration;
26645						delete copy.duration;
26646					}
26647				}
26648				tl.to(targets[i], duration, copy, i * stagger);
26649			}
26650			return this.add(tl, position);
26651		};
26652
26653		p.staggerFrom = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
26654			vars.immediateRender = vars.immediateRender != false;
26655			vars.runBackwards = true;
26656			return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
26657		};
26658
26659		p.staggerFromTo = function (targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
26660			toVars.startAt = fromVars;
26661			toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
26662			return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
26663		};
26664
26665		p.call = function (callback, params, scope, position) {
26666			return this.add(TweenLite.delayedCall(0, callback, params, scope), position);
26667		};
26668
26669		p.set = function (target, vars, position) {
26670			position = this._parseTimeOrLabel(position, 0, true);
26671			if (vars.immediateRender == null) {
26672				vars.immediateRender = position === this._time && !this._paused;
26673			}
26674			return this.add(new TweenLite(target, 0, vars), position);
26675		};
26676
26677		TimelineLite.exportRoot = function (vars, ignoreDelayedCalls) {
26678			vars = vars || {};
26679			if (vars.smoothChildTiming == null) {
26680				vars.smoothChildTiming = true;
26681			}
26682			var tl = new TimelineLite(vars),
26683			    root = tl._timeline,
26684			    hasNegativeStart,
26685			    time,
26686			    tween,
26687			    next;
26688			if (ignoreDelayedCalls == null) {
26689				ignoreDelayedCalls = true;
26690			}
26691			root._remove(tl, true);
26692			tl._startTime = 0;
26693			tl._rawPrevTime = tl._time = tl._totalTime = root._time;
26694			tween = root._first;
26695			while (tween) {
26696				next = tween._next;
26697				if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) {
26698					time = tween._startTime - tween._delay;
26699					if (time < 0) {
26700						hasNegativeStart = 1;
26701					}
26702					tl.add(tween, time);
26703				}
26704				tween = next;
26705			}
26706			root.add(tl, 0);
26707			if (hasNegativeStart) {
26708				//calling totalDuration() will force the adjustment necessary to shift the children forward so none of them start before zero, and moves the timeline backwards the same amount, so the playhead is still aligned where it should be globally, but the timeline doesn't have illegal children that start before zero.
26709				tl.totalDuration();
26710			}
26711			return tl;
26712		};
26713
26714		p.add = function (value, position, align, stagger) {
26715			var curTime, l, i, child, tl, beforeRawTime;
26716			if (typeof position !== "number") {
26717				position = this._parseTimeOrLabel(position, 0, true, value);
26718			}
26719			if (!(value instanceof Animation)) {
26720				if (value instanceof Array || value && value.push && _isArray(value)) {
26721					align = align || "normal";
26722					stagger = stagger || 0;
26723					curTime = position;
26724					l = value.length;
26725					for (i = 0; i < l; i++) {
26726						if (_isArray(child = value[i])) {
26727							child = new TimelineLite({ tweens: child });
26728						}
26729						this.add(child, curTime);
26730						if (typeof child !== "string" && typeof child !== "function") {
26731							if (align === "sequence") {
26732								curTime = child._startTime + child.totalDuration() / child._timeScale;
26733							} else if (align === "start") {
26734								child._startTime -= child.delay();
26735							}
26736						}
26737						curTime += stagger;
26738					}
26739					return this._uncache(true);
26740				} else if (typeof value === "string") {
26741					return this.addLabel(value, position);
26742				} else if (typeof value === "function") {
26743					value = TweenLite.delayedCall(0, value);
26744				} else {
26745					throw "Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string.";
26746				}
26747			}
26748
26749			SimpleTimeline.prototype.add.call(this, value, position);
26750
26751			if (value._time) {
26752				//in case, for example, the _startTime is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning.
26753				value.render((this.rawTime() - value._startTime) * value._timeScale, false, false);
26754			}
26755
26756			//if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate.
26757			if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) {
26758				//in case any of the ancestors had completed but should now be enabled...
26759				tl = this;
26760				beforeRawTime = tl.rawTime() > value._startTime; //if the tween is placed on the timeline so that it starts BEFORE the current rawTime, we should align the playhead (move the timeline). This is because sometimes users will create a timeline, let it finish, and much later append a tween and expect it to run instead of jumping to its end state. While technically one could argue that it should jump to its end state, that's not what users intuitively expect.
26761				while (tl._timeline) {
26762					if (beforeRawTime && tl._timeline.smoothChildTiming) {
26763						tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it.
26764					} else if (tl._gc) {
26765						tl._enabled(true, false);
26766					}
26767					tl = tl._timeline;
26768				}
26769			}
26770
26771			return this;
26772		};
26773
26774		p.remove = function (value) {
26775			if (value instanceof Animation) {
26776				this._remove(value, false);
26777				var tl = value._timeline = value.vars.useFrames ? Animation._rootFramesTimeline : Animation._rootTimeline; //now that it's removed, default it to the root timeline so that if it gets played again, it doesn't jump back into this timeline.
26778				value._startTime = (value._paused ? value._pauseTime : tl._time) - (!value._reversed ? value._totalTime : value.totalDuration() - value._totalTime) / value._timeScale; //ensure that if it gets played again, the timing is correct.
26779				return this;
26780			} else if (value instanceof Array || value && value.push && _isArray(value)) {
26781				var i = value.length;
26782				while (--i > -1) {
26783					this.remove(value[i]);
26784				}
26785				return this;
26786			} else if (typeof value === "string") {
26787				return this.removeLabel(value);
26788			}
26789			return this.kill(null, value);
26790		};
26791
26792		p._remove = function (tween, skipDisable) {
26793			SimpleTimeline.prototype._remove.call(this, tween, skipDisable);
26794			var last = this._last;
26795			if (!last) {
26796				this._time = this._totalTime = this._duration = this._totalDuration = 0;
26797			} else if (this._time > this.duration()) {
26798				this._time = this._duration;
26799				this._totalTime = this._totalDuration;
26800			}
26801			return this;
26802		};
26803
26804		p.append = function (value, offsetOrLabel) {
26805			return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value));
26806		};
26807
26808		p.insert = p.insertMultiple = function (value, position, align, stagger) {
26809			return this.add(value, position || 0, align, stagger);
26810		};
26811
26812		p.appendMultiple = function (tweens, offsetOrLabel, align, stagger) {
26813			return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger);
26814		};
26815
26816		p.addLabel = function (label, position) {
26817			this._labels[label] = this._parseTimeOrLabel(position);
26818			return this;
26819		};
26820
26821		p.addPause = function (position, callback, params, scope) {
26822			var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this);
26823			t.vars.onComplete = t.vars.onReverseComplete = callback;
26824			t.data = "isPause";
26825			this._hasPause = true;
26826			return this.add(t, position);
26827		};
26828
26829		p.removeLabel = function (label) {
26830			delete this._labels[label];
26831			return this;
26832		};
26833
26834		p.getLabelTime = function (label) {
26835			return this._labels[label] != null ? this._labels[label] : -1;
26836		};
26837
26838		p._parseTimeOrLabel = function (timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) {
26839			var clippedDuration, i;
26840			//if we're about to add a tween/timeline (or an array of them) that's already a child of this timeline, we should remove it first so that it doesn't contaminate the duration().
26841			if (ignore instanceof Animation && ignore.timeline === this) {
26842				this.remove(ignore);
26843			} else if (ignore && (ignore instanceof Array || ignore.push && _isArray(ignore))) {
26844				i = ignore.length;
26845				while (--i > -1) {
26846					if (ignore[i] instanceof Animation && ignore[i].timeline === this) {
26847						this.remove(ignore[i]);
26848					}
26849				}
26850			}
26851			clippedDuration = typeof timeOrLabel === "number" && !offsetOrLabel ? 0 : this.duration() > 99999999999 ? this.recent().endTime(false) : this._duration; //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead.
26852			if (typeof offsetOrLabel === "string") {
26853				return this._parseTimeOrLabel(offsetOrLabel, appendIfAbsent && typeof timeOrLabel === "number" && this._labels[offsetOrLabel] == null ? timeOrLabel - clippedDuration : 0, appendIfAbsent);
26854			}
26855			offsetOrLabel = offsetOrLabel || 0;
26856			if (typeof timeOrLabel === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) {
26857				//if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value).
26858				i = timeOrLabel.indexOf("=");
26859				if (i === -1) {
26860					if (this._labels[timeOrLabel] == null) {
26861						return appendIfAbsent ? this._labels[timeOrLabel] = clippedDuration + offsetOrLabel : offsetOrLabel;
26862					}
26863					return this._labels[timeOrLabel] + offsetOrLabel;
26864				}
26865				offsetOrLabel = parseInt(timeOrLabel.charAt(i - 1) + "1", 10) * Number(timeOrLabel.substr(i + 1));
26866				timeOrLabel = i > 1 ? this._parseTimeOrLabel(timeOrLabel.substr(0, i - 1), 0, appendIfAbsent) : clippedDuration;
26867			} else if (timeOrLabel == null) {
26868				timeOrLabel = clippedDuration;
26869			}
26870			return Number(timeOrLabel) + offsetOrLabel;
26871		};
26872
26873		p.seek = function (position, suppressEvents) {
26874			return this.totalTime(typeof position === "number" ? position : this._parseTimeOrLabel(position), suppressEvents !== false);
26875		};
26876
26877		p.stop = function () {
26878			return this.paused(true);
26879		};
26880
26881		p.gotoAndPlay = function (position, suppressEvents) {
26882			return this.play(position, suppressEvents);
26883		};
26884
26885		p.gotoAndStop = function (position, suppressEvents) {
26886			return this.pause(position, suppressEvents);
26887		};
26888
26889		p.render = function (time, suppressEvents, force) {
26890			if (this._gc) {
26891				this._enabled(true, false);
26892			}
26893			var prevTime = this._time,
26894			    totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
26895			    prevStart = this._startTime,
26896			    prevTimeScale = this._timeScale,
26897			    prevPaused = this._paused,
26898			    tween,
26899			    isComplete,
26900			    next,
26901			    callback,
26902			    internalForce,
26903			    pauseTween,
26904			    curTime;
26905			if (prevTime !== this._time) {
26906				//if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump).
26907				time += this._time - prevTime;
26908			}
26909			if (time >= totalDur - 0.0000001 && time >= 0) {
26910				//to work around occasional floating point math artifacts.
26911				this._totalTime = this._time = totalDur;
26912				if (!this._reversed) if (!this._hasPausedChild()) {
26913					isComplete = true;
26914					callback = "onComplete";
26915					internalForce = !!this._timeline.autoRemoveChildren; //otherwise, if the animation is unpaused/activated after it's already finished, it doesn't get removed from the parent timeline.
26916					if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) {
26917						internalForce = true;
26918						if (this._rawPrevTime > _tinyNum) {
26919							callback = "onReverseComplete";
26920						}
26921					}
26922				}
26923				this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
26924				time = totalDur + 0.0001; //to avoid occasional floating point rounding errors - sometimes child tweens/timelines were not being fully completed (their progress might be 0.999999999999998 instead of 1 because when _time - tween._startTime is performed, floating point errors would return a value that was SLIGHTLY off). Try (999999999999.7 - 999999999999) * 1 = 0.699951171875 instead of 0.7.
26925			} else if (time < 0.0000001) {
26926				//to work around occasional floating point math artifacts, round super small values to 0.
26927				this._totalTime = this._time = 0;
26928				if (prevTime !== 0 || this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || time < 0 && this._rawPrevTime >= 0)) {
26929					callback = "onReverseComplete";
26930					isComplete = this._reversed;
26931				}
26932				if (time < 0) {
26933					this._active = false;
26934					if (this._timeline.autoRemoveChildren && this._reversed) {
26935						//ensures proper GC if a timeline is resumed after it's finished reversing.
26936						internalForce = isComplete = true;
26937						callback = "onReverseComplete";
26938					} else if (this._rawPrevTime >= 0 && this._first) {
26939						//when going back beyond the start, force a render so that zero-duration tweens that sit at the very beginning render their start values properly. Otherwise, if the parent timeline's playhead lands exactly at this timeline's startTime, and then moves backwards, the zero-duration tweens at the beginning would still be at their end state.
26940						internalForce = true;
26941					}
26942					this._rawPrevTime = time;
26943				} else {
26944					this._rawPrevTime = this._duration || !suppressEvents || time || this._rawPrevTime === time ? time : _tinyNum; //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline or tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. We set the _rawPrevTime to be a precise tiny number to indicate this scenario rather than using another property/variable which would increase memory usage. This technique is less readable, but more efficient.
26945					if (time === 0 && isComplete) {
26946						//if there's a zero-duration tween at the very beginning of a timeline and the playhead lands EXACTLY at time 0, that tween will correctly render its end values, but we need to keep the timeline alive for one more render so that the beginning values render properly as the parent's playhead keeps moving beyond the begining. Imagine obj.x starts at 0 and then we do tl.set(obj, {x:100}).to(obj, 1, {x:200}) and then later we tl.reverse()...the goal is to have obj.x revert to 0. If the playhead happens to land on exactly 0, without this chunk of code, it'd complete the timeline and remove it from the rendering queue (not good).
26947						tween = this._first;
26948						while (tween && tween._startTime === 0) {
26949							if (!tween._duration) {
26950								isComplete = false;
26951							}
26952							tween = tween._next;
26953						}
26954					}
26955					time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
26956					if (!this._initted) {
26957						internalForce = true;
26958					}
26959				}
26960			} else {
26961
26962				if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
26963					if (time >= prevTime) {
26964						tween = this._first;
26965						while (tween && tween._startTime <= time && !pauseTween) {
26966							if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
26967								pauseTween = tween;
26968							}
26969							tween = tween._next;
26970						}
26971					} else {
26972						tween = this._last;
26973						while (tween && tween._startTime >= time && !pauseTween) {
26974							if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
26975								pauseTween = tween;
26976							}
26977							tween = tween._prev;
26978						}
26979					}
26980					if (pauseTween) {
26981						this._time = time = pauseTween._startTime;
26982						this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay);
26983					}
26984				}
26985
26986				this._totalTime = this._time = this._rawPrevTime = time;
26987			}
26988			if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
26989				return;
26990			} else if (!this._initted) {
26991				this._initted = true;
26992			}
26993
26994			if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) {
26995				this._active = true; //so that if the user renders the timeline (as opposed to the parent timeline rendering it), it is forced to re-render and align it with the proper time/frame on the next rendering cycle. Maybe the timeline already finished but the user manually re-renders it as halfway done, for example.
26996			}
26997
26998			if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) {
26999				this._callback("onStart");
27000			}
27001
27002			curTime = this._time;
27003			if (curTime >= prevTime) {
27004				tween = this._first;
27005				while (tween) {
27006					next = tween._next; //record it here because the value could change after rendering...
27007					if (curTime !== this._time || this._paused && !prevPaused) {
27008						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
27009						break;
27010					} else if (tween._active || tween._startTime <= curTime && !tween._paused && !tween._gc) {
27011						if (pauseTween === tween) {
27012							this.pause();
27013						}
27014						if (!tween._reversed) {
27015							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
27016						} else {
27017							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
27018						}
27019					}
27020					tween = next;
27021				}
27022			} else {
27023				tween = this._last;
27024				while (tween) {
27025					next = tween._prev; //record it here because the value could change after rendering...
27026					if (curTime !== this._time || this._paused && !prevPaused) {
27027						//in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
27028						break;
27029					} else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) {
27030						if (pauseTween === tween) {
27031							pauseTween = tween._prev; //the linked list is organized by _startTime, thus it's possible that a tween could start BEFORE the pause and end after it, in which case it would be positioned before the pause tween in the linked list, but we should render it before we pause() the timeline and cease rendering. This is only a concern when going in reverse.
27032							while (pauseTween && pauseTween.endTime() > this._time) {
27033								pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force);
27034								pauseTween = pauseTween._prev;
27035							}
27036							pauseTween = null;
27037							this.pause();
27038						}
27039						if (!tween._reversed) {
27040							tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
27041						} else {
27042							tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
27043						}
27044					}
27045					tween = next;
27046				}
27047			}
27048
27049			if (this._onUpdate) if (!suppressEvents) {
27050				if (_lazyTweens.length) {
27051					//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values.
27052					_lazyRender();
27053				}
27054				this._callback("onUpdate");
27055			}
27056
27057			if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) {
27058				//if one of the tweens that was rendered altered this timeline's startTime (like if an onComplete reversed the timeline), it probably isn't complete. If it is, don't worry, because whatever call altered the startTime would complete if it was necessary at the new time. The only exception is the timeScale property. Also check _gc because there's a chance that kill() could be called in an onUpdate
27059				if (isComplete) {
27060					if (_lazyTweens.length) {
27061						//in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onComplete on a timeline that reports/checks tweened values.
27062						_lazyRender();
27063					}
27064					if (this._timeline.autoRemoveChildren) {
27065						this._enabled(false, false);
27066					}
27067					this._active = false;
27068				}
27069				if (!suppressEvents && this.vars[callback]) {
27070					this._callback(callback);
27071				}
27072			}
27073		};
27074
27075		p._hasPausedChild = function () {
27076			var tween = this._first;
27077			while (tween) {
27078				if (tween._paused || tween instanceof TimelineLite && tween._hasPausedChild()) {
27079					return true;
27080				}
27081				tween = tween._next;
27082			}
27083			return false;
27084		};
27085
27086		p.getChildren = function (nested, tweens, timelines, ignoreBeforeTime) {
27087			ignoreBeforeTime = ignoreBeforeTime || -9999999999;
27088			var a = [],
27089			    tween = this._first,
27090			    cnt = 0;
27091			while (tween) {
27092				if (tween._startTime < ignoreBeforeTime) {
27093					//do nothing
27094				} else if (tween instanceof TweenLite) {
27095					if (tweens !== false) {
27096						a[cnt++] = tween;
27097					}
27098				} else {
27099					if (timelines !== false) {
27100						a[cnt++] = tween;
27101					}
27102					if (nested !== false) {
27103						a = a.concat(tween.getChildren(true, tweens, timelines));
27104						cnt = a.length;
27105					}
27106				}
27107				tween = tween._next;
27108			}
27109			return a;
27110		};
27111
27112		p.getTweensOf = function (target, nested) {
27113			var disabled = this._gc,
27114			    a = [],
27115			    cnt = 0,
27116			    tweens,
27117			    i;
27118			if (disabled) {
27119				this._enabled(true, true); //getTweensOf() filters out disabled tweens, and we have to mark them as _gc = true when the timeline completes in order to allow clean garbage collection, so temporarily re-enable the timeline here.
27120			}
27121			tweens = TweenLite.getTweensOf(target);
27122			i = tweens.length;
27123			while (--i > -1) {
27124				if (tweens[i].timeline === this || nested && this._contains(tweens[i])) {
27125					a[cnt++] = tweens[i];
27126				}
27127			}
27128			if (disabled) {
27129				this._enabled(false, true);
27130			}
27131			return a;
27132		};
27133
27134		p.recent = function () {
27135			return this._recent;
27136		};
27137
27138		p._contains = function (tween) {
27139			var tl = tween.timeline;
27140			while (tl) {
27141				if (tl === this) {
27142					return true;
27143				}
27144				tl = tl.timeline;
27145			}
27146			return false;
27147		};
27148
27149		p.shiftChildren = function (amount, adjustLabels, ignoreBeforeTime) {
27150			ignoreBeforeTime = ignoreBeforeTime || 0;
27151			var tween = this._first,
27152			    labels = this._labels,
27153			    p;
27154			while (tween) {
27155				if (tween._startTime >= ignoreBeforeTime) {
27156					tween._startTime += amount;
27157				}
27158				tween = tween._next;
27159			}
27160			if (adjustLabels) {
27161				for (p in labels) {
27162					if (labels[p] >= ignoreBeforeTime) {
27163						labels[p] += amount;
27164					}
27165				}
27166			}
27167			return this._uncache(true);
27168		};
27169
27170		p._kill = function (vars, target) {
27171			if (!vars && !target) {
27172				return this._enabled(false, false);
27173			}
27174			var tweens = !target ? this.getChildren(true, true, false) : this.getTweensOf(target),
27175			    i = tweens.length,
27176			    changed = false;
27177			while (--i > -1) {
27178				if (tweens[i]._kill(vars, target)) {
27179					changed = true;
27180				}
27181			}
27182			return changed;
27183		};
27184
27185		p.clear = function (labels) {
27186			var tweens = this.getChildren(false, true, true),
27187			    i = tweens.length;
27188			this._time = this._totalTime = 0;
27189			while (--i > -1) {
27190				tweens[i]._enabled(false, false);
27191			}
27192			if (labels !== false) {
27193				this._labels = {};
27194			}
27195			return this._uncache(true);
27196		};
27197
27198		p.invalidate = function () {
27199			var tween = this._first;
27200			while (tween) {
27201				tween.invalidate();
27202				tween = tween._next;
27203			}
27204			return Animation.prototype.invalidate.call(this);;
27205		};
27206
27207		p._enabled = function (enabled, ignoreTimeline) {
27208			if (enabled === this._gc) {
27209				var tween = this._first;
27210				while (tween) {
27211					tween._enabled(enabled, true);
27212					tween = tween._next;
27213				}
27214			}
27215			return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline);
27216		};
27217
27218		p.totalTime = function (time, suppressEvents, uncapped) {
27219			this._forcingPlayhead = true;
27220			var val = Animation.prototype.totalTime.apply(this, arguments);
27221			this._forcingPlayhead = false;
27222			return val;
27223		};
27224
27225		p.duration = function (value) {
27226			if (!arguments.length) {
27227				if (this._dirty) {
27228					this.totalDuration(); //just triggers recalculation
27229				}
27230				return this._duration;
27231			}
27232			if (this.duration() !== 0 && value !== 0) {
27233				this.timeScale(this._duration / value);
27234			}
27235			return this;
27236		};
27237
27238		p.totalDuration = function (value) {
27239			if (!arguments.length) {
27240				if (this._dirty) {
27241					var max = 0,
27242					    tween = this._last,
27243					    prevStart = 999999999999,
27244					    prev,
27245					    end;
27246					while (tween) {
27247						prev = tween._prev; //record it here in case the tween changes position in the sequence...
27248						if (tween._dirty) {
27249							tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it.
27250						}
27251						if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) {
27252							//in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence
27253							this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel().
27254							this.add(tween, tween._startTime - tween._delay);
27255							this._calculatingDuration = 0;
27256						} else {
27257							prevStart = tween._startTime;
27258						}
27259						if (tween._startTime < 0 && !tween._paused) {
27260							//children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.
27261							max -= tween._startTime;
27262							if (this._timeline.smoothChildTiming) {
27263								this._startTime += tween._startTime / this._timeScale;
27264								this._time -= tween._startTime;
27265								this._totalTime -= tween._startTime;
27266								this._rawPrevTime -= tween._startTime;
27267							}
27268							this.shiftChildren(-tween._startTime, false, -9999999999);
27269							prevStart = 0;
27270						}
27271						end = tween._startTime + tween._totalDuration / tween._timeScale;
27272						if (end > max) {
27273							max = end;
27274						}
27275						tween = prev;
27276					}
27277					this._duration = this._totalDuration = max;
27278					this._dirty = false;
27279				}
27280				return this._totalDuration;
27281			}
27282			return value && this.totalDuration() ? this.timeScale(this._totalDuration / value) : this;
27283		};
27284
27285		p.paused = function (value) {
27286			if (!value) {
27287				//if there's a pause directly at the spot from where we're unpausing, skip it.
27288				var tween = this._first,
27289				    time = this._time;
27290				while (tween) {
27291					if (tween._startTime === time && tween.data === "isPause") {
27292						tween._rawPrevTime = 0; //remember, _rawPrevTime is how zero-duration tweens/callbacks sense directionality and determine whether or not to fire. If _rawPrevTime is the same as _startTime on the next render, it won't fire.
27293					}
27294					tween = tween._next;
27295				}
27296			}
27297			return Animation.prototype.paused.apply(this, arguments);
27298		};
27299
27300		p.usesFrames = function () {
27301			var tl = this._timeline;
27302			while (tl._timeline) {
27303				tl = tl._timeline;
27304			}
27305			return tl === Animation._rootFramesTimeline;
27306		};
27307
27308		p.rawTime = function (wrapRepeats) {
27309			return wrapRepeats && (this._paused || this._repeat && this.time() > 0 && this.totalProgress() < 1) ? this._totalTime % (this._duration + this._repeatDelay) : this._paused ? this._totalTime : (this._timeline.rawTime(wrapRepeats) - this._startTime) * this._timeScale;
27310		};
27311
27312		return TimelineLite;
27313	}, true);
27314});if (_gsScope._gsDefine) {
27315	_gsScope._gsQueue.pop()();
27316}
27317
27318//export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date)
27319(function (name) {
27320	"use strict";
27321
27322	var getGlobal = function () {
27323		return (_gsScope.GreenSockGlobals || _gsScope)[name];
27324	};
27325	if (typeof module !== "undefined" && module.exports) {
27326		//node
27327		__webpack_require__(1); //dependency
27328		module.exports = getGlobal();
27329	} else if (true) {
27330		//AMD
27331		!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(1)], __WEBPACK_AMD_DEFINE_FACTORY__ = (getGlobal),
27332				__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
27333				(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
27334				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
27335	}
27336})("TimelineLite");
27337/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(5)))
27338
27339/***/ }),
27340/* 24 */,
27341/* 25 */,
27342/* 26 */,
27343/* 27 */,
27344/* 28 */,
27345/* 29 */,
27346/* 30 */,
27347/* 31 */,
27348/* 32 */,
27349/* 33 */,
27350/* 34 */,
27351/* 35 */,
27352/* 36 */,
27353/* 37 */,
27354/* 38 */,
27355/* 39 */,
27356/* 40 */,
27357/* 41 */,
27358/* 42 */
27359/***/ (function(module, __webpack_exports__, __webpack_require__) {
27360
27361"use strict";
27362Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
27363/* WEBPACK VAR INJECTION */(function($, ScrollMagic) {/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery__ = __webpack_require__(0);
27364/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_jquery___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_jquery__);
27365/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_scrollmagic__ = __webpack_require__(2);
27366/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_scrollmagic___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_scrollmagic__);
27367/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_animation__ = __webpack_require__(21);
27368/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_animation___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_2_animation__);
27369/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_debug_addIndicators__ = __webpack_require__(22);
27370/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3_debug_addIndicators___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3_debug_addIndicators__);
27371/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_TweenLite__ = __webpack_require__(1);
27372/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_TweenLite___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_4_TweenLite__);
27373/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_TweenMax__ = __webpack_require__(7);
27374/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5_TweenMax___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_5_TweenMax__);
27375/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_TimelineLite__ = __webpack_require__(23);
27376/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6_TimelineLite___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6_TimelineLite__);
27377/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_TimelineMax__ = __webpack_require__(8);
27378/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_TimelineMax___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_TimelineMax__);
27379/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__browser__ = __webpack_require__(6);
27380/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__maxin__ = __webpack_require__(9);
27381/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__base__ = __webpack_require__(10);
27382/* eslint no-loop-func: 0 */
27383/* eslint no-unused-vars: 0 */
27384/* eslint prefer-destructuring: ["off", {VariableDeclarator: {object: false}}] */
27385/* eslint no-lonely-if: "off" */
27386/* eslint max-len: ["error", { "code": 200 }] */
27387/* eslint no-undef: "off" */
27388/* eslint func-names: ["error", "never"] */
27389
27390/**
27391 * ------------------------------------------------------------------
27392 * 关于欣和 -
27393 * ------------------------------------------------------------------
27394 */
27395
27396/**
27397* @date     2017-10-30
27398* @author   Telliex<[email protected]>
27399*           Fish<[email protected]>
27400*/
27401
27402// import ScrollMagic from 'ScrollMagic';
27403
27404
27405
27406
27407
27408
27409
27410
27411
27412
27413
27414$(() => {
27415  let controller;
27416  let anchorController;
27417  let showStyle;
27418  let scrollStatus = 'show';
27419  let scrollMovingTimer;
27420  let anchorPin;
27421  // 所有瀏覽器判別值
27422  const GLOBAL_BROWSER_STAT = {};
27423
27424  let anchorSelected1;
27425  let anchorSelected2;
27426  let anchorSelected3;
27427  let anchorSelected4;
27428  let anchorSelected5;
27429  let anchorSelected6;
27430
27431  const scrollMovingEle = $('.about-scrollmoving-sticker');
27432  let scrollMovingAni;
27433
27434  const aboutOutline = '.about-outline';
27435  const aboutOutlineTitle = '.about-outline-title';
27436  const aboutOutlineGrahic = '.about-outline-grahic';
27437  const aboutOutlineContent = '.about-outline-content';
27438
27439  const aboutShinhoLogo = '.about-shinho-logo';
27440  const aboutShinhoLogoTitle = '.about-shinho-logo-title';
27441  const aboutShinhoLogoGrahic = '.about-shinho-logo-grahic';
27442  const aboutShinhoLogoBox = '.about-shinho-logo-box';
27443
27444  const aboutSlogan = '.about-slogan';
27445  const aboutSloganTitle = '.about-slogan-title';
27446  const aboutSloganContent = '.about-slogan-content';
27447
27448  const aboutPhilosophy = '.about-philosophy';
27449  const aboutPhilosophyTitle = '.about-philosophy-title';
27450  const aboutPhilosophyBox = '.about-philosophy-box';
27451  const aboutPhilosophyItem1 = '.about-philosophy-item:first-child';
27452  const aboutPhilosophyItem2 = '.about-philosophy-item:nth-child(2)';
27453  const aboutPhilosophyItem3 = '.about-philosophy-item:nth-child(3)';
27454  const aboutPhilosophyItem4 = '.about-philosophy-item:nth-child(4)';
27455  const aboutPhilosophyItemArti1 = '.about-philosophy-item:first-child .about-philosophy-article';
27456  const aboutPhilosophyItemArti2 = '.about-philosophy-item:nth-child(2) .about-philosophy-article';
27457  const aboutPhilosophyItemArti3 = '.about-philosophy-item:nth-child(3) .about-philosophy-article';
27458  const aboutPhilosophyItemArti4 = '.about-philosophy-item:nth-child(4) .about-philosophy-article';
27459  const aboutPhilosophySubtitle1 = '.about-philosophy-item:first-child .about-philosophy-subtitle';
27460  const aboutPhilosophySubtitle2 = '.about-philosophy-item:nth-child(2) .about-philosophy-subtitle';
27461  const aboutPhilosophySubtitle3 = '.about-philosophy-item:nth-child(3) .about-philosophy-subtitle';
27462  const aboutPhilosophySubtitle4 = '.about-philosophy-item:nth-child(4) .about-philosophy-subtitle';
27463  const aboutPhilosophyMoreBtn = '.about-philosophy-more-btn';
27464
27465  const aboutFoodeco = '.about-foodeco';
27466  const aboutFoodecoTitle = '.about-foodeco-title';
27467  const aboutFoodecoMain = '.about-foodeco-main';
27468  const aboutFoodecoGrahics = '.about-foodeco-grahics';
27469  const aboutFoodecoGrahicsBox = '.about-foodeco-grahics-box';
27470  const aboutFoodecoIntros = '.about-foodeco-intros';
27471  const aboutFoodecoGrahicsItems = '.about-foodeco-grahics-item';
27472  const aboutFoodecoGrahicsItem1 = '.about-foodeco-grahics-item:first-child';
27473  const aboutFoodecoGrahicsItem2 = '.about-foodeco-grahics-item:nth-child(2)';
27474  const aboutFoodecoGrahicsItem3 = '.about-foodeco-grahics-item:nth-child(3)';
27475  const aboutFoodecoGrahicsItem4 = '.about-foodeco-grahics-item:nth-child(4)';
27476  const aboutFoodecoGrahicsItem5 = '.about-foodeco-grahics-item:nth-child(5)';
27477  const aboutFoodecoGrahicsItem6 = '.about-foodeco-grahics-item:nth-child(6)';
27478  const aboutFoodecoGrahicsItem7 = '.about-foodeco-grahics-item:nth-child(7)';
27479  const aboutFoodecoBox = '.about-foodeco-box';
27480  const aboutFoodecoItem1 = '.about-foodeco-item:first-child';
27481  const aboutFoodecoItem2 = '.about-foodeco-item:nth-child(2)';
27482  const aboutFoodecoItem3 = '.about-foodeco-item:nth-child(3)';
27483  const aboutFoodecoItem4 = '.about-foodeco-item:nth-child(4)';
27484  const aboutFoodecoItem5 = '.about-foodeco-item:nth-child(5)';
27485  const aboutFoodecoItem6 = '.about-foodeco-item:nth-child(6)';
27486  const aboutFoodecoItem7 = '.about-foodeco-item:nth-child(7)';
27487  const aboutFoodecoMoreBtn = '.about-foodeco-more-btn';
27488
27489  const aboutWorldwideBranch = '.about-worldwidebranch';
27490  const aboutWorldwideBranchTitle = '.about-worldwidebranch-title';
27491  const aboutWorldwideBranchGrahic = '.about-worldwidebranch-grahic';
27492  const aboutWorldwideBranchGrahicImg = '.about-worldwidebranch-grahic-img';
27493  const aboutWorldwideBranchBox = '.about-worldwidebranch-box';
27494
27495  let aboutOutlineTitlePin;
27496  let aboutOutlineGrahicPin;
27497  let aboutOutlineGrahicAni;
27498  let aboutOutlineContentPin;
27499
27500  let aboutShinhoLogoTitlePin;
27501  let aboutShinhoLogoTitleAni;
27502  let aboutShinhoLogoGrahicPin;
27503  let aboutShinhoLogoGrahicAni;
27504  let aboutShinhoLogoBoxPin;
27505
27506  let aboutSloganTitlePin;
27507  let aboutSloganContentPin;
27508
27509  let aboutPhilosophyTitlePin;
27510  let aboutPhilosophyTitleAni;
27511  let aboutPhilosophyItemArti2Ani;
27512  let aboutPhilosophyItemArti3Ani;
27513  let aboutPhilosophyItemArti4Ani;
27514  let aboutPhilosophySubtitle1Pin;
27515  let aboutPhilosophySubtitle2Pin;
27516  let aboutPhilosophySubtitle3Pin;
27517  let aboutPhilosophySubtitle4Pin;
27518  let aboutPhilosophyBoxMask;
27519  let aboutPhilosophyMoreBtnAni;
27520  let aboutPhilosophySubtitle1Anchor;
27521  let aboutPhilosophySubtitle2Anchor;
27522  let aboutPhilosophySubtitle3Anchor;
27523  let aboutPhilosophySubtitle4Anchor;
27524
27525  let aboutFoodecoTitlePin;
27526  let aboutFoodecoTitleAni;
27527  let aboutFoodecoMainMask;
27528  let aboutFoodecoGrahicsPin;
27529  let aboutFoodecoGrahicsAni;
27530  let aboutFoodecoIntrosAni;
27531  let aboutFoodecoGrahicsItemsAni;
27532  let aboutFoodecoGrahicsItemsSelectClear;
27533  let aboutFoodecoGrahicsItem1Anchor;
27534  let aboutFoodecoGrahicsItem2Anchor;
27535  let aboutFoodecoGrahicsItem3Anchor;
27536  let aboutFoodecoGrahicsItem4Anchor;
27537  let aboutFoodecoGrahicsItem5Anchor;
27538  let aboutFoodecoGrahicsItem6Anchor;
27539  let aboutFoodecoGrahicsItem7Anchor;
27540  let aboutFoodecoMoreBtnAni;
27541
27542  let aboutWorldwideBranchTitlePin;
27543  let aboutWorldwideBranchTitleAni;
27544  let aboutWorldwideBranchGrahicPin;
27545  let aboutWorldwideBranchGrahicAni;
27546  let aboutWorldwideBranchBoxMask;
27547  let aboutWorldwideBranchBoxMaskAni;
27548
27549  function durationCount(boxEleA, triggerEleA, offset) {
27550    const boxEle = $(boxEleA);
27551    const triggerEle = $(triggerEleA);
27552    const eleDuration = boxEle.height() - (triggerEle.offset().top - boxEle.offset().top) + offset - 350;
27553    return eleDuration;
27554  }
27555
27556  function foodecoGrahicsItemsSelectClear(event) {
27557    if (event.type === 'enter') {
27558      $('.about-foodeco-grahics-item').removeClass('status-selected');
27559    } else {
27560      $('.about-foodeco-grahics-item').addClass('status-selected');
27561    }
27562  }
27563
27564  function aboutOutlineScrollMagic() {
27565    const aboutOutlineGrahicTween = TweenMax.to(aboutOutlineGrahic, 0.3, { x: 235, ease: Linear.easeNone });
27566
27567    aboutOutlineTitlePin = new ScrollMagic.Scene().triggerElement(aboutOutlineTitle).offset(-110).duration(durationCount(aboutOutline, aboutOutlineTitle, 60)).setPin(aboutOutlineTitle, { pushFollowers: false })
27568    // .addIndicators() // add indicators (requires plugin)
27569    .addTo(controller);
27570
27571    aboutOutlineGrahicPin = new ScrollMagic.Scene().triggerElement(aboutOutlineGrahic).offset(-370).duration(durationCount(aboutOutline, aboutOutlineGrahic, 320)).setPin(aboutOutlineGrahic, { pushFollowers: false })
27572    // .addIndicators() // add indicators (requires plugin)
27573    .addTo(controller);
27574
27575    aboutOutlineGrahicAni = new ScrollMagic.Scene().triggerElement(aboutOutlineGrahic).offset(-370).duration(200).setTween(aboutOutlineGrahicTween)
27576    // .addIndicators() // add indicators (requires plugin)
27577    .addTo(controller);
27578
27579    aboutOutlineContentPin = new ScrollMagic.Scene().triggerElement(aboutOutlineContent).offset(-370).duration(durationCount(aboutOutline, aboutOutlineContent, 320)).setPin(aboutOutlineContent, { pushFollowers: false })
27580    // .addIndicators() // add indicators (requires plugin)
27581    .addTo(controller);
27582  }
27583
27584  function aboutShinhoLogoScrollMagic() {
27585    const aboutShinhoLogoGrahicTween = TweenMax.to(aboutShinhoLogoGrahic, 0.3, { x: -312, ease: Linear.easeNone });
27586    const aboutShinhoLogoTitleTween = TweenMax.to(aboutShinhoLogoTitle, 0.3, { css: { scaleX: 0.6, scaleY: 0.6 }, ease: Linear.easeNone });
27587
27588    aboutShinhoLogoTitlePin = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoTitle).offset(-110).duration(durationCount(aboutShinhoLogo, aboutShinhoLogoTitle, 60)).setPin(aboutShinhoLogoTitle, { pushFollowers: false })
27589    // .addIndicators() // add indicators (requires plugin)
27590    .addTo(controller);
27591
27592    aboutShinhoLogoTitleAni = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoTitle).offset(-120).duration(150).setTween(aboutShinhoLogoTitleTween)
27593    // .addIndicators() // add indicators (requires plugin)
27594    .addTo(controller);
27595
27596    aboutShinhoLogoGrahicPin = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoGrahic).offset(-240).duration(durationCount(aboutShinhoLogo, aboutShinhoLogoGrahic, 180)).setPin(aboutShinhoLogoGrahic, { pushFollowers: false })
27597    // .addIndicators() // add indicators (requires plugin)
27598    .addTo(controller);
27599
27600    aboutShinhoLogoGrahicAni = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoGrahic).offset(-240).duration(200).setTween(aboutShinhoLogoGrahicTween)
27601    // .addIndicators() // add indicators (requires plugin)
27602    .addTo(controller);
27603
27604    aboutShinhoLogoBoxPin = new ScrollMagic.Scene().triggerElement(aboutShinhoLogoBox).offset(-240).duration(durationCount(aboutShinhoLogo, aboutShinhoLogoBox, 180)).setPin(aboutShinhoLogoBox, { pushFollowers: false })
27605    // .addIndicators() // add indicators (requires plugin)
27606    .addTo(controller);
27607  }
27608
27609  function aboutSloganScrollMagic() {
27610    aboutSloganTitlePin = new ScrollMagic.Scene().triggerElement(aboutSloganTitle).offset(-120).duration(durationCount(aboutSlogan, aboutSloganTitle, 60)).setPin(aboutSloganTitle, { pushFollowers: false })
27611    // .addIndicators() // add indicators (requires plugin)
27612    .addTo(controller);
27613
27614    aboutSloganContentPin = new ScrollMagic.Scene().triggerElement(aboutSloganContent).offset(-380).duration(durationCount(aboutSlogan, aboutSloganContent, 320)).setPin(aboutSloganContent, { pushFollowers: false })
27615    // .addIndicators() // add indicators (requires plugin)
27616    .addTo(controller);
27617  }
27618
27619  function aboutPhilosophyScrollMagic() {
27620    const aboutPhilosophyTitleTween = TweenMax.to(aboutPhilosophyTitle, 0.3, { css: { scaleX: 0.6, scaleY: 0.6 }, ease: Linear.easeNone });
27621    const aboutPhilosophyItemArti2Tween = TweenMax.to(aboutPhilosophyItemArti2, 0.3, { y: -175, ease: Linear.easeNone });
27622    const aboutPhilosophyItemArti3Tween = TweenMax.to(aboutPhilosophyItemArti3, 0.3, { y: -175, ease: Linear.easeNone });
27623    const aboutPhilosophyItemArti4Tween = TweenMax.to(aboutPhilosophyItemArti4, 0.3, { y: -175, ease: Linear.easeNone });
27624    const aboutPhilosophyMoreBtnTween = TweenMax.to(aboutPhilosophyMoreBtn, 0.3, { y: -100, ease: Linear.easeNone });
27625
27626    aboutPhilosophyTitlePin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyTitle).offset(-120).duration(durationCount(aboutPhilosophy, aboutPhilosophyTitle, -217)).setPin(aboutPhilosophyTitle, { pushFollowers: false })
27627    // .addIndicators() // add indicators (requires plugin)
27628    .addTo(controller);
27629
27630    aboutPhilosophyTitleAni = new ScrollMagic.Scene().triggerElement(aboutPhilosophyTitle).offset(-120).duration(150).setTween(aboutPhilosophyTitleTween)
27631    // .addIndicators() // add indicators (requires plugin)
27632    .addTo(controller);
27633
27634    aboutPhilosophySubtitle1Pin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophySubtitle1, -77)).setPin(aboutPhilosophySubtitle1, { pushFollowers: false })
27635    // .addIndicators() // add indicators (requires plugin)
27636    .addTo(controller);
27637
27638    aboutPhilosophySubtitle2Pin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophySubtitle2, -7)).setPin(aboutPhilosophySubtitle2, { pushFollowers: false })
27639    // .addIndicators() // add indicators (requires plugin)
27640    .addTo(controller);
27641
27642    aboutPhilosophySubtitle3Pin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophySubtitle3, 63)).setPin(aboutPhilosophySubtitle3, { pushFollowers: false })
27643    // .addIndicators() // add indicators (requires plugin)
27644    .addTo(controller);
27645
27646    aboutPhilosophySubtitle4Pin = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophySubtitle4, 133)).setPin(aboutPhilosophySubtitle4, { pushFollowers: false })
27647    // .addIndicators() // add indicators (requires plugin)
27648    .addTo(controller);
27649
27650    aboutPhilosophyBoxMask = new ScrollMagic.Scene().triggerElement(aboutPhilosophyBox).setClassToggle(aboutPhilosophyBox, 'status-mask').offset(-260).duration(durationCount(aboutPhilosophy, aboutPhilosophyBox, -40))
27651    // .addIndicators() // add indicators (requires plugin)
27652    .addTo(controller);
27653
27654    aboutPhilosophyItemArti2Ani = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItem2).offset(-864).duration(230).setTween(aboutPhilosophyItemArti2Tween)
27655    // .addIndicators() // add indicators (requires plugin)
27656    .addTo(controller);
27657
27658    aboutPhilosophyItemArti3Ani = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItem3).offset(-864).duration(230).setTween(aboutPhilosophyItemArti3Tween)
27659    // .addIndicators() // add indicators (requires plugin)
27660    .addTo(controller);
27661
27662    aboutPhilosophyItemArti4Ani = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItem4).offset(-864).duration(230).setTween(aboutPhilosophyItemArti4Tween)
27663    // .addIndicators() // add indicators (requires plugin)
27664    .addTo(controller);
27665
27666    aboutPhilosophyMoreBtnAni = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti3).duration(200).setTween(aboutPhilosophyMoreBtnTween)
27667    // .addIndicators() // add indicators (requires plugin)
27668    .addTo(controller);
27669
27670    aboutPhilosophySubtitle1Anchor = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti1).offset(-360).duration($('.about-philosophy-item:first-child').height() + 175).setClassToggle(aboutPhilosophyItem1, 'status-selected')
27671    // .addIndicators() // add indicators (requires plugin)
27672    .addTo(controller);
27673
27674    aboutPhilosophySubtitle2Anchor = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti2).offset(-360).duration($('.about-philosophy-item:nth-child(2)').height() + 175).setClassToggle(aboutPhilosophyItem2, 'status-selected')
27675    // .addIndicators() // add indicators (requires plugin)
27676    .addTo(controller);
27677
27678    aboutPhilosophySubtitle3Anchor = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti3).offset(-360).duration($('.about-philosophy-item:nth-child(3)').height() + 175).setClassToggle(aboutPhilosophyItem3, 'status-selected')
27679    // .addIndicators() // add indicators (requires plugin)
27680    .addTo(controller);
27681
27682    aboutPhilosophySubtitle4Anchor = new ScrollMagic.Scene().triggerElement(aboutPhilosophyItemArti4).offset(-360).duration($('.about-philosophy-item:nth-child(4)').height() + 175).setClassToggle(aboutPhilosophyItem4, 'status-selected')
27683    // .addIndicators() // add indicators (requires plugin)
27684    .addTo(controller);
27685  }
27686
27687  function aboutFoodecoSrollMagic() {
27688    const aboutFoodecoTitleTween = TweenMax.to(aboutFoodecoTitle, 0.3, { css: { scaleX: 0.6, scaleY: 0.6 }, ease: Linear.easeNone });
27689    const aboutFoodecoIntrosTimeline = new TimelineMax();
27690    // add a tween
27691    aboutFoodecoIntrosTimeline.add(TweenLite.to(aboutFoodecoIntros, 0, { opacity: 0 }));
27692    aboutFoodecoIntrosTimeline.add(TweenLite.to(aboutFoodecoIntros, 2, { opacity: 1 }));
27693    aboutFoodecoIntrosTimeline.add(TweenLite.to(aboutFoodecoIntros, 2, { opacity: 1 }));
27694    aboutFoodecoIntrosTimeline.add(TweenLite.to(aboutFoodecoIntros, 0.8, { opacity: 0 }));
27695
27696    const aboutFoodecoGrahicsItemsTween = TweenMax.to(aboutFoodecoGrahicsItems, 0.3, { css: { 'padding-bottom': '16%' }, ease: Power1.easeInOut });
27697    const aboutFoodecoGrahicsTween = TweenMax.to(aboutFoodecoGrahicsBox, 0.3, { x: -250, ease: Power1.easeInOut });
27698    const aboutFoodecoMoreBtnTween = TweenMax.from(aboutFoodecoMoreBtn, 0.3, { y: 100, ease: Linear.easeNone });
27699
27700    aboutFoodecoTitlePin = new ScrollMagic.Scene().triggerElement(aboutFoodecoTitle).offset(-120).duration(durationCount(aboutFoodeco, aboutFoodecoTitle, -160)).setPin(aboutFoodecoTitle, { pushFollowers: false })
27701    // .addIndicators() // add indicators (requires plugin)
27702    .addTo(controller);
27703
27704    aboutFoodecoTitleAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoTitle).offset(-120).duration(150).setTween(aboutFoodecoTitleTween)
27705    // .addIndicators() // add indicators (requires plugin)
27706    .addTo(controller);
27707
27708    aboutFoodecoMainMask = new ScrollMagic.Scene().triggerElement(aboutFoodecoTitle).setClassToggle(aboutFoodecoMain, 'status-mask').offset(-120).duration(durationCount(aboutFoodeco, aboutFoodecoTitle, -100))
27709    // .addIndicators() // add indicators (requires plugin)
27710    .addTo(controller);
27711
27712    aboutFoodecoGrahicsPin = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(-180).duration(durationCount(aboutFoodeco, aboutFoodecoGrahics, -100)).setPin(aboutFoodecoGrahics, { pushFollowers: false })
27713    // .addIndicators() // add indicators (requires plugin)
27714    .addTo(controller);
27715
27716    aboutFoodecoIntrosAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(-180).duration(300).setTween(aboutFoodecoIntrosTimeline)
27717    // .addIndicators() // add indicators (requires plugin)
27718    .addTo(controller);
27719
27720    aboutFoodecoGrahicsItemsAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(120).duration(200).setTween(aboutFoodecoGrahicsItemsTween)
27721    // .addIndicators() // add indicators (requires plugin)
27722    .addTo(controller);
27723
27724    aboutFoodecoGrahicsAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(320).duration(200).setTween(aboutFoodecoGrahicsTween)
27725    // .addIndicators() // add indicators (requires plugin)
27726    .addTo(controller);
27727
27728    aboutFoodecoGrahics
27728ItemsSelectClear = new ScrollMagic.Scene().triggerElement(aboutFoodecoGrahics).offset(520)
27729    // .addIndicators() // add indicators (requires plugin)
27730    .on('enter leave', foodecoGrahicsItemsSelectClear).addTo(controller);
27731
27732    aboutFoodecoGrahicsItem1Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem1).setClassToggle(aboutFoodecoGrahicsItem1, 'status-selected').duration(351).offset(-291)
27733    // .addIndicators() // add indicators (requires plugin)
27734    .addTo(controller);
27735
27736    aboutFoodecoGrahicsItem2Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem2).setClassToggle(aboutFoodecoGrahicsItem2, 'status-selected').duration(351).offset(-291)
27737    // .addIndicators() // add indicators (requires plugin)
27738    .addTo(controller);
27739
27740    aboutFoodecoGrahicsItem3Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem3).setClassToggle(aboutFoodecoGrahicsItem3, 'status-selected').duration(351).offset(-291)
27741    // .addIndicators() // add indicators (requires plugin)
27742    .addTo(controller);
27743
27744    aboutFoodecoGrahicsItem4Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem4).setClassToggle(aboutFoodecoGrahicsItem4, 'status-selected').duration(351).offset(-291)
27745    // .addIndicators() // add indicators (requires plugin)
27746    .addTo(controller);
27747
27748    aboutFoodecoGrahicsItem5Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem5).setClassToggle(aboutFoodecoGrahicsItem5, 'status-selected').duration(351).offset(-291)
27749    // .addIndicators() // add indicators (requires plugin)
27750    .addTo(controller);
27751
27752    aboutFoodecoGrahicsItem6Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem6).setClassToggle(aboutFoodecoGrahicsItem6, 'status-selected').duration(351).offset(-291)
27753    // .addIndicators() // add indicators (requires plugin)
27754    .addTo(controller);
27755
27756    aboutFoodecoGrahicsItem7Anchor = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem7).setClassToggle(aboutFoodecoGrahicsItem7, 'status-selected').duration(351).offset(-291)
27757    // .addIndicators() // add indicators (requires plugin)
27758    .addTo(controller);
27759
27760    aboutFoodecoMoreBtnAni = new ScrollMagic.Scene().triggerElement(aboutFoodecoItem6).offset(-70).duration(200).setTween(aboutFoodecoMoreBtnTween)
27761    // .addIndicators() // add indicators (requires plugin)
27762    .addTo(controller);
27763  }
27764
27765  function aboutWorldwideBranchScrollMagic() {
27766    const aboutWorldwideBranchGrahicTween = TweenMax.to(aboutWorldwideBranchGrahicImg, 0.5, { css: { width: '470px' }, ease: Linear.easeNone });
27767    const aboutWorldwideBranchTitleTween = TweenMax.to(aboutWorldwideBranchTitle, 0.3, { css: { scaleX: 0.6, scaleY: 0.6 }, ease: Linear.easeNone });
27768    aboutWorldwideBranchTitlePin = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchTitle).offset(-120).duration(durationCount(aboutWorldwideBranch, aboutWorldwideBranchTitle, 50)).setPin(aboutWorldwideBranchTitle, { pushFollowers: false })
27769    // .addIndicators() // add indicators (requires plugin)
27770    .addTo(controller);
27771
27772    aboutWorldwideBranchTitleAni = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchTitle).offset(-120).duration(150).setTween(aboutWorldwideBranchTitleTween)
27773    // .addIndicators() // add indicators (requires plugin)
27774    .addTo(controller);
27775
27776    aboutWorldwideBranchGrahicPin = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchGrahic).offset(-240).duration(durationCount(aboutWorldwideBranch, aboutWorldwideBranchGrahic, 170)).setPin(aboutWorldwideBranchGrahic, { pushFollowers: false })
27777    // .addIndicators() // add indicators (requires plugin)
27778    .addTo(controller);
27779
27780    aboutWorldwideBranchGrahicAni = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchGrahic).offset(-240).duration(200).setTween(aboutWorldwideBranchGrahicTween)
27781    // .addIndicators() // add indicators (requires plugin)
27782    .addTo(controller);
27783
27784    aboutWorldwideBranchBoxMask = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchBox).setClassToggle(aboutWorldwideBranchBox, 'status-mask').offset(-260).duration(1500)
27785    // .addIndicators() // add indicators (requires plugin)
27786    .addTo(controller);
27787
27788    scrollMovingAni = new ScrollMagic.Scene().triggerElement(aboutWorldwideBranchBox).setClassToggle('.about-scrollmov
27788ing-sticker', 'status-hide').offset(-250)
27789    // .addIndicators() // add indicators (requires plugin)
27790    .addTo(controller);
27791  }
27792
27793  // 向下滾動箭頭
27794  const scrollMovingSticker = function (event) {
27795    if (event.type === 'scrollstop') {
27796      scrollMovingEle.stop(true, true);
27797      if (scrollStatus === 'hide') {
27798        scrollMovingEle.animate({
27799          opacity: '1'
27800        }, 300, () => {
27801          scrollStatus = 'show';
27802        });
27803      }
27804    } else if (event.type === 'scrollstart') {
27805      scrollMovingEle.stop(true, true);
27806      if (scrollStatus === 'show') {
27807        scrollMovingEle.animate({
27808          opacity: '0'
27809        }, 300, () => {
27810          scrollStatus = 'hide';
27811        });
27812      }
27813    }
27814  };
27815
27816  const bodyEle = window.opera ? document.compatMode === 'CSS1Compat' ? $('html') : $('body') : $('html,body');
27817  const anchorEle = '.about-anchor';
27818
27819  const anchorOffset = 10;
27820  const anchorLength = $('.about-anchor-item').length;
27821
27822  function anchorScrollTo() {
27823    $(document).on('click', 'a[href^="#anch-marker-"]', function (event) {
27824      const id = $(this).attr('href');
27825
27826      if ($(id).length > 0) {
27827        event.preventDefault();
27828        bodyEle.animate({
27829          scrollTop: $(id).offset().top - anchorOffset
27830        }, 1000);
27831
27832        return false;
27833      }
27834      return true;
27835    });
27836  }
27837
27838  function anchorNavSelected(offsetNum) {
27839    const anchorDurations = {};
27840
27841    for (let i = 1; i <= anchorLength; i += 1) {
27842      if (i === anchorLength) {
27843        anchorDurations[i - 1] = $(`#anch-marker-${i}`).offset().top + offsetNum;
27844      } else {
27845        anchorDurations[i - 1] = $(`#anch-marker-${i + 1}`).offset().top - $(`#anch-marker-${i}`).offset().top;
27846      }
27847
27848      window[`anchorSelected${i}`] = new ScrollMagic.Scene().triggerElement(`#anch-marker-${i}`).offset(-200).duration(anchorDurations[i - 1]).setClassToggle(`.about-anchor-item:nth-child(${i})`, 'status-selected') // add class toggle
27849      // .addIndicators() // add indicators (requires plugin)
27850      .addTo(controller);
27851    }
27852  }
27853
27854  const init = () => {
27855    // anchorController = new ScrollMagic.Controller({
27856    //     globalSceneOptions :{
27857    //         triggerHook: 0
27858    //     }
27859    // });;
27860
27861    anchorScrollTo();
27862
27863    if (GLOBAL_BROWSER_STAT.ie8Browser === false) {
27864      controller = new ScrollMagic.Controller({
27865        globalSceneOptions: {
27866          triggerHook: 0
27867        }
27868      });
27869
27870      if (__WEBPACK_IMPORTED_MODULE_10__base__["a" /* default */].viewport(Object(__WEBPACK_IMPORTED_MODULE_9__maxin__["a" /* default */])()) === 'max') {
27871        if (showStyle !== 'desktop') {
27872          showStyle = 'desktop';
27873
27874          if (!$('.about').hasClass('status-animate')) {
27875            $('.about').addClass('status-animate');
27876          }
27877
27878          anchorNavSelected(1000);
27879
27880          aboutOutlineScrollMagic();
27881          aboutShinhoLogoScrollMagic();
27882          aboutSloganScrollMagic();
27883          aboutPhilosophyScrollMagic();
27884          aboutFoodecoSrollMagic();
27885          aboutWorldwideBranchScrollMagic();
27886
27887          anchorPin = new ScrollMagic.Scene().triggerElement('#about-anchor').offset(-120).setPin('#about-anchor', { pushFollowers: false }).duration($('.about').height() - 500)
27888          // .addIndicators() // add indicators (requires plugin)
27889          .addTo(controller);
27890
27891          $(window).on('scrollstop scrollstart', event => {
27892            clearTimeout(scrollMovingTimer);
27893            if (event.type === 'scrollstop') {
27894              scrollMovingTimer = setTimeout(scrollMovingSticker(event), 2000);
27895            } else {
27896              scrollMovingTimer = setTimeout(scrollMovingSticker(event), 0);
27897            }
27898          });
27899        }
27900      } else {
27901        if (showStyle !== 'mobile') {
27902          showStyle = 'mobile';
27903        }
27904
27905        if ($('.about').hasClass('status-animate')) {
27906          $('.about').removeClass('status-animate');
27907        }
27908      }
27909    }
27910  };
27911
27912  $(window).on('scroll', () => {
27913    if (controller) {
27914      controller.update(true);
27915    }
27916  });
27917
27918  $(window).resize(() => {
27919    if (GLOBAL_BROWSER_STAT.ie8Browser === false) {
27920      if (__WEBPACK_IMPORTED_MODULE_10__base__["a" /* default */].viewport(Object(__WEBPACK_IMPORTED_MODULE_9__maxin__["a" /* default */])()) === 'max') {
27921        if (showStyle !== 'desktop') {
27922          if (controller != null) {
27923            controller.destroy(true);
27924            controller = null;
27925          } else {
27926            // ..
27927          }
27928          init();
27929        }
27930      } else {
27931        showStyle = 'mobile';
27932        if (controller != null) {
27933          controller.destroy(true);
27934          controller = null;
27935        }
27936      }
27937    }
27938  });
27939  const setting = () => {
27940    // 賦予瀏覽器判別值
27941    GLOBAL_BROWSER_STAT.modernBrowser = __WEBPACK_IMPORTED_MODULE_10__base__["a" /* default */].modernBrowser();
27942    GLOBAL_BROWSER_STAT.ie8Browser = __WEBPACK_IMPORTED_MODULE_10__base__["a" /* default */].ie8Browser();
27943    setTimeout(() => {
27944      init();
27945    }, 1000);
27946
27947    // 浮动选单
27948
27949    // let $body = (window.opera) ? (document.compatMode == "CSS1Compat" ? $('html') : $('body')) : $('html,body');
27950    // for (let i = 1; i <= sectionNum; i++) {
27951    //     let offset = 110;
27952
27953    //     $("#anchor" + i).on("click", function(e) {
27954    //         $body.animate({
27955    //             scrollTop: $("#sec" + i).offset().top - offset
27956    //         }, 1000);
27957    //         return false;
27958    //     })
27959    // }
27960  };
27961
27962  $(window).load(() => {
27963    setting();
27964  });
27965});
27966/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(0), __webpack_require__(2)))
27967
27968/***/ })
27969/******/ ]);
27970//# sourceMappingURL=../../src/map/lyt-cn-about.js.map

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.