PageSourceSearch

https://www.nexans.no/.resources/nexans-base/webresources/js/main.js?t=24.20

js nexans.no collected 2026-09-24 23:26:54 UTC 1,220,479 bytes, 28,124 lines download raw bytes

1(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
2(function (global){(function (){
3"use strict";
4
5function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
6/**
7*  Ajax Autocomplete for jQuery, version 1.4.11
8*  (c) 2017 Tomas Kirda
9*
10*  Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
11*  For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete
12*/
13
14/*jslint  browser: true, white: true, single: true, this: true, multivar: true */
15/*global define, window, document, jQuery, exports, require */
16
17// Expose plugin as an AMD module if AMD loader is present:
18(function (factory) {
19  "use strict";
20
21  if (typeof define === 'function' && define.amd) {
22    // AMD. Register as an anonymous module.
23    define(['jquery'], factory);
24  } else if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof require === 'function') {
25    // Browserify
26    factory((typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null));
27  } else {
28    // Browser globals
29    factory(jQuery);
30  }
31})(function ($) {
32  'use strict';
33
34  var utils = function () {
35      return {
36        escapeRegExChars: function escapeRegExChars(value) {
37          return value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
38        },
39        createNode: function createNode(containerClass) {
40          var div = document.createElement('div');
41          div.className = containerClass;
42          div.style.position = 'absolute';
43          div.style.display = 'none';
44          return div;
45        }
46      };
47    }(),
48    keys = {
49      ESC: 27,
50      TAB: 9,
51      RETURN: 13,
52      LEFT: 37,
53      UP: 38,
54      RIGHT: 39,
55      DOWN: 40
56    },
57    noop = $.noop;
58  function Autocomplete(el, options) {
59    var that = this;
60
61    // Shared variables:
62    that.element = el;
63    that.el = $(el);
64    that.suggestions = [];
65    that.badQueries = [];
66    that.selectedIndex = -1;
67    that.currentValue = that.element.value;
68    that.timeoutId = null;
69    that.cachedResponse = {};
70    that.onChangeTimeout = null;
71    that.onChange = null;
72    that.isLocal = false;
73    that.suggestionsContainer = null;
74    that.noSuggestionsContainer = null;
75    that.options = $.extend(true, {}, Autocomplete.defaults, options);
76    that.classes = {
77      selected: 'autocomplete-selected',
78      suggestion: 'autocomplete-suggestion'
79    };
80    that.hint = null;
81    that.hintValue = '';
82    that.selection = null;
83
84    // Initialize and set options:
85    that.initialize();
86    that.setOptions(options);
87  }
88  Autocomplete.utils = utils;
89  $.Autocomplete = Autocomplete;
90  Autocomplete.defaults = {
91    ajaxSettings: {},
92    autoSelectFirst: false,
93    appendTo: 'body',
94    serviceUrl: null,
95    lookup: null,
96    onSelect: null,
97    width: 'auto',
98    minChars: 1,
99    maxHeight: 300,
100    deferRequestBy: 0,
101    params: {},
102    formatResult: _formatResult,
103    formatGroup: _formatGroup,
104    delimiter: null,
105    zIndex: 9999,
106    type: 'GET',
107    noCache: false,
108    onSearchStart: noop,
109    onSearchComplete: noop,
110    onSearchError: noop,
111    preserveInput: false,
112    containerClass: 'autocomplete-suggestions',
113    tabDisabled: false,
114    dataType: 'text',
115    currentRequest: null,
116    triggerSelectOnValidInput: true,
117    preventBadQueries: true,
118    lookupFilter: _lookupFilter,
119    paramName: 'query',
120    transformResult: _transformResult,
121    showNoSuggestionNotice: false,
122    noSuggestionNotice: 'No results',
123    orientation: 'bottom',
124    forceFixPosition: false
125  };
126  function _lookupFilter(suggestion, originalQuery, queryLowerCase) {
127    return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
128  }
129  ;
130  function _transformResult(response) {
131    return typeof response === 'string' ? $.parseJSON(response) : response;
132  }
133  ;
134  function _formatResult(suggestion, currentValue) {
135    // Do not replace anything if the current value is empty
136    if (!currentValue) {
137      return suggestion.value;
138    }
139    var pattern = '(' + utils.escapeRegExChars(currentValue) + ')';
140    return suggestion.value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/&lt;(\/?strong)&gt;/g, '<$1>');
141  }
142  ;
143  function _formatGroup(suggestion, category) {
144    return '<div class="autocomplete-group">' + category + '</div>';
145  }
146  ;
147  Autocomplete.prototype = {
148    initialize: function initialize() {
149      var that = this,
150        suggestionSelector = '.' + that.classes.suggestion,
151        selected = that.classes.selected,
152        options = that.options,
153        container;
154      that.element.setAttribute('autocomplete', 'off');
155
156      // html() deals with many types: htmlString or Element or Array or jQuery
157      that.noSuggestionsContainer = $('<div class="autocomplete-no-suggestion"></div>').html(this.options.noSuggestionNotice).get(0);
158      that.suggestionsContainer = Autocomplete.utils.createNode(options.containerClass);
159      container = $(that.suggestionsContainer);
160      container.appendTo(options.appendTo || 'body');
161
162      // Only set width if it was provided:
163      if (options.width !== 'auto') {
164        container.css('width', options.width);
165      }
166
167      // Listen for mouse over event on suggestions list:
168      container.on('mouseover.autocomplete', suggestionSelector, function () {
169        that.activate($(this).data('index'));
170      });
171
172      // Deselect active element when mouse leaves suggestions container:
173      container.on('mouseout.autocomplete', function () {
174        that.selectedIndex = -1;
175        container.children('.' + selected).removeClass(selected);
176      });
177
178      // Listen for click event on suggestions list:
179      container.on('click.autocomplete', suggestionSelector, function () {
180        that.select($(this).data('index'));
181      });
182      container.on('click.autocomplete', function () {
183        clearTimeout(that.blurTimeoutId);
184      });
185      that.fixPositionCapture = function () {
186        if (that.visible) {
187          that.fixPosition();
188        }
189      };
190      $(window).on('resize.autocomplete', that.fixPositionCapture);
191      that.el.on('keydown.autocomplete', function (e) {
192        that.onKeyPress(e);
193      });
194      that.el.on('keyup.autocomplete', function (e) {
195        that.onKeyUp(e);
196      });
197      that.el.on('blur.autocomplete', function () {
198        that.onBlur();
199      });
200      that.el.on('focus.autocomplete', function () {
201        that.onFocus();
202      });
203      that.el.on('change.autocomplete', function (e) {
204        that.onKeyUp(e);
205      });
206      that.el.on('input.autocomplete', function (e) {
207        that.onKeyUp(e);
208      });
209    },
210    onFocus: function onFocus() {
211      var that = this;
212      if (that.disabled) {
213        return;
214      }
215      that.fixPosition();
216      if (that.el.val().length >= that.options.minChars) {
217        that.onValueChange();
218      }
219    },
220    onBlur: function onBlur() {
221      var that = this,
222        options = that.options,
223        value = that.el.val(),
224        query = that.getQuery(value);
225
226      // If user clicked on a suggestion, hide() will
227      // be canceled, otherwise close suggestions
228      that.blurTimeoutId = setTimeout(function () {
229        that.hide();
230        if (that.selection && that.currentValue !== query) {
231          (options.onInvalidateSelection || $.noop).call(that.element);
232        }
233      }, 200);
234    },
235    abortAjax: function abortAjax() {
236      var that = this;
237      if (that.currentRequest) {
238        that.currentRequest.abort();
239        that.currentRequest = null;
240      }
241    },
242    setOptions: function setOptions(suppliedOptions) {
243      var that = this,
244        options = $.extend({}, that.options, suppliedOptions);
245      that.isLocal = Array.isArray(options.lookup);
246      if (that.isLocal) {
247        options.lookup = that.verifySuggestionsFormat(options.lookup);
248      }
249      options.orientation = that.validateOrientation(options.orientation, 'bottom');
250
251      // Adjust height, width and z-index:
252      $(that.suggestionsContainer).css({
253        'max-height': options.maxHeight + 'px',
254        'width': options.width + 'px',
255        'z-index': options.zIndex
256      });
257      this.options = options;
258    },
259    clearCache: function clearCache() {
260      this.cachedResponse = {};
261      this.badQueries = [];
262    },
263    clear: function clear() {
264      this.clearCache();
265      this.currentValue = '';
266      this.suggestions = [];
267    },
268    disable: function disable() {
269      var that = this;
270      that.disabled = true;
271      clearTimeout(that.onChangeTimeout);
272      that.abortAjax();
273    },
274    enable: function enable() {
275      this.disabled = false;
276    },
277    fixPosition: function fixPosition() {
278      // Use only when container has already its content
279
280      var that = this,
281        $container = $(that.suggestionsContainer),
282        containerParent = $container.parent().get(0);
283      // Fix position automatically when appended to body.
284      // In other cases force parameter must be given.
285      if (containerParent !== document.body && !that.options.forceFixPosition) {
286        return;
287      }
288
289      // Choose orientation
290      var orientation = that.options.orientation,
291        containerHeight = $container.outerHeight(),
292        height = that.el.outerHeight(),
293        offset = that.el.offset(),
294        styles = {
295          'top': offset.top,
296          'left': offset.left
297        };
298      if (orientation === 'auto') {
299        var viewPortHeight = $(window).height(),
300          scrollTop = $(window).scrollTop(),
301          topOverflow = -scrollTop + offset.top - containerHeight,
302          bottomOverflow = scrollTop + viewPortHeight - (offset.top + height + containerHeight);
303        orientation = Math.max(topOverflow, bottomOverflow) === topOverflow ? 'top' : 'bottom';
304      }
305      if (orientation === 'top') {
306        styles.top += -containerHeight;
307      } else {
308        styles.top += height;
309      }
310
311      // If container is not positioned to body,
312      // correct its position using offset parent offset
313      if (containerParent !== document.body) {
314        var opacity = $container.css('opacity'),
315          parentOffsetDiff;
316        if (!that.visible) {
317          $container.css('opacity', 0).show();
318        }
319        parentOffsetDiff = $container.offsetParent().offset();
320        styles.top -= parentOffsetDiff.top;
321        styles.top += containerParent.scrollTop;
322        styles.left -= parentOffsetDiff.left;
323        if (!that.visible) {
324          $container.css('opacity', opacity).hide();
325        }
326      }
327      if (that.options.width === 'auto') {
328        styles.width = that.el.outerWidth() + 'px';
329      }
330      $container.css(styles);
331    },
332    isCursorAtEnd: function isCursorAtEnd() {
333      var that = this,
334        valLength = that.el.val().length,
335        selectionStart = that.element.selectionStart,
336        range;
337      if (typeof selectionStart === 'number') {
338        return selectionStart === valLength;
339      }
340      if (document.selection) {
341        range = document.selection.createRange();
342        range.moveStart('character', -valLength);
343        return valLength === range.text.length;
344      }
345      return true;
346    },
347    onKeyPress: function onKeyPress(e) {
348      var that = this;
349
350      // If suggestions are hidden and user presses arrow down, display suggestions:
351      if (!that.disabled && !that.visible && e.which === keys.DOWN && that.currentValue) {
352        that.suggest();
353        return;
354      }
355      if (that.disabled || !that.visible) {
356        return;
357      }
358      switch (e.which) {
359        case keys.ESC:
360          that.el.val(that.currentValue);
361          that.hide();
362          break;
363        case keys.RIGHT:
364          if (that.hint && that.options.onHint && that.isCursorAtEnd()) {
365            that.selectHint();
366            break;
367          }
368          return;
369        case keys.TAB:
370          if (that.hint && that.options.onHint) {
371            that.selectHint();
372            return;
373          }
374          if (that.selectedIndex === -1) {
375            that.hide();
376            return;
377          }
378          that.select(that.selectedIndex);
379          if (that.options.tabDisabled === false) {
380            return;
381          }
382          break;
383        case keys.RETURN:
384          if (that.selectedIndex === -1) {
385            that.hide();
386            return;
387          }
388          that.select(that.selectedIndex);
389          break;
390        case keys.UP:
391          that.moveUp();
392          break;
393        case keys.DOWN:
394          that.moveDown();
395          break;
396        default:
397          return;
398      }
399
400      // Cancel event if function did not return:
401      e.stopImmediatePropagation();
402      e.preventDefault();
403    },
404    onKeyUp: function onKeyUp(e) {
405      var that = this;
406      if (that.disabled) {
407        return;
408      }
409      switch (e.which) {
410        case keys.UP:
411        case keys.DOWN:
412          return;
413      }
414      clearTimeout(that.onChangeTimeout);
415      if (that.currentValue !== that.el.val()) {
416        that.findBestHint();
417        if (that.options.deferRequestBy > 0) {
418          // Defer lookup in case when value changes very quickly:
419          that.onChangeTimeout = setTimeout(function () {
420            that.onValueChange();
421          }, that.options.deferRequestBy);
422        } else {
423          that.onValueChange();
424        }
425      }
426    },
427    onValueChange: function onValueChange() {
428      if (this.ignoreValueChange) {
429        this.ignoreValueChange = false;
430        return;
431      }
432      var that = this,
433        options = that.options,
434        value = that.el.val(),
435        query = that.getQuery(value);
436      if (that.selection && that.currentValue !== query) {
437        that.selection = null;
438        (options.onInvalidateSelection || $.noop).call(that.element);
439      }
440      clearTimeout(that.onChangeTimeout);
441      that.currentValue = value;
442      that.selectedIndex = -1;
443
444      // Check existing suggestion for the match before proceeding:
445      if (options.triggerSelectOnValidInput && that.isExactMatch(query)) {
446        that.select(0);
447        return;
448      }
449      if (query.length < options.minChars) {
450        that.hide();
451      } else {
452        that.getSuggestions(query);
453      }
454    },
455    isExactMatch: function isExactMatch(query) {
456      var suggestions = this.suggestions;
457      return suggestions.length === 1 && suggestions[0].value.toLowerCase() === query.toLowerCase();
458    },
459    getQuery: function getQuery(value) {
460      var delimiter = this.options.delimiter,
461        parts;
462      if (!delimiter) {
463        return value;
464      }
465      parts = value.split(delimiter);
466      return $.trim(parts[parts.length - 1]);
467    },
468    getSuggestionsLocal: function getSuggestionsLocal(query) {
469      var that = this,
470        options = that.options,
471        queryLowerCase = query.toLowerCase(),
472        filter = options.lookupFilter,
473        limit = parseInt(options.lookupLimit, 10),
474        data;
475      data = {
476        suggestions: $.grep(options.lookup, function (suggestion) {
477          return filter(suggestion, query, queryLowerCase);
478        })
479      };
480      if (limit && data.suggestions.length > limit) {
481        data.suggestions = data.suggestions.slice(0, limit);
482      }
483      return data;
484    },
485    getSuggestions: function getSuggestions(q) {
486      var response,
487        that = this,
488        options = that.options,
489        serviceUrl = options.serviceUrl,
490        params,
491        cacheKey,
492        ajaxSettings;
493      options.params[options.paramName] = q;
494      if (options.onSearchStart.call(that.element, options.params) === false) {
495        return;
496      }
497      params = options.ignoreParams ? null : options.params;
498      if ($.isFunction(options.lookup)) {
499        options.lookup(q, function (data) {
500          that.suggestions = data.suggestions;
501          that.suggest();
502          options.onSearchComplete.call(that.element, q, data.suggestions);
503        });
504        return;
505      }
506      if (that.isLocal) {
507        response = that.getSuggestionsLocal(q);
508      } else {
509        if ($.isFunction(serviceUrl)) {
510          serviceUrl = serviceUrl.call(that.element, q);
511        }
512        cacheKey = serviceUrl + '?' + $.param(params || {});
513        response = that.cachedResponse[cacheKey];
514      }
515      if (response && Array.isArray(response.suggestions)) {
516        that.suggestions = response.suggestions;
517        that.suggest();
518        options.onSearchComplete.call(that.element, q, response.suggestions);
519      } else if (!that.isBadQuery(q)) {
520        that.abortAjax();
521        ajaxSettings = {
522          url: serviceUrl,
523          data: params,
524          type: options.type,
525          dataType: options.dataType
526        };
527        $.extend(ajaxSettings, options.ajaxSettings);
528        that.currentRequest = $.ajax(ajaxSettings).done(function (data) {
529          var result;
530          that.currentRequest = null;
531          result = options.transformResult(data, q);
532          that.processResponse(result, q, cacheKey);
533          options.onSearchComplete.call(that.element, q, result.suggestions);
534        }).fail(function (jqXHR, textStatus, errorThrown) {
535          options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown);
536        });
537      } else {
538        options.onSearchComplete.call(that.element, q, []);
539      }
540    },
541    isBadQuery: function isBadQuery(q) {
542      if (!this.options.preventBadQueries) {
543        return false;
544      }
545      var badQueries = this.badQueries,
546        i = badQueries.length;
547      while (i--) {
548        if (q.indexOf(badQueries[i]) === 0) {
549          return true;
550        }
551      }
552      return false;
553    },
554    hide: function hide() {
555      var that = this,
556        container = $(that.suggestionsContainer);
557      if ($.isFunction(that.options.onHide) && that.visible) {
558        that.options.onHide.call(that.element, container);
559      }
560      that.visible = false;
561      that.selectedIndex = -1;
562      clearTimeout(that.onChangeTimeout);
563      $(that.suggestionsContainer).hide();
564      that.signalHint(null);
565    },
566    suggest: function suggest() {
567      if (!this.suggestions.length) {
568        if (this.options.showNoSuggestionNotice) {
569          this.noSuggestions();
570        } else {
571          this.hide();
572        }
573        return;
574      }
575      var that = this,
576        options = that.options,
577        groupBy = options.groupBy,
578        formatResult = options.formatResult,
579        value = that.getQuery(that.currentValue),
580        className = that.classes.suggestion,
581        classSelected = that.classes.selected,
582        container = $(that.suggestionsContainer),
583        noSuggestionsContainer = $(that.noSuggestionsContainer),
584        beforeRender = options.beforeRender,
585        html = '',
586        category,
587        formatGroup = function formatGroup(suggestion, index) {
588          var currentCategory = suggestion.data[groupBy];
589          if (category === currentCategory) {
590            return '';
591          }
592          category = currentCategory;
593          return options.formatGroup(suggestion, category);
594        };
595      if (options.triggerSelectOnValidInput && that.isExactMatch(value)) {
596        that.select(0);
597        return;
598      }
599
600      // Build suggestions inner HTML:
601      $.each(that.suggestions, function (i, suggestion) {
602        if (groupBy) {
603          html += formatGroup(suggestion, value, i);
604        }
605        html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value, i) + '</div>';
606      });
607      this.adjustContainerWidth();
608      noSuggestionsContainer.detach();
609      container.html(html);
610      if ($.isFunction(beforeRender)) {
611        beforeRender.call(that.element, container, that.suggestions);
612      }
613      that.fixPosition();
614      container.show();
615
616      // Select first value by default:
617      if (options.autoSelectFirst) {
618        that.selectedIndex = 0;
619        container.scrollTop(0);
620        container.children('.' + className).first().addClass(classSelected);
621      }
622      that.visible = true;
623      that.findBestHint();
624    },
625    noSuggestions: function noSuggestions() {
626      var that = this,
627        beforeRender = that.options.beforeRender,
628        container = $(that.suggestionsContainer),
629        noSuggestionsContainer = $(that.noSuggestionsContainer);
630      this.adjustContainerWidth();
631
632      // Some explicit steps. Be careful here as it easy to get
633      // noSuggestionsContainer removed from DOM if not detached properly.
634      noSuggestionsContainer.detach();
635
636      // clean suggestions if any
637      container.empty();
638      container.append(noSuggestionsContainer);
639      if ($.isFunction(beforeRender)) {
640        beforeRender.call(that.element, container, that.suggestions);
641      }
642      that.fixPosition();
643      container.show();
644      that.visible = true;
645    },
646    adjustContainerWidth: function adjustContainerWidth() {
647      var that = this,
648        options = that.options,
649        width,
650        container = $(that.suggestionsContainer);
651
652      // If width is auto, adjust width before displaying suggestions,
653      // because if instance was created before input had width, it will be zero.
654      // Also it adjusts if input width has changed.
655      if (options.width === 'auto') {
656        width = that.el.outerWidth();
657        container.css('width', width > 0 ? width : 300);
658      } else if (options.width === 'flex') {
659        // Trust the source! Unset the width property so it will be the max length
660        // the containing elements.
661        container.css('width', '');
662      }
663    },
664    findBestHint: function findBestHint() {
665      var that = this,
666        value = that.el.val().toLowerCase(),
667        bestMatch = null;
668      if (!value) {
669        return;
670      }
671      $.each(that.suggestions, function (i, suggestion) {
672        var foundMatch = suggestion.value.toLowerCase().indexOf(value) === 0;
673        if (foundMatch) {
674          bestMatch = suggestion;
675        }
676        return !foundMatch;
677      });
678      that.signalHint(bestMatch);
679    },
680    signalHint: function signalHint(suggestion) {
681      var hintValue = '',
682        that = this;
683      if (suggestion) {
684        hintValue = that.currentValue + suggestion.value.substr(that.currentValue.length);
685      }
686      if (that.hintValue !== hintValue) {
687        that.hintValue = hintValue;
688        that.hint = suggestion;
689        (this.options.onHint || $.noop)(hintValue);
690      }
691    },
692    verifySuggestionsFormat: function verifySuggestionsFormat(suggestions) {
693      // If suggestions is string array, convert them to supported format:
694      if (suggestions.length && typeof suggestions[0] === 'string') {
695        return $.map(suggestions, function (value) {
696          return {
697            value: value,
698            data: null
699          };
700        });
701      }
702      return suggestions;
703    },
704    validateOrientation: function validateOrientation(orientation, fallback) {
705      orientation = $.trim(orientation || '').toLowerCase();
706      if ($.inArray(orientation, ['auto', 'bottom', 'top']) === -1) {
707        orientation = fallback;
708      }
709      return orientation;
710    },
711    processResponse: function processResponse(result, originalQuery, cacheKey) {
712      var that = this,
713        options = that.options;
714      result.suggestions = that.verifySuggestionsFormat(result.suggestions);
715
716      // Cache results if cache is not disabled:
717      if (!options.noCache) {
718        that.cachedResponse[cacheKey] = result;
719        if (options.preventBadQueries && !result.suggestions.length) {
720          that.badQueries.push(originalQuery);
721        }
722      }
723
724      // Return if originalQuery is not matching current query:
725      if (originalQuery !== that.getQuery(that.currentValue)) {
726        return;
727      }
728      that.suggestions = result.suggestions;
729      that.suggest();
730    },
731    activate: function activate(index) {
732      var that = this,
733        activeItem,
734        selected = that.classes.selected,
735        container = $(that.suggestionsContainer),
736        children = container.find('.' + that.classes.suggestion);
737      container.find('.' + selected).removeClass(selected);
738      that.selectedIndex = index;
739      if (that.selectedIndex !== -1 && children.length > that.selectedIndex) {
740        activeItem = children.get(that.selectedIndex);
741        $(activeItem).addClass(selected);
742        return activeItem;
743      }
744      return null;
745    },
746    selectHint: function selectHint() {
747      var that = this,
748        i = $.inArray(that.hint, that.suggestions);
749      that.select(i);
750    },
751    select: function select(i) {
752      var that = this;
753      that.hide();
754      that.onSelect(i);
755    },
756    moveUp: function moveUp() {
757      var that = this;
758      if (that.selectedIndex === -1) {
759        return;
760      }
761      if (that.selectedIndex === 0) {
762        $(that.suggestionsContainer).children('.' + that.classes.suggestion).first().removeClass(that.classes.selected);
763        that.selectedIndex = -1;
764        that.ignoreValueChange = false;
765        that.el.val(that.currentValue);
766        that.findBestHint();
767        return;
768      }
769      that.adjustScroll(that.selectedIndex - 1);
770    },
771    moveDown: function moveDown() {
772      var that = this;
773      if (that.selectedIndex === that.suggestions.length - 1) {
774        return;
775      }
776      that.adjustScroll(that.selectedIndex + 1);
777    },
778    adjustScroll: function adjustScroll(index) {
779      var that = this,
780        activeItem = that.activate(index);
781      if (!activeItem) {
782        return;
783      }
784      var offsetTop,
785        upperBound,
786        lowerBound,
787        heightDelta = $(activeItem).outerHeight();
788      offsetTop = activeItem.offsetTop;
789      upperBound = $(that.suggestionsContainer).scrollTop();
790      lowerBound = upperBound + that.options.maxHeight - heightDelta;
791      if (offsetTop < upperBound) {
792        $(that.suggestionsContainer).scrollTop(offsetTop);
793      } else if (offsetTop > lowerBound) {
794        $(that.suggestionsContainer).scrollTop(offsetTop - that.options.maxHeight + heightDelta);
795      }
796      if (!that.options.preserveInput) {
797        // During onBlur event, browser will trigger "change" event,
798        // because value has changed, to avoid side effect ignore,
799        // that event, so that correct suggestion can be selected
800        // when clicking on suggestion with a mouse
801        that.ignoreValueChange = true;
802        that.el.val(that.getValue(that.suggestions[index].value));
803      }
804      that.signalHint(null);
805    },
806    onSelect: function onSelect(index) {
807      var that = this,
808        onSelectCallback = that.options.onSelect,
809        suggestion = that.suggestions[index];
810      that.currentValue = that.getValue(suggestion.value);
811      if (that.currentValue !== that.el.val() && !that.options.preserveInput) {
812        that.el.val(that.currentValue);
813      }
814      that.signalHint(null);
815      that.suggestions = [];
816      that.selection = suggestion;
817      if ($.isFunction(onSelectCallback)) {
818        onSelectCallback.call(that.element, suggestion);
819      }
820    },
821    getValue: function getValue(value) {
822      var that = this,
823        delimiter = that.options.delimiter,
824        currentValue,
825        parts;
826      if (!delimiter) {
827        return value;
828      }
829      currentValue = that.currentValue;
830      parts = currentValue.split(delimiter);
831      if (parts.length === 1) {
832        return value;
833      }
834      return currentValue.substr(0, currentValue.length - parts[parts.length - 1].length) + value;
835    },
836    dispose: function dispose() {
837      var that = this;
838      that.el.off('.autocomplete').removeData('autocomplete');
839      $(window).off('resize.autocomplete', that.fixPositionCapture);
840      $(that.suggestionsContainer).remove();
841    }
842  };
843
844  // Create chainable jQuery plugin:
845  $.fn.devbridgeAutocomplete = function (options, args) {
846    var dataKey = 'autocomplete';
847    // If function invoked without argument return
848    // instance of the first matched element:
849    if (!arguments.length) {
850      return this.first().data(dataKey);
851    }
852    return this.each(function () {
853      var inputElement = $(this),
854        instance = inputElement.data(dataKey);
855      if (typeof options === 'string') {
856        if (instance && typeof instance[options] === 'function') {
857          instance[options](args);
858        }
859      } else {
860        // If instance already exists, destroy it:
861        if (instance && instance.dispose) {
862          instance.dispose();
863        }
864        instance = new Autocomplete(this, options);
865        inputElement.data(dataKey, instance);
866      }
867    });
868  };
869
870  // Don't overwrite if it already exists
871  if (!$.fn.autocomplete) {
872    $.fn.autocomplete = $.fn.devbridgeAutocomplete;
873  }
874});
875
876}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
877},{}],2:[function(require,module,exports){
878(function (global){(function (){
879"use strict";
880
881function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
882/*!
883 * VERSION: 1.20.4
884 * DATE: 2018-02-15
885 * UPDATES AND DOCS AT: http://greensock.com
886 *
887 * @license Copyright (c) 2008-2018, GreenSock. All rights reserved.
888 * This work is subject to the terms at http://greensock.com/standard-license or for
889 * Club GreenSock members, the software agreement that was issued with your membership.
890 * 
891 * @author: Jack Doyle, [email protected]
892 */
893var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : void 0 || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node
894(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () {
895  "use strict";
896
897  _gsScope._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin", "TweenLite"], function (TweenPlugin, TweenLite) {
898    /** @constructor **/
899    var _CSSPlugin = function CSSPlugin() {
900        TweenPlugin.call(this, "css");
901        this._overwriteProps.length = 0;
902        this.setRatio = _CSSPlugin.prototype.setRatio; //speed optimization (avoid prototype lookup on this "hot" method)
903      },
904      _globals = _gsScope._gsDefine.globals,
905      _hasPriority,
906      //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.
907      _suffixMap,
908      //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
909      _cs,
910      //computed style (we store this in a shared variable to conserve memory and make minification tighter
911      _overwriteProps,
912      //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.
913      _specialProps = {},
914      p = _CSSPlugin.prototype = new TweenPlugin("css");
915    p.constructor = _CSSPlugin;
916    _CSSPlugin.version = "1.20.4";
917    _CSSPlugin.API = 2;
918    _CSSPlugin.defaultTransformPerspective = 0;
919    _CSSPlugin.defaultSkewType = "compensated";
920    _CSSPlugin.defaultSmoothOrigin = true;
921    p = "px"; //we'll reuse the "p" variable to keep file size down
922    _CSSPlugin.suffixMap = {
923      top: p,
924      right: p,
925      bottom: p,
926      left: p,
927      width: p,
928      height: p,
929      fontSize: p,
930      padding: p,
931      margin: p,
932      perspective: p,
933      lineHeight: ""
934    };
935    var _numExp = /(?:\-|\.|\b)(\d|\.|e\-)+/g,
936      _relNumExp = /(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g,
937      _valuesExp = /(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b)/gi,
938      //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)"
939      _NaNExp = /(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g,
940      //also allows scientific notation and doesn't kill the leading -/+ in -= and +=
941      _suffixExp = /(?:\d|\-|\+|=|#|\.)*/g,
942      _opacityExp = /opacity *= *([^)]*)/i,
943      _opacityValExp = /opacity:([^;]*)/i,
944      _alphaFilterExp = /alpha\(opacity *=.+?\)/i,
945      _rgbhslExp = /^(rgb|hsl)/,
946      _capsExp = /([A-Z])/g,
947      _camelExp = /-([a-z])/gi,
948      _urlExp = /(^(?:url\(\"|url\())|(?:(\"\))$|\)$)/gi,
949      //for pulling out urls from url(...) or url("...") strings (some browsers wrap urls in quotes, some don't when reporting things like backgroundImage)
950      _camelFunc = function _camelFunc(s, g) {
951        return g.toUpperCase();
952      },
953      _horizExp = /(?:Left|Right|Width)/i,
954      _ieGetMatrixExp = /(M11|M12|M21|M22)=[\d\-\.e]+/gi,
955      _ieSetMatrixExp = /progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i,
956      _commasOutsideParenExp = /,(?=[^\)]*(?:\(|$))/gi,
957      //finds any commas that are not within parenthesis
958      _complexExp = /[\s,\(]/i,
959      //for testing a string to find if it has a space, comma, or open parenthesis (clues that it's a complex value)
960      _DEG2RAD = Math.PI / 180,
961      _RAD2DEG = 180 / Math.PI,
962      _forcePT = {},
963      _dummyElement = {
964        style: {}
965      },
966      _doc = _gsScope.document || {
967        createElement: function createElement() {
968          return _dummyElement;
969        }
970      },
971      _createElement = function _createElement(type, ns) {
972        return _doc.createElementNS ? _doc.createElementNS(ns || "http://www.w3.org/1999/xhtml", type) : _doc.createElement(type);
973      },
974      _tempDiv = _createElement("div"),
975      _tempImg = _createElement("img"),
976      _internals = _CSSPlugin._internals = {
977        _specialProps: _specialProps
978      },
979      //provides a hook to a few internal methods that we need to access from inside other plugins
980      _agent = (_gsScope.navigator || {}).userAgent || "",
981      _autoRound,
982      _reqSafariFix,
983      //we won't apply the Safari transform fix until we actually come across a tween that affects a transform property (to maintain best performance).
984
985      _isSafari,
986      _isFirefox,
987      //Firefox has a bug that causes 3D transformed elements to randomly disappear unless a repaint is forced after each update on each element.
988      _isSafariLT6,
989      //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!)
990      _ieVers,
991      _supportsOpacity = function () {
992        //we set _isSafari, _ieVers, _isFirefox, and _supportsOpacity all in one function here to reduce file size slightly, especially in the minified version.
993        var i = _agent.indexOf("Android"),
994          a = _createElement("a");
995        _isSafari = _agent.indexOf("Safari") !== -1 && _agent.indexOf("Chrome") === -1 && (i === -1 || parseFloat(_agent.substr(i + 8, 2)) > 3);
996        _isSafariLT6 = _isSafari && parseFloat(_agent.substr(_agent.indexOf("Version/") + 8, 2)) < 6;
997        _isFirefox = _agent.indexOf("Firefox") !== -1;
998        if (/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(_agent) || /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(_agent)) {
999          _ieVers = parseFloat(RegExp.$1);
1000        }
1001        if (!a) {
1002          return false;
1003        }
1004        a.style.cssText = "top:1px;opacity:.55;";
1005        return /^0.55/.test(a.style.opacity);
1006      }(),
1007      _getIEOpacity = function _getIEOpacity(v) {
1008        return _opacityExp.test(typeof v === "string" ? v : (v.currentStyle ? v.currentStyle.filter : v.style.filter) || "") ? parseFloat(RegExp.$1) / 100 : 1;
1009      },
1010      _log = function _log(s) {
1011        //for logging messages, but in a way that won't throw errors in old versions of IE.
1012        if (_gsScope.console) {
1013          console.log(s);
1014        }
1015      },
1016      _target,
1017      //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
1018      _index,
1019      //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
1020
1021      _prefixCSS = "",
1022      //the non-camelCase vendor prefix like "-o-", "-moz-", "-ms-", or "-webkit-"
1023      _prefix = "",
1024      //camelCase vendor prefix like "O", "ms", "Webkit", or "Moz".
1025
1026      // @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)
1027      _checkPropPrefix = function _checkPropPrefix(p, e) {
1028        e = e || _tempDiv;
1029        var s = e.style,
1030          a,
1031          i;
1032        if (s[p] !== undefined) {
1033          return p;
1034        }
1035        p = p.charAt(0).toUpperCase() + p.substr(1);
1036        a = ["O", "Moz", "ms", "Ms", "Webkit"];
1037        i = 5;
1038        while (--i > -1 && s[a[i] + p] === undefined) {}
1039        if (i >= 0) {
1040          _prefix = i === 3 ? "ms" : a[i];
1041          _prefixCSS = "-" + _prefix.toLowerCase() + "-";
1042          return _prefix + p;
1043        }
1044        return null;
1045      },
1046      _getComputedStyle = _doc.defaultView ? _doc.defaultView.getComputedStyle : function () {},
1047      /**
1048       * @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:
1049       * var currentLeft = CSSPlugin.getStyle( document.getElementById("myElement"), "left");
1050       *
1051       * @param {!Object} t Target element whose style property you want to query
1052       * @param {!string} p Property name (like "left" or "top" or "marginTop", etc.)
1053       * @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.
1054       * @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.
1055       * @param {string=} dflt Default value that should be returned in the place of null, "none", "auto" or "auto auto".
1056       * @return {?string} The current property value
1057       */
1058      _getStyle = _CSSPlugin.getStyle = function (t, p, cs, calc, dflt) {
1059        var rv;
1060        if (!_supportsOpacity) if (p === "opacity") {
1061          //several versions of IE don't use the standard "opacity" property - they use things like filter:alpha(opacity=50), so we parse that here.
1062          return _getIEOpacity(t);
1063        }
1064        if (!calc && t.style[p]) {
1065          rv = t.style[p];
1066        } else if (cs = cs || _getComputedStyle(t)) {
1067          rv = cs[p] || cs.getPropertyValue(p) || cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase());
1068        } else if (t.currentStyle) {
1069          rv = t.currentStyle[p];
1070        }
1071        return dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto") ? dflt : rv;
1072      },
1073      /**
1074       * @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.
1075       * @param {!Object} t Target element
1076       * @param {!string} p Property name (like "left", "top", "marginLeft", etc.)
1077       * @param {!number} v Value
1078       * @param {string=} sfx Suffix (like "px" or "%" or "em")
1079       * @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.
1080       * @return {number} value in pixels
1081       */
1082      _convertToPixels = _internals.convertToPixels = function (t, p, v, sfx, recurse) {
1083        if (sfx === "px" || !sfx && p !== "lineHeight") {
1084          return v;
1085        }
1086        if (sfx === "auto" || !v) {
1087          return 0;
1088        }
1089        var horiz = _horizExp.test(p),
1090          node = t,
1091          style = _tempDiv.style,
1092          neg = v < 0,
1093          precise = v === 1,
1094          pix,
1095          cache,
1096          time;
1097        if (neg) {
1098          v = -v;
1099        }
1100        if (precise) {
1101          v *= 100;
1102        }
1103        if (p === "lineHeight" && !sfx) {
1104          //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.
1105          cache = _getComputedStyle(t).lineHeight;
1106          t.style.lineHeight = v;
1107          pix = parseFloat(_getComputedStyle(t).lineHeight);
1108          t.style.lineHeight = cache;
1109        } else if (sfx === "%" && p.indexOf("border") !== -1) {
1110          pix = v / 100 * (horiz ? t.clientWidth : t.clientHeight);
1111        } else {
1112          style.cssText = "border:0 solid red;position:" + _getStyle(t, "position") + ";line-height:0;";
1113          if (sfx === "%" || !node.appendChild || sfx.charAt(0) === "v" || sfx === "rem") {
1114            node = t.parentNode || _doc.body;
1115            if (_getStyle(node, "display").indexOf("flex") !== -1) {
1116              //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.
1117              style.position = "absolute";
1118            }
1119            cache = node._gsCache;
1120            time = TweenLite.ticker.frame;
1121            if (cache && horiz && cache.time === time) {
1122              //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)
1123              return cache.width * v / 100;
1124            }
1125            style[horiz ? "width" : "height"] = v + sfx;
1126          } else {
1127            style[horiz ? "borderLeftWidth" : "borderTopWidth"] = v + sfx;
1128          }
1129          node.appendChild(_tempDiv);
1130          pix = parseFloat(_tempDiv[horiz ? "offsetWidth" : "offsetHeight"]);
1131          node.removeChild(_tempDiv);
1132          if (horiz && sfx === "%" && _CSSPlugin.cacheWidths !== false) {
1133            cache = node._gsCache = node._gsCache || {};
1134            cache.time = time;
1135            cache.width = pix / v * 100;
1136          }
1137          if (pix === 0 && !recurse) {
1138            pix = _convertToPixels(t, p, v, sfx, true);
1139          }
1140        }
1141        if (precise) {
1142          pix /= 100;
1143        }
1144        return neg ? -pix : pix;
1145      },
1146      _calculateOffset = _internals.calculateOffset = function (t, p, cs) {
1147        //for figuring out "top" or "left" in px when it's "auto". We need to factor in margin with the offsetLeft/offsetTop
1148        if (_getStyle(t, "position", cs) !== "absolute") {
1149          return 0;
1150        }
1151        var dim = p === "left" ? "Left" : "Top",
1152          v = _getStyle(t, "margin" + dim, cs);
1153        return t["offset" + dim] - (_convertToPixels(t, p, parseFloat(v), v.replace(_suffixExp, "")) || 0);
1154      },
1155      // @private returns at object containing ALL of the style properties in camelCase and their associated values.
1156      _getAllStyles = function _getAllStyles(t, cs) {
1157        var s = {},
1158          i,
1159          tr,
1160          p;
1161        if (cs = cs || _getComputedStyle(t, null)) {
1162          if (i = cs.length) {
1163            while (--i > -1) {
1164              p = cs[i];
1165              if (p.indexOf("-transform") === -1 || _transformPropCSS === p) {
1166                //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
1167                s[p.replace(_camelExp, _camelFunc)] = cs.getPropertyValue(p);
1168              }
1169            }
1170          } else {
1171            //some browsers behave differently - cs.length is always 0, so we must do a for...in loop.
1172            for (i in cs) {
1173              if (i.indexOf("Transform") === -1 || _transformProp === i) {
1174                //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
1175                s[i] = cs[i];
1176              }
1177            }
1178          }
1179        } else if (cs = t.currentStyle || t.style) {
1180          for (i in cs) {
1181            if (typeof i === "string" && s[i] === undefined) {
1182              s[i.replace(_camelExp, _camelFunc)] = cs[i];
1183            }
1184          }
1185        }
1186        if (!_supportsOpacity) {
1187          s.opacity = _getIEOpacity(t);
1188        }
1189        tr = _getTransform(t, cs, false);
1190        s.rotation = tr.rotation;
1191        s.skewX = tr.skewX;
1192        s.scaleX = tr.scaleX;
1193        s.scaleY = tr.scaleY;
1194        s.x = tr.x;
1195        s.y = tr.y;
1196        if (_supports3D) {
1197          s.z = tr.z;
1198          s.rotationX = tr.rotationX;
1199          s.rotationY = tr.rotationY;
1200          s.scaleZ = tr.scaleZ;
1201        }
1202        if (s.filters) {
1203          delete s.filters;
1204        }
1205        return s;
1206      },
1207      // @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
1207ontaining 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.
1208      _cssDif = function _cssDif(t, s1, s2, vars, forceLookup) {
1209        var difs = {},
1210          style = t.style,
1211          val,
1212          p,
1213          mpt;
1214        for (p in s2) {
1215          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") {
1216            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.
1217            if (style[p] !== undefined) {
1218              //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.
1219              mpt = new MiniPropTween(style, p, style[p], mpt);
1220            }
1221          }
1222        }
1223        if (vars) {
1224          for (p in vars) {
1225            //copy properties (except className)
1226            if (p !== "className") {
1227              difs[p] = vars[p];
1228            }
1229          }
1230        }
1231        return {
1232          difs: difs,
1233          firstMPT: mpt
1234        };
1235      },
1236      _dimensions = {
1237        width: ["Left", "Right"],
1238        height: ["Top", "Bottom"]
1239      },
1240      _margins = ["marginLeft", "marginRight", "marginTop", "marginBottom"],
1241      /**
1242       * @private Gets the width or height of an element
1243       * @param {!Object} t Target element
1244       * @param {!string} p Property name ("width" or "height")
1245       * @param {Object=} cs Computed style object (if one exists). Just a speed optimization.
1246       * @return {number} Dimension (in pixels)
1247       */
1248      _getDimension = function _getDimension(t, p, cs) {
1249        if ((t.nodeName + "").toLowerCase() === "svg") {
1250          //Chrome no longer supports offsetWidth/offsetHeight on SVG elements.
1251          return (cs || _getComputedStyle(t))[p] || 0;
1252        } else if (t.getCTM && _isSVG(t)) {
1253          return t.getBBox()[p] || 0;
1254        }
1255        var v = parseFloat(p === "width" ? t.offsetWidth : t.offsetHeight),
1256          a = _dimensions[p],
1257          i = a.length;
1258        cs = cs || _getComputedStyle(t, null);
1259        while (--i > -1) {
1260          v -= parseFloat(_getStyle(t, "padding" + a[i], cs, true)) || 0;
1261          v -= parseFloat(_getStyle(t, "border" + a[i] + "Width", cs, true)) || 0;
1262        }
1263        return v;
1264      },
1265      // @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)
1266      _parsePosition2 = function _parsePosition(v, recObj) {
1267        if (v === "contain" || v === "auto" || v === "auto auto") {
1268          //note: Firefox uses "auto auto" as default whereas Chrome uses "auto".
1269          return v + " ";
1270        }
1271        if (v == null || v === "") {
1272          v = "0 0";
1273        }
1274        var a = v.split(" "),
1275          x = v.indexOf("left") !== -1 ? "0%" : v.indexOf("right") !== -1 ? "100%" : a[0],
1276          y = v.indexOf("top") !== -1 ? "0%" : v.indexOf("bottom") !== -1 ? "100%" : a[1],
1277          i;
1278        if (a.length > 3 && !recObj) {
1279          //multiple positions
1280          a = v.split(", ").join(",").split(",");
1281          v = [];
1282          for (i = 0; i < a.length; i++) {
1283            v.push(_parsePosition2(a[i]));
1284          }
1285          return v.join(",");
1286        }
1287        if (y == null) {
1288          y = x === "center" ? "50%" : "0";
1289        } else if (y === "center") {
1290          y = "50%";
1291        }
1292        if (x === "center" || isNaN(parseFloat(x)) && (x + "").indexOf("=") === -1) {
1293          //remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it c
1293ould be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative.
1294          x = "50%";
1295        }
1296        v = x + " " + y + (a.length > 2 ? " " + a[2] : "");
1297        if (recObj) {
1298          recObj.oxp = x.indexOf("%") !== -1;
1299          recObj.oyp = y.indexOf("%") !== -1;
1300          recObj.oxr = x.charAt(1) === "=";
1301          recObj.oyr = y.charAt(1) === "=";
1302          recObj.ox = parseFloat(x.replace(_NaNExp, ""));
1303          recObj.oy = parseFloat(y.replace(_NaNExp, ""));
1304          recObj.v = v;
1305        }
1306        return recObj || v;
1307      },
1308      /**
1309       * @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!)
1310       * @param {(number|string)} e End value which is typically a string, but could be a number
1311       * @param {(number|string)} b Beginning value which is typically a string but could be a number
1312       * @return {number} Amount of change between the beginning and ending values (relative values that have a "+=" or "-=" are recognized)
1313       */
1314      _parseChange = function _parseChange(e, b) {
1315        if (typeof e === "function") {
1316          e = e(_index, _target);
1317        }
1318        return typeof e === "string" && e.charAt(1) === "=" ? parseInt(e.charAt(0) + "1", 10) * parseFloat(e.substr(2)) : parseFloat(e) - parseFloat(b) || 0;
1319      },
1320      /**
1321       * @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.
1322       * @param {Object} v Value to be parsed
1323       * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
1324       * @return {number} Parsed value
1325       */
1326      _parseVal = function _parseVal(v, d) {
1327        if (typeof v === "function") {
1328          v = v(_index, _target);
1329        }
1330        return v == null ? d : typeof v === "string" && v.charAt(1) === "=" ? parseInt(v.charAt(0) + "1", 10) * parseFloat(v.substr(2)) + d : parseFloat(v) || 0;
1331      },
1332      /**
1333       * @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.
1334       * @param {Object} v Value to be parsed
1335       * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
1336       * @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"
1337       * @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.
1338       * @return {number} parsed angle in radians
1339       */
1340      _parseAngle = function _parseAngle(v, d, p, directionalEnd) {
1341        var min = 0.000001,
1342          cap,
1343          split,
1344          dif,
1345          result,
1346          isRelative;
1347        if (typeof v === "function") {
1348          v = v(_index, _target);
1349        }
1350        if (v == null) {
1351          result = d;
1352        } else if (typeof v === "number") {
1353          result = v;
1354        } else {
1355          cap = 360;
1356          split = v.split("_");
1357          isRelative = v.charAt(1) === "=";
1358          dif = (isRelative ? parseInt(v.charAt(0) + "1", 10) * parseFloat(split[0].substr(2)) : parseFloat(split[0])
1358) * (v.indexOf("rad") === -1 ? 1 : _RAD2DEG) - (isRelative ? 0 : d);
1359          if (split.length) {
1360            if (directionalEnd) {
1361              directionalEnd[p] = d + dif;
1362            }
1363            if (v.indexOf("short") !== -1) {
1364              dif = dif % cap;
1365              if (dif !== dif % (cap / 2)) {
1366                dif = dif < 0 ? dif + cap : dif - cap;
1367              }
1368            }
1369            if (v.indexOf("_cw") !== -1 && dif < 0) {
1370              dif = (dif + cap * 9999999999) % cap - (dif / cap | 0) * cap;
1371            } else if (v.indexOf("ccw") !== -1 && dif > 0) {
1372              dif = (dif - cap * 9999999999) % cap - (dif / cap | 0) * cap;
1373            }
1374          }
1375          result = d + dif;
1376        }
1377        if (result < min && result > -min) {
1378          result = 0;
1379        }
1380        return result;
1381      },
1382      _colorLookup = {
1383        aqua: [0, 255, 255],
1384        lime: [0, 255, 0],
1385        silver: [192, 192, 192],
1386        black: [0, 0, 0],
1387        maroon: [128, 0, 0],
1388        teal: [0, 128, 128],
1389        blue: [0, 0, 255],
1390        navy: [0, 0, 128],
1391        white: [255, 255, 255],
1392        fuchsia: [255, 0, 255],
1393        olive: [128, 128, 0],
1394        yellow: [255, 255, 0],
1395        orange: [255, 165, 0],
1396        gray: [128, 128, 128],
1397        purple: [128, 0, 128],
1398        green: [0, 128, 0],
1399        red: [255, 0, 0],
1400        pink: [255, 192, 203],
1401        cyan: [0, 255, 255],
1402        transparent: [255, 255, 255, 0]
1403      },
1404      _hue = function _hue(h, m1, m2) {
1405        h = h < 0 ? h + 1 : h > 1 ? h - 1 : h;
1406        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;
1407      },
1408      /**
1409       * @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).
1410       * @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.
1411       * @param {(boolean)} toHSL If true, an hsl() or hsla() value will be returned instead of rgb() or rgba()
1412       * @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.
1413       */
1414      _parseColor = _CSSPlugin.parseColor = function (v, toHSL) {
1415        var a, r, g, b, h, s, l, max, min, d, wasHSL;
1416        if (!v) {
1417          a = _colorLookup.black;
1418        } else if (typeof v === "number") {
1419          a = [v >> 16, v >> 8 & 255, v & 255];
1420        } else {
1421          if (v.charAt(v.length - 1) === ",") {
1422            //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.
1423            v = v.substr(0, v.length - 1);
1424          }
1425          if (_colorLookup[v]) {
1426            a = _colorLookup[v];
1427          } else if (v.charAt(0) === "#") {
1428            if (v.length === 4) {
1429              //for shorthand like #9F0
1430              r = v.charAt(1);
1431              g = v.charAt(2);
1432              b = v.charAt(3);
1433              v = "#" + r + r + g + g + b + b;
1434            }
1435            v = parseInt(v.substr(1), 16);
1436            a = [v >> 16, v >> 8 & 255, v & 255];
1437          } else if (v.substr(0, 3) === "hsl") {
1438            a = wasHSL = v.match(_numExp);
1439            if (!toHSL) {
1440              h = Number(a[0]) % 360 / 360;
1441              s = Number(a[1]) / 100;
1442              l = Number(a[2]) / 100;
1443              g = l <= 0.5 ? l * (s + 1) : l + s - l * s;
1444              r = l * 2 - g;
1445              if (a.length > 3) {
1446                a[3] = Number(a[3]);
1447              }
1448              a[0] = _hue(h + 1 / 3, r, g);
1449              a[1] = _hue(h, r, g);
1450              a[2] = _hue(h - 1 / 3, r, g);
1451            } else if (v.indexOf("=") !== -1) {
1452              //if relative values are found, just return the raw strings with the relative prefixes in place.
1453              return v.match(_relNumExp);
1454            }
1455          } else {
1456            a = v.match(_numExp) || _colorLookup.transparent;
1457          }
1458          a[0] = Number(a[0]);
1459          a[1] = Number(a[1]);
1460          a[2] = Number(a[2]);
1461          if (a.length > 3) {
1462            a[3] = Number(a[3]);
1463          }
1464        }
1465        if (toHSL && !wasHSL) {
1466          r = a[0] / 255;
1467          g = a[1] / 255;
1468          b = a[2] / 255;
1469          max = Math.max(r, g, b);
1470          min = Math.min(r, g, b);
1471          l = (max + min) / 2;
1472          if (max === min) {
1473            h = s = 0;
1474          } else {
1475            d = max - min;
1476            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1477            h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
1478            h *= 60;
1479          }
1480          a[0] = h + 0.5 | 0;
1481          a[1] = s * 100 + 0.5 | 0;
1482          a[2] = l * 100 + 0.5 | 0;
1483        }
1484        return a;
1485      },
1486      _formatColors = function _formatColors(s, toHSL) {
1487        var colors = s.match(_colorExp) || [],
1488          charIndex = 0,
1489          parsed = "",
1490          i,
1491          color,
1492          temp;
1493        if (!colors.length) {
1494          return s;
1495        }
1496        for (i = 0; i < colors.length; i++) {
1497          color = colors[i];
1498          temp = s.substr(charIndex, s.indexOf(color, charIndex) - charIndex);
1499          charIndex += temp.length + color.length;
1500          color = _parseColor(color, toHSL);
1501          if (color.length === 3) {
1502            color.push(1);
1503          }
1504          parsed += temp + (toHSL ? "hsla(" + color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : "rgba(" + color.
1504join(",")) + ")";
1505        }
1506        return parsed + s.substr(charIndex);
1507      },
1508      _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.
1509
1510    for (p in _colorLookup) {
1511      _colorExp += "|" + p + "\\b";
1512    }
1513    _colorExp = new RegExp(_colorExp + ")", "gi");
1514    _CSSPlugin.colorStringFilter = function (a) {
1515      var combined = a[0] + " " + a[1],
1516        toHSL;
1517      if (_colorExp.test(combined)) {
1518        toHSL = combined.indexOf("hsl(") !== -1 || combined.indexOf("hsla(") !== -1;
1519        a[0] = _formatColors(a[0], toHSL);
1520        a[1] = _formatColors(a[1], toHSL);
1521      }
1522      _colorExp.lastIndex = 0;
1523    };
1524    if (!TweenLite.defaultStringFilter) {
1525      TweenLite.defaultStringFilter = _CSSPlugin.colorStringFilter;
1526    }
1527
1528    /**
1529     * @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.
1530     * @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.
1531     * @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.
1532     * @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.
1533     * @return {Function} formatter function
1534     */
1535    var _getFormatter = function _getFormatter(dflt, clr, collapsible, multi) {
1536        if (dflt == null) {
1537          return function (v) {
1538            return v;
1539          };
1540        }
1541        var dColor = clr ? (dflt.match(_colorExp) || [""])[0] : "",
1542          dVals = dflt.split(dColor).join("").match(_valuesExp) || [],
1543          pfx = dflt.substr(0, dflt.indexOf(dVals[0])),
1544          sfx = dflt.charAt(dflt.length - 1) === ")" ? ")" : "",
1545          delim = dflt.indexOf(" ") !== -1 ? " " : ",",
1546          numVals = dVals.length,
1547          dSfx = numVals > 0 ? dVals[0].replace(_numExp, "") : "",
1548          _formatter2;
1549        if (!numVals) {
1550          return function (v) {
1551            return v;
1552          };
1553        }
1554        if (clr) {
1555          _formatter2 = function formatter(v) {
1556            var color, vals, i, a;
1557            if (typeof v === "number") {
1558              v += dSfx;
1559            } else if (multi && _commasOutsideParenExp.test(v)) {
1560              a = v.replace(_commasOutsideParenExp, "|").split("|");
1561              for (i = 0; i < a.length; i++) {
1562                a[i] = _formatter2(a[i]);
1563              }
1564              return a.join(",");
1565            }
1566            color = (v.match(_colorExp) || [dColor])[0];
1567            vals = v.split(color).join("").match(_valuesExp) || [];
1568            i = vals.length;
1569            if (numVals > i--) {
1570              while (++i < numVals) {
1571                vals[i] = collapsible ? vals[(i - 1) / 2 | 0] : dVals[i];
1572              }
1573            }
1574            return pfx + vals.join(delim) + delim + color + sfx + (v.indexOf("inset") !== -1 ? " inset" : "");
1575          };
1576          return _formatter2;
1577        }
1578        _formatter2 = function _formatter(v) {
1579          var vals, a, i;
1580          if (typeof v === "number") {
1581            v += dSfx;
1582          } else if (multi && _commasOutsideParenExp.test(v)) {
1583            a = v.replace(_commasOutsideParenExp, "|").split("|");
1584            for (i = 0; i < a.length; i++) {
1585              a[i] = _formatter2(a[i]);
1586            }
1587            return a.join(",");
1588          }
1589          vals = v.match(_valuesExp) || [];
1590          i = vals.length;
1591          if (numVals > i--) {
1592            while (++i < numVals) {
1593              vals[i] = collapsible ? vals[(i - 1) / 2 | 0] : dVals[i];
1594            }
1595          }
1596          return pfx + vals.join(delim) + sfx;
1597        };
1598        return _formatter2;
1599      },
1600      /**
1601       * @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.
1602       * @param {!string} props a comma-delimited list of property names in order from top to left, like "marginTop,marginRight,marginBottom,marginLeft"
1603       * @return {Function} a formatter function
1604       */
1605      _getEdgeParser = function _getEdgeParser(props) {
1606        props = props.split(",");
1607        return function (t, e, p, cssp, pt, plugin, vars) {
1608          var a = (e + "").split(" "),
1609            i;
1610          vars = {};
1611          for (i = 0; i < 4; i++) {
1612            vars[props[i]] = a[i] = a[i] || a[(i - 1) / 2 >> 0];
1613          }
1614          return cssp.parse(t, vars, pt, plugin);
1615        };
1616      },
1617      // @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.
1618      _setPluginRatio = _internals._setPluginRatio = function (v) {
1619        this.plugin.setRatio(v);
1620        var d = this.data,
1621          proxy = d.proxy,
1622          mpt = d.firstMPT,
1623          min = 0.000001,
1624          val,
1625          pt,
1626          i,
1627          str,
1628          p;
1629        while (mpt) {
1630          val = proxy[mpt.v];
1631          if (mpt.r) {
1632            val = Math.round(val);
1633          } else if (val < min && val > -min) {
1634            val = 0;
1635          }
1636          mpt.t[mpt.p] = val;
1637          mpt = mpt._next;
1638        }
1639        if (d.autoRotate) {
1640          d.autoRotate.rotation = d.mod ? d.mod(proxy.rotation, this.t) : proxy.rotation; //special case for ModifyPlugin to hook into an auto-rotating bezier
1641        }
1642        //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.
1643        if (v === 1 || v === 0) {
1644          mpt = d.firstMPT;
1645          p = v === 1 ? "e" : "b";
1646          while (mpt) {
1647            pt = mpt.t;
1648            if (!pt.type) {
1649              pt[p] = pt.s + pt.xs0;
1650            } else if (pt.type === 1) {
1651              str = pt.xs0 + pt.s + pt.xs1;
1652              for (i = 1; i < pt.l; i++) {
1653                str += pt["xn" + i] + pt["xs" + (i + 1)];
1654              }
1655              pt[p] = str;
1656            }
1657            mpt = mpt._next;
1658          }
1659        }
1660      },
1661      /**
1662       * @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
1662ded plus the original value.
1663       * @param {!Object} t target object whose property we're tweening (often a CSSPropTween)
1664       * @param {!string} p property name
1665       * @param {(number|string|object)} v value
1666       * @param {MiniPropTween=} next next MiniPropTween in the linked list
1667       * @param {boolean=} r if true, the tweened value should be rounded to the nearest integer
1668       */
1669      MiniPropTween = function MiniPropTween(t, p, v, next, r) {
1670        this.t = t;
1671        this.p = p;
1672        this.v = v;
1673        this.r = r;
1674        if (next) {
1675          next._prev = this;
1676          this._next = next;
1677        }
1678      },
1679      /**
1680       * @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.
1681       * This method returns an object that has the following properties:
1682       *  - 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
1683       *  - 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
1684       *  - firstMPT: the first MiniPropTween in the linked list
1685       *  - 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.
1686       * @param {!Object} t target object to be tweened
1687       * @param {!(Object|string)} vars the object containing the information about the tweening values (typically the end/destination values) that should be parsed
1688       * @param {!CSSPlugin} cssp The CSSPlugin instance
1689       * @param {CSSPropTween=} pt the next CSSPropTween in the linked list
1690       * @param {TweenPlugin=} plugin the external TweenPlugin instance that will be handling tweening the numeric values
1691       * @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.
1692       * @return An object containing the following properties: proxy, end, firstMPT, and pt (see above for descriptions)
1693       */
1694      _parseToProxy = _internals._parseToProxy = function (t, vars, cssp, pt, plugin, shallow) {
1695        var bpt = pt,
1696          start = {},
1697          end = {},
1698          transform = cssp._transform,
1699          oldForce = _forcePT,
1700          i,
1701          p,
1702          xp,
1703          mpt,
1704          firstPT;
1705        cssp._transform = null;
1706        _forcePT = vars;
1707        pt = firstPT = cssp.parse(t, vars, pt, plugin);
1708        _forcePT = oldForce;
1709        //break off from the linked list so the new ones are isolated.
1710        if (shallow) {
1711          cssp._transform = transform;
1712          if (bpt) {
1713            bpt._prev = null;
1714            if (bpt._prev) {
1715              bpt._prev._next = null;
1716            }
1717          }
1718        }
1719        while (pt && pt !== bpt) {
1720          if (pt.type <= 1) {
1721            p = pt.p;
1722            end[p] = pt.s + pt.c;
1723            start[p] = pt.s;
1724            if (!shallow) {
1725              mpt = new MiniPropTween(pt, "s", p, mpt, pt.r);
1726              pt.c = 0;
1727            }
1728            if (pt.type === 1) {
1729              i = pt.l;
1730              while (--i > 0) {
1731                xp = "xn" + i;
1732                p = pt.p + "_" + xp;
1733                end[p] = pt.data[xp];
1734                start[p] = pt[xp];
1735                if (!shallow) {
1736                  mpt = new MiniPropTween(pt, xp, p, mpt, pt.rxp[xp]);
1737                }
1738              }
1739            }
1740          }
1741          pt = pt._next;
1742        }
1743        return {
1744          proxy: start,
1745          end: end,
1746          firstMPT: mpt,
1747          pt: firstPT
1748        };
1749      },
1750      /**
1751       * @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.
1752       * CSSPropTweens have the following optional properties as well (not defined through the constructor):
1753       *  - 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.
1754       *  - 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)
1755       *  - plugin: The TweenPlugin instance that will handle the tweening of any complex values. For example, sometimes we don't want to use normal subt
1755weens (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.
1756       *  - 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.
1757       *  - 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.
1758       * @param {!Object} t Target object whose property will be tweened. Often a DOM element, but not always. It could be anything.
1759       * @param {string} p Property to tween (name). For example, to tween element.width, p would be "width".
1760       * @param {number} s Starting numeric value
1761       * @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.
1762       * @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.
1763       * @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.
1764       * @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"
1765       * @param {boolean=} r If true, the value(s) should be rounded
1766       * @param {number=} pr Priority in the linked list order. Higher priority CSSPropTweens will be updated before lower priority ones. The default priority is 0.
1767       * @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.
1768       * @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.
1769       */
1770      CSSPropTween = _internals.CSSPropTween = function (t, p, s, c, next, type, n, r, pr, b, e) {
1771        this.t = t; //target
1772        this.p = p; //property
1773        this.s = s; //starting value
1774        this.c = c; //change value
1775        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)
1776        if (!(t instanceof CSSPropTween)) {
1777          _overwriteProps.push(this.n);
1778        }
1779        this.r = r; //round (boolean)
1780        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
1781        if (pr) {
1782          this.pr = pr;
1783          _hasPriority = true;
1784        }
1785        this.b = b === undefined ? s : b;
1786        this.e = e === undefined ? s + c : e;
1787        if (next) {
1788          this._next = next;
1789          next._prev = this;
1790        }
1791      },
1792      _addNonTweeningNumericPT = function _addNonTweeningNumericPT(target, prop, start, end, next, overwriteProp) {
1793        //cleans up some code redundancies and helps minification. Just a fast way to add a NUMERIC non-tweening CSSPropTween
1794        var pt = new CSSPropTween(target, prop, start, end - start, next, -1, overwriteProp);
1795        pt.b = start;
1796        pt.e = pt.xs0 = end;
1797        return pt;
1798      },
1799      /**
1800       * 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:
1801       * 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);
1802       * 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().
1803       * 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.
1804       *
1805       * @param {!Object} t Target whose property will be tweened
1806       * @param {!string} p Property that will be tweened (its name, like "left" or "backgroundColor" or "boxShadow")
1807       * @param {string} b Beginning value
1808       * @param {string} e Ending value
1809       * @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)
1810       * @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
1811       * @param {?CSSPropTween} pt CSSPropTween instance that is the current head of the linked list (we'll prepend to this).
1812       * @param {number=} pr Priority in the linked list order. Higher priority properties will be updated before lower priority ones. The default priority is 0.
1813       * @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}
1814       * @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.
1815       * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parseComplex() call.
1816       */
1817      _parseComplex = _CSSPlugin.parseComplex = function (t, p, b, e, clrs, dflt, pt, pr, plugin, setRatio) {
1818        //DEBUG: _log("parseComplex: "+p+", b: "+b+", e: "+e);
1819        b = b || dflt || "";
1820        if (typeof e === "function") {
1821          e = e(_index, _target);
1822        }
1823        pt = new CSSPropTween(t, p, 0, 0, pt, setRatio ? 2 : 1, null, false, pr, b, e);
1824        e += ""; //ensures it's a string
1825        if (clrs && _colorExp.test(e + b)) {
1826          //if colors are found, normalize the formatting to rgba() or hsla().
1827          e = [b, e];
1828          _CSSPlugin.colorStringFilter(e);
1829          b = e[0];
1830          e = e[1];
1831        }
1832        var ba = b.split(", ").join(",").split(" "),
1833          //beginning array
1834          ea = e.split(", ").join(",").split(" "),
1835          //ending array
1836          l = ba.length,
1837          autoRound = _autoRound !== false,
1838          i,
1839          xi,
1840          ni,
1841          bv,
1842          ev,
1843          bnums,
1844          enums,
1845          bn,
1846          hasAlpha,
1847          temp,
1848          cv,
1849          str,
1850          useHSL;
1851        if (e.indexOf(",") !== -1 || b.indexOf(",") !== -1) {
1852          if ((e + b).indexOf("rgb") !== -1 || (e + b).indexOf("hsl") !== -1) {
1853            //keep rgb(), rgba(), hsl(), and hsla() values together! (remember, we're splitting on spaces)
1854            ba = ba.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
1855            ea = ea.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
1856          } else {
1857            ba = ba.join(" ").split(",").join(", ").split(" ");
1858            ea = ea.join(" ").split(",").join(", ").split(" ");
1859          }
1860          l = ba.length;
1861        }
1862        if (l !== ea.length) {
1863          //DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
1864          ba = (dflt || "").split(" ");
1865          l = ba.length;
1866        }
1867        pt.plugin = plugin;
1868        pt.setRatio = setRatio;
1869        _colorExp.lastIndex = 0;
1870        for (i = 0; i < l; i++) {
1871          bv = ba[i];
1872          ev = ea[i];
1873          bn = parseFloat(bv);
1874          //if the value begins with a number (most common). It's fine if it has a suffix like px
1875          if (bn || bn === 0) {
1876            pt.appendXtra("", bn, _parseChange(ev, bn), ev.replace(_relNumExp, ""), autoRound && ev.indexOf("px") !== -1, true);
1877
1878            //if the value is a color
1879          } else if (clrs && _colorExp.test(bv)) {
1880            str = ev.indexOf(")") + 1;
1881            str = ")" + (str ? ev.substr(str) : ""); //if there's a comma or ) at the end, retain it.
1882            useHSL = ev.indexOf("hsl") !== -1 && _supportsOpacity;
1883            temp = ev; //original string value so we can look for any prefix later.
1884            bv = _parseColor(bv, useHSL);
1885            ev = _parseColor(ev, useHSL);
1886            hasAlpha = bv.length + ev.length > 6;
1887            if (hasAlpha && !_supportsOpacity && ev[3] === 0) {
1888              //older versions of IE don't support rgba(), so if the destination alpha is 0, just use "transparent" for the end color
1889              pt["xs" + pt.l] += pt.l ? " transparent" : "transparent";
1890              pt.e = pt.e.split(ea[i]).join("transparent");
1891            } else {
1892              if (!_supportsOpacity) {
1893                //old versions of IE don't support rgba().
1894                hasAlpha = false;
1895              }
1896              if (useHSL) {
1897                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);
1898              } else {
1899                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);
1900              }
1901              if (hasAlpha) {
1902                bv = bv.length < 4 ? 1 : bv[3];
1903                pt.appendXtra("", bv, (ev.length < 4 ? 1 : ev[3]) - bv, str, false);
1904              }
1905            }
1906            _colorExp.lastIndex = 0; //otherwise the test() on the RegExp could move the lastIndex and taint future results.
1907          } else {
1908            bnums = bv.match(_numExp); //gets each group of numbers in the beginning value string and drops them into an array
1909
1910            //if no number is found, treat it as a non-tweening value and just append the string to the current xs.
1911            if (!bnums) {
1912              pt["xs" + pt.l] += pt.l || pt["xs" + pt.l] ? " " + ev : ev;
1913
1914              //loop through all the numbers that are found and construct the extra values on the pt.
1915            } else {
1916              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
1917              if (!enums || enums.length !== bnums.length) {
1918                //DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
1919                return pt;
1920              }
1921              ni = 0;
1922              for (xi = 0; xi < bnums.length; xi++) {
1923                cv = bnums[xi];
1924                temp = bv.indexOf(cv, ni);
1925                pt.appendXtra(bv.substr(ni, temp - ni), Number(cv), _parseChange(enums[xi], cv), "", autoRound && bv.substr(temp + cv.length, 2) === "px", xi === 0);
1926                ni = temp + cv.length;
1927              }
1928              pt["xs" + pt.l] += bv.substr(ni);
1929            }
1930          }
1931        }
1932        //if there are relative values ("+=" or "-=" prefix), we need to adjust the ending value to eliminate the prefixes and combine the values properly.
1933        if (e.indexOf("=") !== -1) if (pt.data) {
1934          str = pt.xs0 + pt.data.s;
1935          for (i = 1; i < pt.l; i++) {
1936            str += pt["xs" + i] + pt.data["xn" + i];
1937          }
1938          pt.e = str + pt["xs" + i];
1939        }
1940        if (!pt.l) {
1941          pt.type = -1;
1942          pt.xs0 = pt.e;
1943        }
1944        return pt.xfirst || pt;
1945      },
1946      i = 9;
1947    p = CSSPropTween.prototype;
1948    p.l = p.pr = 0; //length (number of extra properties like xn1, xn2, xn3, etc.
1949    while (--i > 0) {
1950      p["xn" + i] = 0;
1951      p["xs" + i] = "";
1952    }
1953    p.xs0 = "";
1954    p._next = p._prev = p.xfirst = p.data = p.plugin = p.setRatio = p.rxp = null;
1955
1956    /**
1957     * 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:
1958     * xs0:"rect(", s:10, xs1:"px, ", xn1:5, xs2:"px, ", xn2:0, xs3:"px, ", xn3:20, xn4:"px)"
1959     * And they'd all get joined together when the CSSPlugin renders (in the setRatio() method).
1960     * @param {string=} pfx Prefix (if any)
1961     * @param {!number} s Starting value
1962     * @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.
1963     * @param {string=} sfx Suffix (if any)
1964     * @param {boolean=} r Round (if true).
1965     * @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.
1966     * @return {CSSPropTween} returns itself so that multiple methods can be chained together.
1967     */
1968    p.appendXtra = function (pfx, s, c, sfx, r, pad) {
1969      var pt = this,
1970        l = pt.l;
1971      pt["xs" + l] += pad && (l || pt["xs" + l]) ? " " + pfx : pfx || "";
1972      if (!c) if (l !== 0 && !pt.plugin) {
1973        //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!
1974        pt["xs" + l] += s + (sfx || "");
1975        return pt;
1976      }
1977      pt.l++;
1978      pt.type = pt.setRatio ? 2 : 1;
1979      pt["xs" + pt.l] = sfx || "";
1980      if (l > 0) {
1981        pt.data["xn" + l] = s + c;
1982        pt.rxp["xn" + l] = r; //round extra property (we need to tap into this in the _parseToProxy() method)
1983        pt["xn" + l] = s;
1984        if (!pt.plugin) {
1985          pt.xfirst = new CSSPropTween(pt, "xn" + l, s, c, pt.xfirst || pt, 0, pt.n, r, pt.pr);
1986          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.
1987        }
1988        return pt;
1989      }
1990      pt.data = {
1991        s: s + c
1992      };
1993      pt.rxp = {};
1994      pt.s = s;
1995      pt.c = c;
1996      pt.r = r;
1997      return pt;
1998    };
1999
2000    /**
2001     * @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.
2002     * @param {!string} p Property name (like "boxShadow" or "throwProps")
2003     * @param {Object=}
2003 options An object containing any of the following configuration options:
2004     *                      - defaultValue: the default value
2005     *                      - 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)
2006     *                      - 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.)
2007     *                      - prefix: if true, we'll determine whether or not this property requires a vendor prefix (like Webkit or Moz or ms or O)
2008     *                      - color: set this to true if the value for this SpecialProp may contain color-related values like rgb(), rgba(), etc.
2009     *                      - priority: priority in the linked list order. Higher priority SpecialProps will be updated before lower priority ones. The default priority is 0.
2010     *                      - multi: if true, the formatter should accommodate a comma-delimited list of values, like boxShadow could have multiple boxShadows listed out.
2011     *                      - 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.
2012     *                      - 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).
2013     */
2014    var SpecialProp = function SpecialProp(p, options) {
2015        options = options || {};
2016        this.p = options.prefix ? _checkPropPrefix(p) || p : p;
2017        _specialProps[p] = _specialProps[this.p] = this;
2018        this.format = options.formatter || _getFormatter(options.defaultValue, options.color, options.collapsible, options.multi);
2019        if (options.parser) {
2020          this.parse = options.parser;
2021        }
2022        this.clrs = options.color;
2023        this.multi = options.multi;
2024        this.keyword = options.keyword;
2025        this.dflt = options.defaultValue;
2026        this.pr = options.priority || 0;
2027      },
2028      //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.
2029      _registerComplexSpecialProp = _internals._registerComplexSpecialProp = function (p, options, defaults) {
2030        if (_typeof(options) !== "object") {
2031          options = {
2032            parser: defaults
2033          }; //to make backwards compatible with older versions of BezierPlugin and ThrowPropsPlugin
2034        }
2035        var a = p.split(","),
2036          d = options.defaultValue,
2037          i,
2038          temp;
2039        defaults = defaults || [d];
2040        for (i = 0; i < a.length; i++) {
2041          options.prefix = i === 0 && options.prefix;
2042          options.defaultValue = defaults[i] || d;
2043          temp = new SpecialProp(a[i], options);
2044        }
2045      },
2046      //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.
2047      _registerPluginProp = _internals._registerPluginProp = function (p) {
2048        if (!_specialProps[p]) {
2049          var pluginName = p.charAt(0).toUpperCase() + p.substr(1) + "Plugin";
2050          _registerComplexSpecialProp(p, {
2051            parser: function parser(t, e, p, cssp, pt, plugin, vars) {
2052              var pluginClass = _globals.com.greensock.plugins[pluginName];
2053              if (!pluginClass) {
2054                _log("Error: " + pluginName + " js file not loaded.");
2055                return pt;
2056              }
2057              pluginClass._cssRegister();
2058              return _specialProps[p].parse(t, e, p, cssp, pt, plugin, vars);
2059            }
2060          });
2061        }
2062      };
2063    p = SpecialProp.prototype;
2064
2065    /**
2066     * 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
2066adow) 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)
2067     * @param {!Object} t target element
2068     * @param {(string|number|object)} b beginning value
2069     * @param {(string|number|object)} e ending (destination) value
2070     * @param {CSSPropTween=} pt next CSSPropTween in the linked list
2071     * @param {TweenPlugin=} plugin If another plugin will be tweening the complex value, that TweenPlugin instance goes here.
2072     * @param {function=} setRatio If a custom setRatio() method should be used to handle this complex value, that goes here.
2073     * @return {CSSPropTween=} First CSSPropTween in the linked list
2074     */
2075    p.parseComplex = function (t, b, e, pt, plugin, setRatio) {
2076      var kwd = this.keyword,
2077        i,
2078        ba,
2079        ea,
2080        l,
2081        bi,
2082        ei;
2083      //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)
2084      if (this.multi) if (_commasOutsideParenExp.test(e) || _commasOutsideParenExp.test(b)) {
2085        ba = b.replace(_commasOutsideParenExp, "|").split("|");
2086        ea = e.replace(_commasOutsideParenExp, "|").split("|");
2087      } else if (kwd) {
2088        ba = [b];
2089        ea = [e];
2090      }
2091      if (ea) {
2092        l = ea.length > ba.length ? ea.length : ba.length;
2093        for (i = 0; i < l; i++) {
2094          b = ba[i] = ba[i] || this.dflt;
2095          e = ea[i] = ea[i] || this.dflt;
2096          if (kwd) {
2097            bi = b.indexOf(kwd);
2098            ei = e.indexOf(kwd);
2099            if (bi !== ei) {
2100              if (ei === -1) {
2101                //if the keyword isn't in the end value, remove it from the beginning one.
2102                ba[i] = ba[i].split(kwd).join("");
2103              } else if (bi === -1) {
2104                //if the keyword isn't in the beginning, add it.
2105                ba[i] += " " + kwd;
2106              }
2107            }
2108          }
2109        }
2110        b = ba.join(", ");
2111        e = ea.join(", ");
2112      }
2113      return _parseComplex(t, this.p, b, e, this.clrs, this.dflt, pt, this.pr, plugin, setRatio);
2114    };
2115
2116    /**
2117     * 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:
2118     * this._firstPT = sp.parse(element, "5px 10px 20px rgb(2550,102,51)", "boxShadow", this);
2119     * 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).
2120     * @param {!Object} t Target object whose property is being tweened
2121     * @param {Object} e End value as provided in the vars object (typically a string, but not always - like a throwProps would be an object).
2122     * @param {!string} p Property name
2123     * @param {!CSSPlugin} cssp The CSSPlugin instance that should be associated with this tween.
2124     * @param {?CSSPropTween} pt The CSSPropTween that is the current head of the linked list (we'll prepend to it)
2125     * @param {TweenPlugin=} plugin If a plugin will be used to tween the parsed value, this is the plugin instance.
2126     * @param {Object=} vars Original vars object that contains the data for parsing.
2127     * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parse() call.
2128     */
2129    p.parse = function (t, e, p, cssp, pt, plugin, vars) {
2130      return this.parseComplex(t.style, this.format(_getStyle(t, this.p, _cs, false, this.dflt)), this.format(e), pt, plugin);
2131    };
2132
2133    /**
2134     * 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:
2135     *  1) Target object whose property should be tweened (typically a DOM element)
2136     *  2) The end/destination value (could be a string, number, object, or whatever you want)
2137     *  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)
2138     *
2139     * 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:
2140     *
2141     * CSSPlugin.registerSpecialProp("myCustomProp", function(target, value, tween) {
2142     *      var start = target.style.width;
2143     *      return function(ratio) {
2144     *              target.style.width = (start + value * ratio) + "px";
2145     *              console.log("set width to " + target.style.width);
2146     *          }
2147     * }, 0);
2148     *
2149     * Then, when I do this tween, it will trigger my special property:
2150     *
2151     * TweenLite.to(element, 1, {css:{myCustomProp:100}});
2152     *
2153     * In the example, of course, we're just changing the width, but you can do anything you want.
2154     *
2155     * @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}})
2156     * @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.
2157     * @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.
2158     */
2159    _CSSPlugin.registerSpecialProp = function (name, onInitTween, priority) {
2160      _registerComplexSpecialProp(name, {
2161        parser: function parser(t, e, p, cssp, pt, plugin, vars) {
2162          var rv = new CSSPropTween(t, p, 0, 0, pt, 2, p, false, priority);
2163          rv.plugin = plugin;
2164          rv.setRatio = onInitTween(t, e, cssp._tween, p);
2165          return rv;
2166        },
2167        priority: priority
2168      });
2169    };
2170
2171    //transform-related methods and properties
2172    _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).
2173    var _transformProps = "scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent".split(","),
2174      _transformProp = _checkPropPrefix("transform"),
2175      //the Javascript (camelCase) transform property, like msTransform, WebkitTransform, MozTransform, or OTransform.
2176      _transformPropCSS = _prefixCSS + "transform",
2177      _transformOriginProp = _checkPropPrefix("transformOrigin"),
2178      _supports3D = _checkPropPrefix("perspective") !== null,
2179      Transform = _internals.Transform = function () {
2180        this.perspective = parseFloat(_CSSPlugin.defaultTransformPerspective) || 0;
2181        this.force3D = _CSSPlugin.defaultForce3D === false || !_supports3D ? false : _CSSPlugin.defaultForce3D || "auto";
2182      },
2183      _SVGElement = _gsScope.SVGElement,
2184      _useSVGTransformAttr,
2185      //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.
2186
2187      _createSVG = function _createSVG(type, container, attributes) {
2188        var element = _doc.createElementNS("http://www.w3.org/2000/svg", type),
2189          reg = /([a-z])([A-Z])/g,
2190          p;
2191        for (p in attributes) {
2192          element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]);
2193        }
2194        container.appendChild(element);
2195        return element;
2196      },
2197      _docElement = _doc.documentElement || {},
2198      _forceSVGTransformAttr = function () {
2199        //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
2200        var force = _ieVers || /Android/i.test(_agent) && !_gsScope.chrome,
2201          svg,
2202          rect,
2203          width;
2204        if (_doc.createElementNS && !force) {
2205          //IE8 and earlier doesn't support SVG anyway
2206          svg = _createSVG("svg", _docElement);
2207          rect = _createSVG("rect", svg, {
2208            width: 100,
2209            height: 50,
2210            x: 100
2211          });
2212          width = rect.getBoundingClientRect().width;
2213          rect.style[_transformOriginProp] = "50% 50%";
2214          rect.style[_transformProp] = "scaleX(0.5)";
2215          force = width === rect.getBoundingClientRect().width && !(_is
2215Firefox && _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).
2216          _docElement.removeChild(svg);
2217        }
2218        return force;
2219      }(),
2220      _parseSVGOrigin = function _parseSVGOrigin(e, local, decoratee, absolute, smoothOrigin, skipRecord) {
2221        var tm = e._gsTransform,
2222          m = _getMatrix(e, true),
2223          v,
2224          x,
2225          y,
2226          xOrigin,
2227          yOrigin,
2228          a,
2229          b,
2230          c,
2231          d,
2232          tx,
2233          ty,
2234          determinant,
2235          xOriginOld,
2236          yOriginOld;
2237        if (tm) {
2238          xOriginOld = tm.xOrigin; //record the original values before we alter them.
2239          yOriginOld = tm.yOrigin;
2240        }
2241        if (!absolute || (v = absolute.split(" ")).length < 2) {
2242          b = e.getBBox();
2243          if (b.x === 0 && b.y === 0 && b.width + b.height === 0) {
2244            //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.
2245            b = {
2246              x: parseFloat(e.hasAttribute("x") ? e.getAttribute("x") : e.hasAttribute("cx") ? e.getAttribute("cx") : 0) || 0,
2247              y: parseFloat(e.hasAttribute("y") ? e.getAttribute("y") : e.hasAttribute("cy") ? e.getAttribute("cy") : 0) || 0,
2248              width: 0,
2249              height: 0
2250            };
2251          }
2252          local = _parsePosition2(local).split(" ");
2253          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];
2254        }
2255        decoratee.xOrigin = xOrigin = parseFloat(v[0]);
2256        decoratee.yOrigin = yOrigin = parseFloat(v[1]);
2257        if (absolute && m !== _identity2DMatrix) {
2258          //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.
2259          a = m[0];
2260          b = m[1];
2261          c = m[2];
2262          d = m[3];
2263          tx = m[4];
2264          ty = m[5];
2265          determinant = a * d - b * c;
2266          if (determinant) {
2267            //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.
2268            x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;
2269            y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;
2270            xOrigin = decoratee.xOrigin = v[0] = x;
2271            yOrigin = decoratee.yOrigin = v[1] = y;
2272          }
2273        }
2274        if (tm) {
2275          //avoid jump when transformOrigin is changed - adjust the x/y values accordingly
2276          if (skipRecord) {
2277            decoratee.xOffset = tm.xOffset;
2278            decoratee.yOffset = tm.yOffset;
2279            tm = decoratee;
2280          }
2281          if (smoothOrigin || smoothOrigin !== false && _CSSPlugin.defaultSmoothOrigin !== false) {
2282            x = xOrigin - xOriginOld;
2283            y = yOrigin - yOriginOld;
2284            //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.
2285            //tm.x -= x - (x * m[0] + y * m[2]);
2286            //tm.y -= y - (x * m[1] + y * m[3]);
2287            tm.xOffset += x * m[0] + y * m[2] - x;
2288            tm.yOffset += x * m[1] + y * m[3] - y;
2289          } else {
2290            tm.xOffset = tm.yOffset = 0;
2291          }
2292        }
2293        if (!skipRecord) {
2294          e.setAttribute("data-svg-origin", v.join(" "));
2295        }
2296      },
2297      _getBBoxHack2 = function _getBBoxHack(swapIfPossible) {
2298        //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).
2299        var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"),
2300          oldParent = this.parentNode,
2301          oldSibling = this.nextSibling,
2302          oldCSS = this.style.cssText,
2303          bbox;
2304        _docElement.appendChild(svg);
2305        svg.appendChild(this);
2306        this.style.display = "block";
2307        if (swapIfPossible) {
2308          try {
2309            bbox = this.getBBox();
2310            this._originalGetBBox = this.getBBox;
2311            this.getBBox = _getBBoxHack2;
2312          } catch (e) {}
2313        } else if (this._originalGetBBox) {
2314          bbox = this._originalGetBBox();
2315        }
2316        if (oldSibling) {
2317          oldParent.insertBefore(this, oldSibling);
2318        } else {
2319          oldParent.appendChild(this);
2320        }
2321        _docElement.removeChild(svg);
2322        this.style.cssText = oldCSS;
2323        return bbox;
2324      },
2325      _getBBox = function _getBBox(e) {
2326        try {
2327          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
2328        } catch (error) {
2329          return _getBBoxHack2.call(e, true);
2330        }
2331      },
2332      _isSVG = function _isSVG(e) {
2333        //reports if the element is an SVG on which getBBox() actually works
2334        return !!(_SVGElement && e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));
2335      },
2336      _identity2DMatrix = [1, 0, 0, 1, 0, 0],
2337      _getMatrix = function _getMatrix(e, force2D) {
2338        var tm = e._gsTransform || new Transform(),
2339          rnd = 100000,
2340          style = e.style,
2341          isDefault,
2342          s,
2343          m,
2344          n,
2345          dec,
2346          none;
2347        if (_transformProp) {
2348          s = _getStyle(e, _transformPropCSS, null, true);
2349        } else if (e.currentStyle) {
2350          //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.
2351          s = e.currentStyle.filter.match(_ieGetMatrixExp);
2352          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(",") : "";
2353        }
2354        isDefault = !s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)";
2355        if (_transformProp && ((none = !_getComputedStyle(e) || _getComputedStyle(e).display === "none") || !e.parentNode)) {
2356          //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
2357          if (none) {
2358            //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).
2359            n = style.display;
2360            style.display = "block";
2361          }
2362          if (!e.parentNode) {
2363            dec = 1; //flag
2364            _docElement.appendChild(e);
2365          }
2366          s = _getStyle(e, _transformPropCSS, null, true);
2367          isDefault = !s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)";
2368          if (n) {
2369            style.display = n;
2370          } else if (none) {
2371            _removeProp(style, "display");
2372          }
2373          if (dec) {
2374            _docElement.removeChild(e);
2375          }
2376        }
2377        if (tm.svg || e.getCTM && _isSVG(e)) {
2378          if (isDefault && (style[_transformProp] + "").indexOf("matrix") !== -1) {
2379            //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
2380            s = style[_transformProp];
2381            isDefault = 0;
2382          }
2383          m = e.getAttribute("transform");
2384          if (isDefault && m) {
2385            m = e.transform.baseVal.consolidate().matrix; //ensures that even complex values like "translate(50,60) rotate(135,0,0)" are parsed because it mashes it into a matrix.
2386            s = "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + m.e + "," + m.f + ")";
2387            isDefault = 0;
2388          }
2389        }
2390        if (isDefault) {
2391          return _identity2DMatrix;
2392        }
2393        //split the matrix values out into an array (m for matrix)
2394        m = (s || "").match(_numExp) || [];
2395        i = m.length;
2396        while (--i > -1) {
2397          n = Number(m[i]);
2398          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).
2399        }
2400        return force2D && m.length > 6 ? [m[0], m[1], m[4], m[5], m[12], m[13]] : m;
2401      },
2402      /**
2403       * 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.
2404       * @param {!Object} t target element
2405       * @param {Object=} cs computed style object (optional)
2406       * @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...}
2407       * @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)
2408       * @return {object}
2408 object containing all of the transform properties/values like {x:0, y:0, z:0, scaleX:1...}
2409       */
2410      _getTransform = _internals.getTransform = function (t, cs, rec, parse) {
2411        if (t._gsTransform && rec && !parse) {
2412          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.
2413        }
2414        var tm = rec ? t._gsTransform || new Transform() : new Transform(),
2415          invX = tm.scaleX < 0,
2416          //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.
2417          min = 0.00002,
2418          rnd = 100000,
2419          zOrigin = _supports3D ? parseFloat(_getStyle(t, _transformOriginProp, cs, false, "0 0 0").split(" ")[2]) || tm.zOrigin || 0 : 0,
2420          defaultTransformPerspective = parseFloat(_CSSPlugin.defaultTransformPerspective) || 0,
2421          m,
2422          i,
2423          scaleX,
2424          scaleY,
2425          rotation,
2426          skewX;
2427        tm.svg = !!(t.getCTM && _isSVG(t));
2428        if (tm.svg) {
2429          _parseSVGOrigin(t, _getStyle(t, _transformOriginProp, cs, false, "50% 50%") + "", tm, t.getAttribute("data-svg-origin"));
2430          _useSVGTransformAttr = _CSSPlugin.useSVGTransformAttr || _forceSVGTransformAttr;
2431        }
2432        m = _getMatrix(t);
2433        if (m !== _identity2DMatrix) {
2434          if (m.length === 16) {
2435            //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)
2436            var a11 = m[0],
2437              a21 = m[1],
2438              a31 = m[2],
2439              a41 = m[3],
2440              a12 = m[4],
2441              a22 = m[5],
2442              a32 = m[6],
2443              a42 = m[7],
2444              a13 = m[8],
2445              a23 = m[9],
2446              a33 = m[10],
2447              a14 = m[12],
2448              a24 = m[13],
2449              a34 = m[14],
2450              a43 = m[11],
2451              angle = Math.atan2(a32, a33),
2452              t1,
2453              t2,
2454              t3,
2455              t4,
2456              cos,
2457              sin;
2458            //we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari
2459            if (tm.zOrigin) {
2460              a34 = -tm.zOrigin;
2461              a14 = a13 * a34 - m[12];
2462              a24 = a23 * a34 - m[13];
2463              a34 = a33 * a34 + tm.zOrigin - m[14];
2464            }
2465            //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.
2466            tm.rotationX = angle * _RAD2DEG;
2467            //rotationX
2468            if (angle) {
2469              cos = Math.cos(-angle);
2470              sin = Math.sin(-angle);
2471              t1 = a12 * cos + a13 * sin;
2472              t2 = a22 * cos + a23 * sin;
2473              t3 = a32 * cos + a33 * sin;
2474              a13 = a12 * -sin + a13 * cos;
2475              a23 = a22 * -sin + a23 * cos;
2476              a33 = a32 * -sin + a33 * cos;
2477              a43 = a42 * -sin + a43 * cos;
2478              a12 = t1;
2479              a22 = t2;
2480              a32 = t3;
2481            }
2482            //rotationY
2483            angle = Math.atan2(-a31, a33);
2484            tm.rotationY = angle * _RAD2DEG;
2485            if (angle) {
2486              cos = Math.cos(-angle);
2487              sin = Math.sin(-angle);
2488              t1 = a11 * cos - a13 * sin;
2489              t2 = a21 * cos - a23 * sin;
2490              t3 = a31 * cos - a33 * sin;
2491              a23 = a21 * sin + a23 * cos;
2492              a33 = a31 * sin + a33 * cos;
2493              a43 = a41 * sin + a43 * cos;
2494              a11 = t1;
2495              a21 = t2;
2496              a31 = t3;
2497            }
2498            //rotationZ
2499            angle = Math.atan2(a21, a11);
2500            tm.rotation = angle * _RAD2DEG;
2501            if (angle) {
2502              cos = Math.cos(angle);
2503              sin = Math.sin(angle);
2504              t1 = a11 * cos + a21 * sin;
2505              t2 = a12 * cos + a22 * sin;
2506              t3 = a13 * cos + a23 * sin;
2507              a21 = a21 * cos - a11 * sin;
2508              a22 = a22 * cos - a12 * sin;
2509              a23 = a23 * cos - a13 * sin;
2510              a11 = t1;
2511              a12 = t2;
2512              a13 = t3;
2513            }
2514            if (tm.rotationX && Math.abs(tm.rotationX) + Math.abs(tm.rotation) > 359.9) {
2515              //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.
2516              tm.rotationX = tm.rotation = 0;
2517              tm.rotationY = 180 - tm.rotationY;
2518            }
2519
2520            //skewX
2521            angle = Math.atan2(a12, a22);
2522
2523            //scales
2524            tm.scaleX = (Math.sqrt(a11 * a11 + a21 * a21 + a31 * a31) * rnd + 0.5 | 0) / rnd;
2525            tm.scaleY = (Math.sqrt(a22 * a22 + a32 * a32) * rnd + 0.5 | 0) / rnd;
2526            tm.scaleZ = (Math.sqrt(a13 * a13 + a23 * a23 + a33 * a33) * rnd + 0.5 | 0) / rnd;
2527            a11 /= tm.scaleX;
2528            a12 /= tm.scaleY;
2529            a21 /= tm.scaleX;
2530            a22 /= tm.scaleY;
2531            if (Math.abs(angle) > min) {
2532              tm.skewX = angle * _RAD2DEG;
2533              a12 = 0;
2533 //unskews
2534              if (tm.skewType !== "simple") {
2535                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).
2536              }
2537            } else {
2538              tm.skewX = 0;
2539            }
2540
2541            /* //for testing purposes
2542            var transform = "matrix3d(",
2543            	comma = ",",
2544            	zero = "0";
2545            a13 /= tm.scaleZ;
2546            a23 /= tm.scaleZ;
2547            a31 /= tm.scaleX;
2548            a32 /= tm.scaleY;
2549            a33 /= tm.scaleZ;
2550            transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31);
2551            transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22);
2552            transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13);
2553            transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma;
2554            transform += a14 + comma + a24 + comma + a34 + comma + (tm.perspective ? (1 + (-a34 / tm.perspective)) : 1) + ")";
2555            console.log(transform);
2556            document.querySelector(".test").style[_transformProp] = transform;
2557            */
2558
2559            tm.perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;
2560            tm.x = a14;
2561            tm.y = a24;
2562            tm.z = a34;
2563            if (tm.svg) {
2564              tm.x -= tm.xOrigin - (tm.xOrigin * a11 - tm.yOrigin * a12);
2565              tm.y -= tm.yOrigin - (tm.yOrigin * a21 - tm.xOrigin * a22);
2566            }
2567          } else if (!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || !tm.rotationX && !tm.rotationY) {
2568            //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.
2569            var k = m.length >= 6,
2570              a = k ? m[0] : 1,
2571              b = m[1] || 0,
2572              c = m[2] || 0,
2573              d = k ? m[3] : 1;
2574            tm.x = m[4] || 0;
2575            tm.y = m[5] || 0;
2576            scaleX = Math.sqrt(a * a + b * b);
2577            scaleY = Math.sqrt(d * d + c * c);
2578            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).
2579            skewX = c || d ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0;
2580            tm.scaleX = scaleX;
2581            tm.scaleY = scaleY;
2582            tm.rotation = rotation;
2583            tm.skewX = skewX;
2584            if (_supports3D) {
2585              tm.rotationX = tm.rotationY = tm.z = 0;
2586              tm.perspective = defaultTransformPerspective;
2587              tm.scaleZ = 1;
2588            }
2589            if (tm.svg) {
2590              tm.x -= tm.xOrigin - (tm.xOrigin * a + tm.yOrigin * c);
2591              tm.y -= tm.yOrigin - (tm.xOrigin * b + tm.yOrigin * d);
2592            }
2593          }
2594          if (Math.abs(tm.skewX) > 90 && Math.abs(tm.skewX) < 270) {
2595            if (invX) {
2596              tm.scaleX *= -1;
2597              tm.skewX += tm.rotation <= 0 ? 180 : -180;
2598              tm.rotation += tm.rotation <= 0 ? 180 : -180;
2599            } else {
2600              tm.scaleY *= -1;
2601              tm.skewX += tm.skewX <= 0 ? 180 : -180;
2602            }
2603          }
2604          tm.zOrigin = zOrigin;
2605          //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.
2606          for (i in tm) {
2607            if (tm[i] < min) if (tm[i] > -min) {
2608              tm[i] = 0;
2609            }
2610          }
2611        }
2612        //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);
2613        if (rec) {
2614          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)
2615          if (tm.svg) {
2616            //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.
2617            if (_useSVGTransformAttr && t.style[_transformProp]) {
2618              TweenLite.delayedCall(0.001, function () {
2619                //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).
2620                _removeProp(t.style, _transformProp);
2621              });
2622            } else if (!_useSVGTransformAttr && t.getAttribute("transform")) {
2623              TweenLite.delayedCall(0.001, function () {
2624                t.removeAttribute("transform");
2625              });
2626            }
2627          }
2628        }
2629        return tm;
2630      },
2631      //for setting 2D transforms in IE6, IE7, and IE8 (must use a "filter" to emulate the behavior of modern day browser transforms)
2632      _setIETransformRatio = function _setIETransformRatio(v) {
2633        var t = this.data,
2634          //refers to the element's _gsTransform object
2635          ang = -t.rotation * _DEG2RAD,
2636          skew = ang + t.skewX * _DEG2RAD,
2637          rnd = 100000,
2638          a = (Math.cos(ang) * t.scaleX * rnd | 0) / rnd,
2639          b = (Math.sin(ang) * t.scaleX * rnd | 0) / rnd,
2640          c = (Math.sin(skew) * -t.scaleY * rnd | 0) / rnd,
2641          d = (Math.cos(skew) * t.scaleY * rnd | 0) / rnd,
2642          style = this.t.style,
2643          cs = this.t.currentStyle,
2644          filters,
2645          val;
2646        if (!cs) {
2647          return;
2648        }
2649        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)
2650        b = -c;
2651        c = -val;
2652        filters = cs.filter;
2653        style.filter = ""; //remove filters so that we can accurately measure offsetWidth/offsetHeight
2654        var w = this.t.offsetWidth,
2655          h = this.t.offsetHeight,
2656          clip = cs.position !== "absolute",
2657          m = "progid:DXImageTransform.Microsoft.Matrix(M11=" + a + ", M12=" + b + ", M21=" + c + ", M22=" + d,
2658          ox = t.x + w * t.xPercent / 100,
2659          oy = t.y + h * t.yPercent / 100,
2660          dx,
2661          dy;
2662
2663        //if transformOrigin is being used, adjust the offset x and y
2664        if (t.ox != null) {
2665          dx = (t.oxp ? w * t.ox * 0.01 : t.ox) - w / 2;
2666          dy = (t.oyp ? h * t.oy * 0.01 : t.oy) - h / 2;
2667          ox += dx - (dx * a + dy * b);
2668          oy += dy - (dx * c + dy * d);
2669        }
2670        if (!clip) {
2671          m += ", sizingMethod='auto expand')";
2672        } else {
2673          dx = w / 2;
2674          dy = h / 2;
2675          //translate to ensure that transformations occur around the correct origin (default is center).
2676          m += ", Dx=" + (dx - (dx * a + dy * b) + ox) + ", Dy=" + (dy - (dx * c + dy * d) + oy) + ")";
2677        }
2678        if (filters.indexOf("DXImageTransform.Microsoft.Matrix(") !== -1) {
2679          style.filter = filters.replace(_ieSetMatrixExp, m);
2680        } else {
2681          style.filter = m + " " + filters; //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.
2682        }
2683
2684        //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.
2685        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) {
2686          style.removeAttribute("filter");
2687        }
2688
2689        //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).
2690        if (!clip) {
2691          var mult = _ieVers < 8 ? 1 : -1,
2692            //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
2693            marg,
2694            prop,
2695            dif;
2696          dx = t.ieOffsetX || 0;
2697          dy = t.ieOffsetY || 0;
2698          t.ieOffsetX = Math.round((w - ((a < 0 ? -a : a) * w + (b < 0 ? -b : b) * h)) / 2 + ox);
2699          t.ieOffsetY = Math.round((h - ((d < 0 ? -d : d) * h + (c < 0 ? -c : c) * w)) / 2 + oy);
2700          for (i = 0; i < 4; i++) {
2701            prop = _margins[i];
2702            marg = cs[prop];
2703            //we need to get the current margin in case it is being tweened separately (we want to respect that tween's changes)
2704            val = marg.indexOf("px") !== -1 ? parseFloat(marg) : _convertToPixels(this.t, prop, parseFloat(marg), marg.replace(_suffixExp, "")) || 0;
2705            if (val !== t[prop]) {
2706              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.
2707            } else {
2708              dif = i < 2 ? dx - t.ieOffsetX : dy - t.ieOffsetY;
2709            }
2710            style[prop] = (t[prop] = Math.round(val - dif * (i === 0 || i === 2 ? 1 : mult))) + "px";
2711          }
2712        }
2713      },
2714      /* translates a super small decimal to a string WITHOUT scientific notation
2715      _safeDecimal = function(n) {
2716      	var s = (n < 0 ? -n : n) + "",
2717      		a = s.split("e-");
2718      	return (n < 0 ? "-0." : "0.") + new Array(parseInt(a[1], 10) || 0).join("0") + a[0].split(".").join("");
2719      },
2720      */
2721
2722      _setTransformRatio = _internals.set3DTransformRatio = _internals.setTransformRatio = function (v) {
2723        var t = this.data,
2724          //refers to the element's _gsTransform object
2725          style = this.t.style,
2726          angle = t.rotation,
2727          rotationX = t.rotationX,
2728          rotationY = t.rotationY,
2729          sx = t.scaleX,
2730          sy = t.scaleY,
2731          sz = t.scaleZ,
2732          x = t.x,
2733          y = t.y,
2734          z = t.z,
2735          isSVG = t.svg,
2736          perspective = t.perspective,
2737          force3D = t.force3D,
2738          skewY = t.skewY,
2739          skewX = t.skewX,
2740          t1,
2741          a11,
2742          a12,
2743          a13,
2744          a21,
2745          a22,
2746          a23,
2747          a31,
2748          a32,
2749          a33,
2750          a41,
2751          a42,
2752          a43,
2753          zOrigin,
2754          min,
2755          cos,
2756          sin,
2757          t2,
2758          transform,
2759          comma,
2760          zero,
2761          skew,
2762          rnd;
2763        if (skewY) {
2764          //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.
2765          skewX += skewY;
2766          angle += skewY;
2767        }
2768
2769        //check to see if we should render as 2D (and SVGs must use 2D when _useSVGTransformAttr is true)
2770        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) {
2771          //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.
2772
2773          //2D
2774          if (angle || skewX || isSVG) {
2775            angle *= _DEG2RAD;
2776            skew = skewX * _DEG2RAD;
2777            rnd = 100000;
2778            a11 = Math.cos(angle) * sx;
2779            a21 = Math.sin(angle) * sx;
2780            a12 = Math.sin(angle - skew) * -sy;
2781            a22 = Math.cos(angle - skew) * sy;
2782            if (skew && t.skewType === "simple") {
2783              //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
2784              t1 = Math.tan(skew - skewY * _DEG2RAD);
2785              t1 = Math.sqrt(1 + t1 * t1);
2786              a12 *= t1;
2787              a22 *= t1;
2788              if (skewY) {
2789                t1 = Math.tan(skewY * _DEG2RAD);
2790                t1 = Math.sqrt(1 + t1 * t1);
2791                a11 *= t1;
2792                a21 *= t1;
2793              }
2794            }
2795            if (isSVG) {
2796              x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
2797              y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
2798              if (_useSVGTransformAttr && (t.xPercent || t.yPercent)) {
2799                //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the matrix to simulate it.
2800                min = this.t.getBBox();
2801                x += t.xPercent * 0.01 * min.width;
2802                y += t.yPercent * 0.01 * min.height;
2803              }
2804              min = 0.000001;
2805              if (x < min) if (x > -min) {
2806                x = 0;
2807              }
2808              if (y < min) if (y > -min) {
2809                y = 0;
2810              }
2811            }
2812            transform = (a11 * rnd | 0) / rnd + "," + (a21 * rnd | 0) / rnd + "," + (a12 * rnd | 0) / rnd + "," + (a22 * rnd | 0) / rnd + "," + x + "," + y + ")";
2813            if (isSVG && _useSVGTransformAttr) {
2814              this.t.setAttribute("transform", "matrix(" + transform);
2815            } else {
2816              //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.
2817              style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + transform;
2818            }
2819          } else {
2820            style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + sx + ",0,0," + sy + "," + x + "," + y + ")";
2821          }
2822          return;
2823        }
2824        if (_isFirefox) {
2825          //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.
2826          min = 0.0001;
2827          if (sx < min && sx > -min) {
2828            sx = sz = 0.00002;
2829          }
2830          if (sy < min && sy > -min) {
2831            sy = sz = 0.00002;
2832          }
2833          if (perspective && !t.z && !t.rotationX && !t.rotationY) {
2834            //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).
2835            perspective = 0;
2836          }
2837        }
2838        if (angle || skewX) {
2839          angle *= _DEG2RAD;
2840          cos = a11 = Math.cos(angle);
2841          sin = a21 = Math.sin(angle);
2842          if (skewX) {
2843            angle -= skewX * _DEG2RAD;
2844            cos = Math.cos(angle);
2845            sin = Math.sin(angle);
2846            if (t.skewType === "simple") {
2847              //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
2848              t1 = Math.tan((skewX - skewY) * _DEG2RAD);
2849              t1 = Math.sqrt(1 + t1 * t1);
2850              cos *= t1;
2851              sin *= t1;
2852              if (t.skewY) {
2853                t1 = Math.tan(skewY * _DEG2RAD);
2854                t1 = Math.sqrt(1 + t1 * t1);
2855                a11 *= t1;
2856                a21 *= t1;
2857              }
2858            }
2859          }
2860          a12 = -sin;
2861          a22 = cos;
2862        } else if (!rotationY && !rotationX && sz === 1 && !perspective && !isSVG) {
2863          //if we're only translating and/or 2D scaling, this is faster...
2864          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 + ")" : "");
2865          return;
2866        } else {
2867          a11 = a22 = 1;
2868          a12 = a21 = 0;
2869        }
2870        // KEY  INDEX   AFFECTS a[row][column]
2871        // a11  0       rotation, rotationY, scaleX
2872        // a21  1       rotation, rotationY, scaleX
2873        // a31  2       rotationY, scaleX
2874        // a41  3       rotationY, scaleX
2875        // a12  4       rotation, skewX, rotationX, scaleY
2876        // a22  5       rotation, skewX, rotationX, scaleY
2877        // a32  6       rotationX, scaleY
2878        // a42  7       rotationX, scaleY
2879        // a13  8       rotationY, rotationX, scaleZ
2880        // a23  9       rotationY, rotationX, scaleZ
2881        // a33  10      rotationY, rotationX, scaleZ
2882        // a43  11      rotationY, rotationX, perspective, scaleZ
2883        // a14  12      x, zOrigin, svgOrigin
2884        // a24  13      y, zOrigin, svgOrigin
2885        // a34  14      z, zOrigin
2886        // a44  15
2887        // rotation: Math.atan2(a21, a11)
2888        // rotationY: Math.atan2(a13, a33) (or Math.atan2(a13, a11))
2889        // rotationX: Math.atan2(a32, a33)
2890        a33 = 1;
2891        a13 = a23 = a31 = a32 = a41 = a42 = 0;
2892        a43 = perspective ? -1 / perspective : 0;
2893        zOrigin = t.zOrigin;
2894        min = 0.000001; //threshold below which browsers use scientific notation which w
2894on't work.
2895        comma = ",";
2896        zero = "0";
2897        angle = rotationY * _DEG2RAD;
2898        if (angle) {
2899          cos = Math.cos(angle);
2900          sin = Math.sin(angle);
2901          a31 = -sin;
2902          a41 = a43 * -sin;
2903          a13 = a11 * sin;
2904          a23 = a21 * sin;
2905          a33 = cos;
2906          a43 *= cos;
2907          a11 *= cos;
2908          a21 *= cos;
2909        }
2910        angle = rotationX * _DEG2RAD;
2911        if (angle) {
2912          cos = Math.cos(angle);
2913          sin = Math.sin(angle);
2914          t1 = a12 * cos + a13 * sin;
2915          t2 = a22 * cos + a23 * sin;
2916          a32 = a33 * sin;
2917          a42 = a43 * sin;
2918          a13 = a12 * -sin + a13 * cos;
2919          a23 = a22 * -sin + a23 * cos;
2920          a33 = a33 * cos;
2921          a43 = a43 * cos;
2922          a12 = t1;
2923          a22 = t2;
2924        }
2925        if (sz !== 1) {
2926          a13 *= sz;
2927          a23 *= sz;
2928          a33 *= sz;
2929          a43 *= sz;
2930        }
2931        if (sy !== 1) {
2932          a12 *= sy;
2933          a22 *= sy;
2934          a32 *= sy;
2935          a42 *= sy;
2936        }
2937        if (sx !== 1) {
2938          a11 *= sx;
2939          a21 *= sx;
2940          a31 *= sx;
2941          a41 *= sx;
2942        }
2943        if (zOrigin || isSVG) {
2944          if (zOrigin) {
2945            x += a13 * -zOrigin;
2946            y += a23 * -zOrigin;
2947            z += a33 * -zOrigin + zOrigin;
2948          }
2949          if (isSVG) {
2950            //due to bugs in some browsers, we need to manage the transform-origin of SVG manually
2951            x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
2952            y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
2953          }
2954          if (x < min && x > -min) {
2955            x = zero;
2956          }
2957          if (y < min && y > -min) {
2958            y = zero;
2959          }
2960          if (z < min && z > -min) {
2961            z = 0; //don't use string because we calculate perspective later and need the number.
2962          }
2963        }
2964
2965        //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:
2966        transform = t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix3d(" : "matrix3d(";
2967        transform += (a11 < min && a11 > -min ? zero : a11) + comma + (a21 < min && a21 > -min ? zero : a21) + comma + (a31 < min && a31 > -min ? zero : a31);
2968        transform += comma + (a41 < min && a41 > -min ? zero : a41) + comma + (a12 < min && a12 > -min ? zero : a12) + comma + (a22 < min && a22 > -min ? zero : a22);
2969        if (rotationX || rotationY || sz !== 1) {
2970          //performance optimization (often there's no rotationX or rotationY, so we can skip these calculations)
2971          transform += comma + (a32 < min && a32 > -min ? zero : a32) + comma + (a42 < min && a42 > -min ? zero : a42) + comma + (a13 < min && a13 > -min ? zero : a13);
2972          transform += comma + (a23 < min && a23 > -min ? zero : a23) + comma + (a33 < min && a33 > -min ? zero : a33) + comma + (a43 < min && a43 > -min ? zero : a43) + comma;
2973        } else {
2974          transform += ",0,0,0,0,1,0,";
2975        }
2976        transform += x + comma + y + comma + z + comma + (perspective ? 1 + -z / perspective : 1) + ")";
2977        style[_transformProp] = transform;
2978      };
2979    p = Transform.prototype;
2980    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;
2981    p.scaleX = p.scaleY = p.scaleZ = 1;
2982    _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", {
2983      parser: function parser(t, e, parsingProp, cssp, pt, plugin, vars) {
2984        if (cssp._lastParsedTransform === vars) {
2985          return pt;
2986        } //only need to parse the transform once, and only if the browser supports it.
2987        cssp._lastParsedTransform = vars;
2988        var scaleFunc = vars.scale && typeof vars.scale === "function" ? vars.scale : 0,
2989          //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()).
2990          swapFunc;
2991        if (typeof vars[parsingProp] === "function") {
2992          //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.
2993          swapFunc = vars[parsingProp];
2994          vars[parsingProp] = e;
2995        }
2996        if (scaleFunc) {
2997          vars.scale = scaleFunc(_index, t);
2998        }
2999        var originalGSTransform = t._gsTransform,
3000          style = t.style,
3001          min = 0.000001,
3002          i = _transformProps.length,
3003          v = vars,
3004          endRotations = {},
3005          transformOriginString = "transformOrigin",
3006          m1 = _getTransform(t, _cs, true, v.parseTransform),
3007          orig = v.transform && (typeof v.transform === "function" ? v.transform(_index, _target) : v.transform),
3008          m2,
3009          copy,
3010          has3D,
3011          hasChange,
3012          dr,
3013          x,
3014          y,
3015          matrix,
3016          p;
3017        m1.skewType = v.skewType || m1.skewType || _CSSPlugin.defaultSkewType;
3018        cssp._transform = m1;
3019        if (orig && typeof orig === "string" && _transformProp) {
3020          //for values like transform:"rotate(60deg) scale(0.5, 0.8)"
3021          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.
3022          copy[_transformProp] = orig;
3023          copy.display = "block"; //if display is "none", the browser often refuses to report the transform properties correctly.
3024          copy.position = "absolute";
3025          _doc.body.appendChild(_tempDiv);
3026          m2 = _getTransform(_tempDiv, null, false);
3027          if (m1.skewType === "simple") {
3028            //the default _getTransform() reports the skewX/scaleY as if skewType is "compensated", thus we need to adjust that here if skewType is "simple".
3029            m2.scaleY *= Math.cos(m2.skewX * _DEG2RAD);
3030          }
3031          if (m1.svg) {
3032            //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...
3033            x = m1.xOrigin;
3034            y = m1.yOrigin;
3035            m2.x -= m1.xOffset;
3036            m2.y -= m1.yOffset;
3037            if (v.transformOrigin || v.svgOrigin) {
3038              //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.
3039              orig = {};
3040              _parseSVGOrigin(t, _parsePosition2(v.transformOrigin), orig, v.svgOrigin, v.smoothOrigin, true);
3041              x = orig.xOrigin;
3042              y = orig.yOrigin;
3043              m2.x -= orig.xOffset - m1.xOffset;
3044              m2.y -= orig.yOffset - m1.yOffset;
3045            }
3046            if (x || y) {
3047              matrix = _getMatrix(_tempDiv, true);
3048              m2.x -= x - (x * matrix[0] + y * matrix[2]);
3049              m2.y -= y - (x * matrix[1] + y * matrix[3]);
3050            }
3051          }
3052          _doc.body.removeChild(_tempDiv);
3053          if (!m2.perspective) {
3054            m2.perspective = m1.perspective; //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.
3055          }
3056          if (v.xPercent != null) {
3057            m2.xPercent = _parseVal(v.xPercent, m1.xPercent);
3058          }
3059          if (v.yPercent != null) {
3060            m2.yPercent = _parseVal(v.yPercent, m1.yPercent);
3061          }
3062        } else if (_typeof(v) === "object") {
3063          //for values like scaleX, scaleY, rotation, x, y, skewX, and skewY or transform:{...} (object)
3064          m2 = {
3065            scaleX: _parseVal(v.scaleX != null ? v.scaleX : v.scale, m1.scaleX),
3066            scaleY: _parseVal(v.scaleY != null ? v.scaleY : v.scale, m1.scaleY),
3067            scaleZ: _parseVal(v.scaleZ, m1.scaleZ),
3068            x: _parseVal(v.x, m1.x),
3069            y: _parseVal(v.y, m1.y),
3070            z: _parseVal(v.z, m1.z),
3071            xPercent: _parseVal(v.xPercent, m1.xPercent),
3072            yPercent: _parseVal(v.yPercent, m1.yPercent),
3073            perspective: _parseVal(v.transformPerspective, m1.perspective)
3074          };
3075          dr = v.directionalRotation;
3076          if (dr != null) {
3077            if (_typeof(dr) === "object") {
3078              for (copy in dr) {
3079                v[copy] = dr[copy];
3080              }
3081            } else {
3082              v.rotation = dr;
3083            }
3084          }
3085          if (typeof v.x === "string" && v.x.indexOf("%") !== -1) {
3086            m2.x = 0;
3087            m2.xPercent = _parseVal(v.x, m1.xPercent);
3088          }
3089          if (typeof v.y === "string" && v.y.indexOf("%") !== -1) {
3090            m2.y = 0;
3091            m2.yPercent = _parseVal(v.y, m1.yPercent);
3092          }
3093          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);
3094          if (_supports3D) {
3095            m2.rotationX = _parseAngle("rotationX" in v ? v.rotationX : "shortRotationX" in v ? v.shortRotationX + "_short" : m1.rotationX || 0, m1.rotationX, "rotationX", endRotations);
3096            m2.rotationY = _parseAngle("rotationY" in v ? v.rotationY : "shortRotationY" in v ? v.shortRotationY + "_short" : m1.rotationY || 0, m1.rotationY, "rotationY", endRotations);
3097          }
3098          m2.skewX = _parseAngle(v.skewX, m1.skewX);
3099          m2.skewY = _parseAngle(v.skewY, m1.skewY);
3100        }
3101        if (_supports3D && v.force3D != null) {
3102          m1.force3D = v.force3D;
3103          hasChange = true;
3104        }
3105        has3D = m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective;
3106        if (!has3D && v.scale != null) {
3107          m2.scaleZ = 1; //no need to tween scaleZ.
3108        }
3109        while (--i > -1) {
3110          p = _transformProps[i];
3111          orig = m2[p] - m1[p];
3112          if (orig > min || orig < -min || v[p] != null || _forcePT[p] != null) {
3113            hasChange = true;
3114            pt = new CSSPropTween(m1, p, m1[p], orig, pt);
3115            if (p in endRotations) {
3116              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
3117            }
3118            pt.xs0 = 0; //ensures the value stays numeric in setRatio()
3119            pt.plugin = plugin;
3120            cssp._overwriteProps.push(pt.n);
3121          }
3122        }
3123        orig = v.transformOrigin;
3124        if (m1.svg && (orig || v.svgOrigin)) {
3125          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
3126          y = m1.yOffset;
3127          _parseSVGOrigin(t, _parsePosition2(orig), m2, v.svgOrigin, v.smoothOrigin);
3128          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.
3129          pt = _addNonTweeningNumericPT(m1, "yOrigin", (originalGSTransform ? m1 : m2).yOrigin, m2.yOrigin, pt, transformOriginString);
3130          if (x !== m1.xOffset || y !== m1.yOffset) {
3131            pt = _addNonTweeningNumericPT(m1, "xOffset", originalGSTransform ? x : m1.xOffset, m1.xOffset, pt, transformOriginString);
3132            pt = _addNonTweeningNumericPT(m1, "yOffset", originalGSTransform ? y : m1.yOffset, m1.yOffset, pt, transformOriginString);
3133          }
3134          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
3135        }
3136        if (orig || _supports3D && has3D && m1.zOrigin) {
3137          //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).
3138          if (_transformProp) {
3139            hasChange = true;
3140            p = _transformOriginProp;
3141            orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors
3142            pt = new CSSPropTween(style, p, 0, 0, pt, -1, transformOriginString);
3143            pt.b = style[p];
3144            pt.plugin = plugin;
3145            if (_supports3D) {
3146              copy = m1.zOrigin;
3147              orig = orig.split(" ");
3148              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.
3149              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)!
3150              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)
3151              pt.b = copy;
3152              pt.xs0 = pt.e = m1.zOrigin;
3153            } else {
3154              pt.xs0 = pt.e = orig;
3155            }
3156
3157            //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).
3158          } else {
3159            _parsePosition2(orig + "", m1);
3160          }
3161        }
3162        if (hasChange) {
3163          cssp._transformType = !(m1.svg && _useSVGTransformAttr) && (has3D || this._transformType === 3) ? 3 : 2; //quicker than calling cssp._enableTransforms();
3164        }
3165        if (swapFunc) {
3166          vars[parsingProp] = swapFunc;
3167        }
3168        if (scaleFunc) {
3169          vars.scale = scaleFunc;
3170        }
3171        return pt;
3172      },
3173      prefix: true
3174    });
3175    _registerComplexSpecialProp("boxShadow", {
3176      defaultValue: "0px 0px 0px 0px #999",
3177      prefix: true,
3178      color: true,
3179      multi: true,
3180      keyword: "inset"
3181    });
3182    _registerComplexSpecialProp("borderRadius", {
3183      defaultValue: "0px",
3184      parser: function parser(t, e, p, cssp, pt, plugin) {
3185        e = this.format(e);
3186        var props = ["borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius"],
3187          style = t.style,
3188          ea1,
3189          i,
3190          es2,
3191          bs2,
3192          bs,
3193          es,
3194          bn,
3195          en,
3196          w,
3197          h,
3198          esfx,
3199          bsfx,
3200          rel,
3201          hn,
3202          vn,
3203          em;
3204        w = parseFloat(t.offsetWidth);
3205        h = parseFloat(t.offsetHeight);
3206        ea1 = e.split(" ");
3207        for (i = 0; i < props.length; i++) {
3208          //if we're dealing with percentages, we must convert things separately for the horizontal and vertical axis!
3209          if (this.p.indexOf("border")) {
3210            //older browsers used a prefix
3211            props[i] = _checkPropPrefix(props[i]);
3212          }
3213          bs = bs2 = _getStyle(t, props[i], _cs, false, "0px");
3214          if (bs.indexOf(" ") !== -1) {
3215            bs2 = bs.split(" ");
3216            bs = bs2[0];
3217            bs2 = bs2[1];
3218          }
3219          es = es2 = ea1[i];
3220          bn = parseFloat(bs);
3221          bsfx = bs.substr((bn + "").length);
3222          rel = es.charAt(1) === "=";
3223          if (rel) {
3224            en = parseInt(es.charAt(0) + "1", 10);
3225            es = es.substr(2);
3226            en *= parseFloat(es);
3227            esfx = es.substr((en + "").length - (en < 0 ? 1 : 0)) || "";
3228          } else {
3229            en = parseFloat(es);
3230            esfx = es.substr((en + "").length);
3231          }
3232          if (esfx === "") {
3233            esfx = _suffixMap[p] || bsfx;
3234          }
3235          if (esfx !== bsfx) {
3236            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.
3237            vn = _convertToPixels(t, "borderTop", bn, bsfx); //vertical number
3238            if (esfx === "%") {
3239              bs = hn / w * 100 + "%";
3240              bs2 = vn / h * 100 + "%";
3241            } else if (esfx === "em") {
3242              em = _convertToPixels(t, "borderLeft", 1, "em");
3243              bs = hn / em + "em";
3244              bs2 = vn / em + "em";
3245            } else {
3246              bs = hn + "px";
3247              bs2 = vn + "px";
3248            }
3249            if (rel) {
3250              es = parseFloat(bs) + en + esfx;
3251              es2 = parseFloat(bs2) + en + esfx;
3252            }
3253          }
3254          pt = _parseComplex(style, props[i], bs + " " + bs2, es + " " + es2, false, "0px", pt);
3255        }
3256        return pt;
3257      },
3258      prefix: true,
3259      formatter: _getFormatter("0px 0px 0px 0px", false, true)
3260    });
3261    _registerComplexSpecialProp("borderBottomLeftRadius,borderBottomRightRadius,borderTopLeftRadius,borderTopRightRadius", {
3262      defaultValue: "0px",
3263      parser: function parser(t, e, p, cssp, pt, plugin) {
3264        return _parseComplex(t.style, p, this.format(_getStyle(t, p, _cs, false, "0px 0px")), this.format(e), false, "0px", pt);
3265      },
3266      prefix: true,
3267      formatter: _getFormatter("0px 0px", false, true)
3268    });
3269    _registerComplexSpecialProp("backgroundPosition", {
3270      defaultValue: "0 0",
3271      parser: function parser(t, e, p, cssp, pt, plugin) {
3272        var bp = "background-position",
3273          cs = _cs || _getComputedStyle(t, null),
3274          bs = this.format((cs ? _ieVers ? cs.getPropertyValue(bp + "-x") + " " + cs.getPropertyValue(bp + "-y") : cs.getPropertyValue(bp) : t.currentStyle.backgroundPositionX + " " + t.currentStyle.backgroundPositionY) || "0 0"),
3275          //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
3276          es = this.format(e),
3277          ba,
3278          ea,
3279          i,
3280          pct,
3281          overlap,
3282          src;
3283        if (bs.indexOf("%") !== -1 !== (es.indexOf("%") !== -1) && es.split(",").length < 2) {
3284          src = _getStyle(t, "backgroundImage").replace(_urlExp, "");
3285          if (src && src !== "none") {
3286            ba = bs.split(" ");
3287            ea = es.split(" ");
3288            _tempImg.setAttribute("src", src); //set the temp IMG's src to the background-image so that we can measure its width/height
3289            i = 2;
3290            while (--i > -1) {
3291              bs = ba[i];
3292              pct = bs.indexOf("%") !== -1;
3293              if (pct !== (ea[i].indexOf("%") !== -1)) {
3294                overlap = i === 0 ? t.offsetWidth - _tempImg.width : t.offsetHeight - _tempImg.height;
3295                ba[i] = pct ? parseFloat(bs) / 100 * overlap + "px" : parseFloat(bs) / overlap * 100 + "%";
3296              }
3297            }
3298            bs = ba.join(" ");
3299          }
3300        }
3301        return this.parseComplex(t.style, bs, es, pt, plugin);
3302      },
3303      formatter: _parsePosition2
3304    });
3305    _registerComplexSpecialProp("backgroundSize", {
3306      defaultValue: "0 0",
3307      formatter: function formatter(v) {
3308        v += ""; //ensure it's a string
3309        return _parsePosition2(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).
3310      }
3311    });
3312    _registerComplexSpecialProp("perspective", {
3313      defaultValue: "0px",
3314      prefix: true
3315    });
3316    _registerComplexSpecialProp("perspectiveOrigin", {
3317      defaultValue: "50% 50%",
3318      prefix: true
3319    });
3320    _registerComplexSpecialProp("transformStyle", {
3321      prefix: true
3322    });
3323    _registerComplexSpecialProp("backfaceVisibility", {
3324      prefix: true
3325    });
3326    _registerComplexSpecialProp("userSelect", {
3327      prefix: true
3328    });
3329    _registerComplexSpecialProp("margin", {
3330      parser: _getEdgeParser("marginTop,marginRight,marginBottom,marginLeft")
3331    });
3332    _registerComplexSpecialProp("padding", {
3333      parser: _getEdgeParser("paddingTop,paddingRight,paddingBottom,paddingLeft")
3334    });
3335    _registerComplexSpecialProp("clip", {
3336      defaultValue: "rect(0px,0px,0px,0px)",
3337      parser: function parser(t, e, p, cssp, pt, plugin) {
3338        var b, cs, delim;
3339        if (_ieVers < 9) {
3340          //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.
3341          cs = t.currentStyle;
3342          delim = _ieVers < 8 ? " " : ",";
3343          b = "rect(" + cs.clipTop + delim + cs.clipRight + delim + cs.clipBottom + delim + cs.clipLeft + ")";
3344          e = this.format(e).split(",").join(delim);
3345        } else {
3346          b = this.format(_getStyle(t, this.p, _cs, false, this.dflt));
3347          e = this.format(e);
3348        }
3349        return this.parseComplex(t.style, b, e, pt, plugin);
3350      }
3351    });
3352    _registerComplexSpecialProp("textShadow", {
3353      defaultValue: "0px 0px 0px #999",
3354      color: true,
3355      multi: true
3356    });
3357    _registerComplexSpecialProp("autoRound,strictUnits", {
3358      parser: function parser(t, e, p, cssp, pt) {
3359        return pt;
3360      }
3361    }); //just so that we can ignore these properties (not tween them)
3362    _registerComplexSpecialProp("border", {
3363      defaultValue: "0px solid #000",
3364      parser: function parser(t, e, p, cssp, pt, plugin) {
3365        var bw = _getStyle(t, "borderTopWidth", _cs, false, "0px"),
3366          end = this.format(e).split(" "),
3367          esfx = end[0].replace(_suffixExp, "");
3368        if (esfx !== "px") {
3369          //if we're animating to a non-px value, we need to convert the beginning width to that unit.
3370          bw = parseFloat(bw) / _convertToPixels(t, "borderTopWidth", 1, esfx) + esfx;
3371        }
3372        return this.parseComplex(t.style, this.format(bw + " " + _getStyle(t, "borderTopStyle", _cs, false, "solid") + " " + _getStyle(t, "borderTopColor", _cs, false, "#000")), end.join(" "), pt, plugin);
3373      },
3374      color: true,
3375      formatter: function formatter(v) {
3376        var a = v.split(" ");
3377        return a[0] + " " + (a[1] || "solid") + " " + (v.match(_colorExp) || ["#000"])[0];
3378      }
3379    });
3380    _registerComplexSpecialProp("borderWidth", {
3381      parser: _getEdgeParser("borderTopWidth,borderRightWidth,borderBottomWidth,borderLeftWidth")
3382    }); //Firefox doesn't pick up on borderWidth set in style sheets (only inline).
3383    _registerComplexSpecialProp("float,cssFloat,styleFloat", {
3384      parser: function parser(t, e, p, cssp, pt, plugin) {
3385        var s = t.style,
3386          prop = "cssFloat" in s ? "cssFloat" : "styleFloat";
3387        return new CSSPropTween(s, prop, 0, 0, pt, -1, p, false, 0, s[prop], e);
3388      }
3389    });
3390
3391    //opacity-related
3392    var _setIEOpacityRatio = function _setIEOpacityRatio(v) {
3393      var t = this.t,
3394        //refers to the element's style property
3395        filters = t.filter || _getStyle(this.data, "filter") || "",
3396        val = this.s + this.c * v | 0,
3397        skip;
3398      if (val === 100) {
3399        //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.
3400        if (filters.indexOf("atrix(") === -1 && filters.indexOf("radient(") === -1 && filters.indexOf("oader(") === -1) {
3401          t.removeAttribute("filter");
3402          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.
3403        } else {
3404          t.filter = filters.replace(_alphaFilterExp, "");
3405          skip = true;
3406        }
3407      }
3408      if (!skip) {
3409        if (this.xn1) {
3410          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.
3411        }
3412        if (filters.indexOf("pacity") === -1) {
3413          //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
3414          if (val !== 0 || !this.xn1) {
3415            //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)
3416            t.filter = filters + " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly.
3417          }
3418        } else {
3419          t.filter = filters.replace(_opacityExp, "opacity=" + val);
3420        }
3421      }
3422    };
3423    _registerComplexSpecialProp("opacity,alpha,autoAlpha", {
3424      defaultValue: "1",
3425      parser: function parser(t, e, p, cssp, pt, plugin) {
3426        var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")),
3427          style = t.style,
3428          isAutoAlpha = p === "autoAlpha";
3429        if (typeof e === "string" && e.charAt(1) === "=") {
3430          e = (e.charAt(0) === "-" ? -1 : 1) * parseFloat(e.substr(2)) + b;
3431        }
3432        if (isAutoAlpha && b === 1 && _getStyle(t, "visibility", _cs) === "hidden" && e !== 0) {
3433          //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience)
3434          b = 0;
3435        }
3436        if (_supportsOpacity) {
3437          pt = new CSSPropTween(style, "opacity", b, e - b, pt);
3438        } else {
3439          pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt);
3440          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.
3441          style.zoom = 1; //helps correct an IE issue.
3442          pt.type = 2;
3443          pt.b = "alpha(opacity=" + pt.s + ")";
3444          pt.e = "alpha(opacity=" + (pt.s + pt.c) + ")";
3445          pt.data = t;
3446          pt.plugin = plugin;
3447          pt.setRatio = _setIEOpacityRatio;
3448        }
3449        if (isAutoAlpha) {
3450          //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
3451          pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, b !== 0 ? "inherit" : "hidden", e === 0 ? "hidden" : "inherit");
3452          pt.xs0 = "inherit";
3453          cssp._overwriteProps.push(pt.n);
3454          cssp._overwriteProps.push(p);
3455        }
3456        return pt;
3457      }
3458    });
3459    var _removeProp = function _removeProp(s, p) {
3460        if (p) {
3461          if (s.removeProperty) {
3462            if (p.substr(0, 2) === "ms" || p.substr(0, 6) === "webkit") {
3463              //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)
3464              p = "-" + p;
3465            }
3466            s.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());
3467          } else {
3468            //note: old versions of IE use "removeAttribute()" instead of "removeProperty()"
3469            s.removeAttribute(p);
3470          }
3471        }
3472      },
3473      _setClassNameRatio = function _setClassNameRatio(v) {
3474        this.t._gsClassPT = this;
3475        if (v === 1 || v === 0) {
3476          this.t.setAttribute("class", v === 0 ? this.b : this.e);
3477          var mpt = this.data,
3478            //first MiniPropTween
3479            s = this.t.style;
3480          while (mpt) {
3481            if (!mpt.v) {
3482              _removeProp(s, mpt.p);
3483            } else {
3484              s[mpt.p] = mpt.v;
3485            }
3486            mpt = mpt._next;
3487          }
3488          if (v === 1 && this.t._gsClassPT === this) {
3489            this.t._gsClassPT = null;
3490          }
3491        } else if (this.t.getAttribute("class") !== this.e) {
3492          this.t.setAttribute("class", this.e);
3493        }
3494      };
3495    _registerComplexSpecialProp("className", {
3496      parser: function parser(t, e, p, cssp, pt, plugin, vars) {
3497        var b = t.getAttribute("class") || "",
3498          //don't use t.className because it doesn't work consistently on SVG elements; getAttribute("class") and setAttribute("class", value") is more reliable.
3499          cssText = t.style.cssText,
3500          difData,
3501          bs,
3502          cnpt,
3503          cnptLookup,
3504          mpt;
3505        pt = cssp._classNamePT = new CSSPropTween(t, p, 0, 0, pt, 2);
3506        pt.setRatio = _setClassNameRatio;
3507        pt.pr = -11;
3508        _hasPriority = true;
3509        pt.b = b;
3510        bs = _getAllStyles(t, _cs);
3511        //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
3511ing that were there just for class-specific values)
3512        cnpt = t._gsClassPT;
3513        if (cnpt) {
3514          cnptLookup = {};
3515          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.
3516          while (mpt) {
3517            cnptLookup[mpt.p] = 1;
3518            mpt = mpt._next;
3519          }
3520          cnpt.setRatio(1);
3521        }
3522        t._gsClassPT = pt;
3523        pt.e = e.charAt(1) !== "=" ? e : b.replace(new RegExp("(?:\\s|^)" + e.substr(2) + "(?![\\w-])"), "") + (e.charAt(0) === "+" ? " " + e.substr(2) : "");
3524        t.setAttribute("class", pt.e);
3525        difData = _cssDif(t, bs, _getAllStyles(t), vars, cnptLookup);
3526        t.setAttribute("class", b);
3527        pt.data = difData.firstMPT;
3528        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).
3529        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)
3530        return pt;
3531      }
3532    });
3533    var _setClearPropsRatio = function _setClearPropsRatio(v) {
3534      if (v === 1 || v === 0) if (this.data._totalTime === this.data._totalDuration && this.data.data !== "isFromStart") {
3535        //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).
3536        var s = this.t.style,
3537          transformParse = _specialProps.transform.parse,
3538          a,
3539          p,
3540          i,
3541          clearTransform,
3542          transform;
3543        if (this.e === "all") {
3544          s.cssText = "";
3545          clearTransform = true;
3546        } else {
3547          a = this.e.split(" ").join("").split(",");
3548          i = a.length;
3549          while (--i > -1) {
3550            p = a[i];
3551            if (_specialProps[p]) {
3552              if (_specialProps[p].parse === transformParse) {
3553                clearTransform = true;
3554              } else {
3555                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"
3556              }
3557            }
3558            _removeProp(s, p);
3559          }
3560        }
3561        if (clearTransform) {
3562          _removeProp(s, _transformProp);
3563          transform = this.t._gsTransform;
3564          if (transform) {
3565            if (transform.svg) {
3566              this.t.removeAttribute("data-svg-origin");
3567              this.t.removeAttribute("transform");
3568            }
3569            delete this.t._gsTransform;
3570          }
3571        }
3572      }
3573    };
3574    _registerComplexSpecialProp("clearProps", {
3575      parser: function parser(t, e, p, cssp, pt) {
3576        pt = new CSSPropTween(t, p, 0, 0, pt, 2);
3577        pt.setRatio = _setClearPropsRatio;
3578        pt.e = e;
3579        pt.pr = -10;
3580        pt.data = cssp._tween;
3581        _hasPriority = true;
3582        return pt;
3583      }
3584    });
3585    p = "bezier,throwProps,physicsProps,physics2D".split(",");
3586    i = p.length;
3587    while (i--) {
3588      _registerPluginProp(p[i]);
3589    }
3590    p = _CSSPlugin.prototype;
3591    p._firstPT = p._lastParsedTransform = p._transform = null;
3592
3593    //gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc.
3594    p._onInitTween = function (target, vars, tween, index) {
3595      if (!target.nodeType) {
3596        //css is only for dom elements
3597        return false;
3598      }
3599      this._target = _target = target;
3600      this._tween = tween;
3601      this._vars = vars;
3602      _index = index;
3603      _autoRound = vars.autoRound;
3604      _hasPriority = false;
3605      _suffixMap = vars.suffixMap || _CSSPlugin.suffixMap;
3606      _cs = _getComputedStyle(target, "");
3607      _overwriteProps = this._overwriteProps;
3608      var style = target.style,
3609        v,
3610        pt,
3611        pt2,
3612        first,
3613        last,
3614        next,
3615        zIndex,
3616        tpt,
3617        threeD;
3618      if (_reqSafariFix) if (style.zIndex === "") {
3619        v = _getStyle(target, "zIndex", _cs);
3620        if (v === "auto" || v === "") {
3621          //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.
3622          this._addLazySet(style, "zIndex", 0);
3623        }
3624      }
3625      if (typeof vars === "string") {
3626        first = style.cssText;
3627        v = _getAllStyles(target, _cs);
3628        style.cssText = first + ";" + vars;
3629        v = _cssDif(target, v, _getAllStyles(target)).difs;
3630        if (!_supportsOpacity && _opacityValExp.test(vars)) {
3631          v.opacity = parseFloat(RegExp.$1);
3632        }
3633        vars = v;
3634        style.cssText = first;
3635      }
3636      if (vars.className) {
3637        //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.
3638        this._firstPT = pt = _specialProps.className.parse(target, vars.className, "className", this, null, null, vars);
3639      } else {
3640        this._firstPT = pt = this.parse(target, vars, null);
3641      }
3642      if (this._transformType) {
3643        threeD = this._transformType === 3;
3644        if (!_transformProp) {
3645          style.zoom = 1; //helps correct an IE issue.
3646        } else if (_isSafari) {
3647          _reqSafariFix = true;
3648          //if zIndex isn't set, iOS Safari doesn't repaint things correctly sometimes (seemingly at random).
3649          if (style.zIndex === "") {
3650            zIndex = _getStyle(target, "zIndex", _cs);
3651            if (zIndex === "auto" || zIndex === "") {
3652              this._addLazySet(style, "zIndex", 0);
3653            }
3654          }
3655          //Setting WebkitBackfaceVisibility corrects 3 bugs:
3656          // 1) [non-Android] Safari skips rendering changes to "top" and "left" that are made on the same frame/render as a transform update.
3657          // 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.
3658          // 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.
3659          //Note: we allow the user to override the auto-setting by defining WebkitBackfaceVisibility in the vars of the tween.
3660          if (_isSafariLT6) {
3661            this._addLazySet(style, "WebkitBackfaceVisibility", this._vars.WebkitBackfaceVisibility || (threeD ? "visible" : "hidden"));
3662          }
3663        }
3664        pt2 = pt;
3665        while (pt2 && pt2._next) {
3666          pt2 = pt2._next;
3667        }
3668        tpt = new CSSPropTween(target, "transform", 0, 0, null, 2);
3669        this._linkCSSP(tpt, null, pt2);
3670        tpt.setRatio = _transformProp ? _setTransformRatio : _setIETransformRatio;
3671        tpt.data = this._transform || _getTransform(target, _cs, true);
3672        tpt.tween = tween;
3673        tpt.pr = -1; //ensures that the transforms get applied after the components are updated.
3674        _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.
3675      }
3676      if (_hasPriority) {
3677        //reorders the linked list in order of pr (priority)
3678        while (pt) {
3679          next = pt._next;
3680          pt2 = first;
3681          while (pt2 && pt2.pr > pt.pr) {
3682            pt2 = pt2._next;
3683          }
3684          if (pt._prev = pt2 ? pt2._prev : last) {
3685            pt._prev._next = pt;
3686          } else {
3687            first = pt;
3688          }
3689          if (pt._next = pt2) {
3690            pt2._prev = pt;
3691          } else {
3692            last = pt;
3693          }
3694          pt = next;
3695        }
3696        this._firstPT = first;
3697      }
3698      return true;
3699    };
3700    p.parse = function (target, vars, pt, plugin) {
3701      var style = target.style,
3702        p,
3703        sp,
3704        bn,
3705        en,
3706        bs,
3707        es,
3708        bsfx,
3709        esfx,
3710        isStr,
3711        rel;
3712      for (p in vars) {
3713        es = vars[p]; //ending value string
3714        if (typeof es === "function") {
3715          es = es(_index, _target);
3716        }
3717        sp = _specialProps[p]; //SpecialProp lookup.
3718        if (sp) {
3719          pt = sp.parse(target, es, p, this, pt, plugin, vars);
3720        } else if (p.substr(0, 2) === "--") {
3721          //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.
3722          this._tween._propLookup[p] = this._addTween.call(this._tween, target.style, "setProperty", _getComputedStyle(target).getPropertyValue(p) + "", es + "", p, false, p);
3723          continue;
3724        } else {
3725          bs = _getStyle(target, p, _cs) + "";
3726          isStr = typeof es === "string";
3727          if (p === "color" || p === "fill" || p === "stroke" || p.indexOf("Color") !== -1 || isStr && _rgbhslExp.test(es)) {
3728            //Opera uses background: to define color sometimes in addition to backgroundColor:
3729            if (!isStr) {
3730              es = _parseColor(es);
3731              es = (es.length > 3 ? "rgba(" : "rgb(") + es.join(",") + ")";
3732            }
3733            pt = _parseComplex(style, p, bs, es, true, "transparent", pt, 0, plugin);
3734          } else if (isStr && _complexExp.test(es)) {
3735            pt = _parseComplex(style, p, bs, es, true, null, pt, 0, plugin);
3736          } else {
3737            bn = parseFloat(bs);
3738            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.
3739
3740            if (bs === "" || bs === "auto") {
3741              if (p === "width" || p === "height") {
3742                bn = _getDimension(target, p, _cs);
3743                bsfx = "px";
3744              } else if (p === "left" || p === "top") {
3745                bn = _calculateOffset(target, p, _cs);
3746                bsfx = "px";
3747              } else {
3748                bn = p !== "opacity" ? 0 : 1;
3749                bsfx = "";
3750              }
3751            }
3752            rel = isStr && es.charAt(1) === "=";
3753            if (rel) {
3754              en = parseInt(es.charAt(0) + "1", 10);
3755              es = es.substr(2);
3756              en *= parseFloat(es);
3757              esfx = es.replace(_suffixExp, "");
3758            } else {
3759              en = parseFloat(es);
3760              esfx = isStr ? es.replace(_suffixExp, "") : "";
3761            }
3762            if (esfx === "") {
3763              esfx = p in _suffixMap ? _suffixMap[p] : bsfx; //populate the end suffix, prioritizing the map, then if none is found, use the beginning suffix.
3764            }
3765            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.
3766            //if the beginning/ending suffixes don't match, normalize them...
3767            if (bsfx !== esfx) if (esfx !== "" || p === "lineHeight") if (en || en === 0) if (bn) {
3768              //note: if the beginning value (bn) is 0, we don't need to convert units!
3769              bn = _convertToPixels(target, p, bn, bsfx);
3770              if (esfx === "%") {
3771                bn /= _convertToPixels(target, p, 100, "%") / 100;
3772                if (vars.strictUnits !== true) {
3773                  //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.
3774                  bs = bn + "%";
3775                }
3776              } else if (esfx === "em" || esfx === "rem" || esfx === "vw" || esfx === "vh") {
3777                bn /= _convertToPixels(target, p, 1, esfx);
3778
3779                //otherwise convert to pixels.
3780              } else if (esfx !== "px") {
3781                en = _convertToPixels(target, p, en, esfx);
3782                esfx = "px"; //we don't use bsfx after this, so we don't need to set it to px too.
3783              }
3784              if (rel) if (en || en === 0) {
3785                es = en + bn + esfx; //the changes we made affect relative calculations, so adjust the end value here.
3786              }
3787            }
3788            if (rel) {
3789              en += bn;
3790            }
3791            if ((bn || bn === 0) && (en || en === 0)) {
3792              //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.
3793              pt = new CSSPropTween(style, p, bn, en - bn, pt, 0, p, _autoRound !== false && (esfx === "px" || p === "zIndex"), 0, bs, es);
3794              pt.xs0 = esfx;
3795              //DEBUG: _log("tween "+p+" from "+pt.b+" ("+bn+esfx+") to "+pt.e+" with suffix: "+pt.xs0);
3796            } else if (style[p] === undefined || !es && (es + "" === "NaN" || es == null)) {
3797              _log("invalid " + p + " tween value: " + vars[p]);
3798            } else {
3799              pt = new CSSPropTween(style, p, en || bn || 0, 0, pt, -1, p, false, 0, bs, es);
3800              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.
3801              //DEBUG: _log("non-tweening value "+p+": "+pt.xs0);
3802            }
3803          }
3804        }
3805        if (plugin) if (pt && !pt.plugin) {
3806          pt.plugin = plugin;
3807        }
3808      }
3809      return pt;
3810    };
3811
3812    //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.
3813    p.setRatio = function (v) {
3814      var pt = this._firstPT,
3815        min = 0.000001,
3816        val,
3817        str,
3818        i;
3819      //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).
3820      if (v === 1 && (this._tween._time === this._tween._duration || this._tween._time === 0)) {
3821        while (pt) {
3822          if (pt.type !== 2) {
3823            if (pt.r && pt.type !== -1) {
3824              val = Math.round(pt.s + pt.c);
3825              if (!pt.type) {
3826                pt.t[pt.p] = val + pt.xs0;
3827              } else if (pt.type === 1) {
3828                //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
3829                i = pt.l;
3830                str = pt.xs0 + val + pt.xs1;
3831                for (i = 1; i < pt.l; i++) {
3832                  str += pt["xn" + i] + pt["xs" + (i + 1)];
3833                }
3834                pt.t[pt.p] = str;
3835              }
3836            } else {
3837              pt.t[pt.p] = pt.e;
3838            }
3839          } else {
3840            pt.setRatio(v);
3841          }
3842          pt = pt._next;
3843        }
3844      } else if (v || !(this._tween._time === this._tween._duration || this._tween._time === 0) || this._tween._rawPrevTime === -0.000001) {
3845        while (pt) {
3846          val = pt.c * v + pt.s;
3847          if (pt.r) {
3848            val = Math.round(val);
3849          } else if (val < min) if (val > -min) {
3850            val = 0;
3851          }
3852          if (!pt.type) {
3853            pt.t[pt.p] = val + pt.xs0;
3854          } else if (pt.type === 1) {
3855            //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
3856            i = pt.l;
3857            if (i === 2) {
3858              pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2;
3859            } else if (i === 3) {
3860              pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3;
3861            } else if (i === 4) {
3862              pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4;
3863            } else if (i === 5) {
3864              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;
3865            } else {
3866              str = pt.xs0 + val + pt.xs1;
3867              for (i = 1; i < pt.l; i++) {
3868                str += pt["xn" + i] + pt["xs" + (i + 1)];
3869              }
3870              pt.t[pt.p] = str;
3871            }
3872          } else if (pt.type === -1) {
3873            //non-tweening value
3874            pt.t[pt.p] = pt.xs0;
3875          }
3875 else if (pt.setRatio) {
3876            //custom setRatio() for things like SpecialProps, external plugins, etc.
3877            pt.setRatio(v);
3878          }
3879          pt = pt._next;
3880        }
3881
3882        //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).
3883      } else {
3884        while (pt) {
3885          if (pt.type !== 2) {
3886            pt.t[pt.p] = pt.b;
3887          } else {
3888            pt.setRatio(v);
3889          }
3890          pt = pt._next;
3891        }
3892      }
3893    };
3894
3895    /**
3896     * @private
3897     * Forces rendering of the target's transforms (rotation, scale, etc.) whenever the CSSPlugin's setRatio() is called.
3898     * Basically, this tells the CSSPlugin to create a CSSPropTween (type 2) after instantiation that runs last in the linked
3899     * list and calls the appropriate (3D or 2D) rendering function. We separate this into its own method so that we can call
3900     * it from other plugins like BezierPlugin if, for example, it needs to apply an autoRotation and this CSSPlugin
3901     * doesn't have any transform-related properties of its own. You can call this method as many times as you
3902     * want and it won't create duplicate CSSPropTweens.
3903     *
3904     * @param {boolean} threeD if true, it should apply 3D tweens (otherwise, just 2D ones are fine and typically faster)
3905     */
3906    p._enableTransforms = function (threeD) {
3907      this._transform = this._transform || _getTransform(this._target, _cs, true); //ensures that the element has a _gsTransform property with the appropriate values.
3908      this._transformType = !(this._transform.svg && _useSVGTransformAttr) && (threeD || this._transformType === 3) ? 3 : 2;
3909    };
3910    var lazySet = function lazySet(v) {
3911      this.t[this.p] = this.e;
3912      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.
3913    };
3914    /** @private Gives us a way to set a value on the first render (and only the first render). **/
3915    p._addLazySet = function (t, p, v) {
3916      var pt = this._firstPT = new CSSPropTween(t, p, 0, 0, this._firstPT, 2);
3917      pt.e = v;
3918      pt.setRatio = lazySet;
3919      pt.data = this;
3920    };
3921
3922    /** @private **/
3923    p._linkCSSP = function (pt, next, prev, remove) {
3924      if (pt) {
3925        if (next) {
3926          next._prev = pt;
3927        }
3928        if (pt._next) {
3929          pt._next._prev = pt._prev;
3930        }
3931        if (pt._prev) {
3932          pt._prev._next = pt._next;
3933        } else if (this._firstPT === pt) {
3934          this._firstPT = pt._next;
3935          remove = true; //just to prevent resetting this._firstPT 5 lines down in case pt._next is null. (optimized for speed)
3936        }
3937        if (prev) {
3938          prev._next = pt;
3939        } else if (!remove && this._firstPT === null) {
3940          this._firstPT = pt;
3941        }
3942        pt._next = next;
3943        pt._prev = prev;
3944      }
3945      return pt;
3946    };
3947    p._mod = function (lookup) {
3948      var pt = this._firstPT;
3949      while (pt) {
3950        if (typeof lookup[pt.p] === "function" && lookup[pt.p] === Math.round) {
3951          //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..
3952          pt.r = 1;
3953        }
3954        pt = pt._next;
3955      }
3956    };
3957
3958    //we need to make sure that if alpha or autoAlpha is killed, opacity is too. And autoAlpha affects the "visibility" property.
3959    p._kill = function (lookup) {
3960      var copy = lookup,
3961        pt,
3962        p,
3963        xfirst;
3964      if (lookup.autoAlpha || lookup.alpha) {
3965        copy = {};
3966        for (p in lookup) {
3967          //copy the lookup so that we're not changing the original which may be passed elsewhere.
3968          copy[p] = lookup[p];
3969        }
3970        copy.opacity = 1;
3971        if (copy.autoAlpha) {
3972          copy.visibility = 1;
3973        }
3974      }
3975      if (lookup.className && (pt = this._classNamePT)) {
3976        //for className tweens, we need to kill any associated CSSPropTweens too; a linked list starts at the className's "xfirst".
3977        xfirst = pt.xfirst;
3978        if (xfirst && xfirst._prev) {
3979          this._linkCSSP(xfirst._prev, pt._next, xfirst._prev._prev); //break off the prev
3980        } else if (xfirst === this._firstPT) {
3981          this._firstPT = pt._next;
3982        }
3983        if (pt._next) {
3984          this._linkCSSP(pt._next, pt._next._next, xfirst._prev);
3985        }
3986        this._classNamePT = null;
3987      }
3988      pt = this._firstPT;
3989      while (pt) {
3990        if (pt.plugin && pt.plugin !== p && pt.plugin._kill) {
3991          //for plugins that are registered with CSSPlugin, we should notify them of the kill.
3992          pt.plugin._kill(lookup);
3993          p = pt.plugin;
3994        }
3995        pt = pt._next;
3996      }
3997      return TweenPlugin.prototype._kill.call(this, copy);
3998    };
3999
4000    //used by cascadeTo() for gathering all the style properties of each child element into an array for c
4000omparison.
4001    var _getChildStyles2 = function _getChildStyles(e, props, targets) {
4002      var children, i, child, type;
4003      if (e.slice) {
4004        i = e.length;
4005        while (--i > -1) {
4006          _getChildStyles2(e[i], props, targets);
4007        }
4008        return;
4009      }
4010      children = e.childNodes;
4011      i = children.length;
4012      while (--i > -1) {
4013        child = children[i];
4014        type = child.type;
4015        if (child.style) {
4016          props.push(_getAllStyles(child));
4017          if (targets) {
4018            targets.push(child);
4019          }
4020        }
4021        if ((type === 1 || type === 9 || type === 11) && child.childNodes.length) {
4022          _getChildStyles2(child, props, targets);
4023        }
4024      }
4025    };
4026
4027    /**
4028     * Typically only useful for className tweens that may affect child elements, this method creates a TweenLite
4029     * and then compares the style properties of all the target's child elements at the tween's start and end, and
4030     * if any are different, it also creates tweens for those and returns an array containing ALL of the resulting
4031     * tweens (so that you can easily add() them to a TimelineLite, for example). The reason this functionality is
4032     * wrapped into a separate static method of CSSPlugin instead of being integrated into all regular className tweens
4033     * is because it creates entirely new tweens that may have completely different targets than the original tween,
4034     * so if they were all lumped into the original tween instance, it would be inconsistent with the rest of the API
4035     * and it would create other problems. For example:
4036     *  - 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)
4037     *  - 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.
4038     *  - 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.
4039     *
4040     * @param {Object} target object to be tweened
4041     * @param {number} Duration in seconds (or frames for frames-based tweens)
4042     * @param {Object} Object containing the end values, like {className:"newClass", ease:Linear.easeNone}
4043     * @return {Array} An array of TweenLite instances
4044     */
4045    _CSSPlugin.cascadeTo = function (target, duration, vars) {
4046      var tween = TweenLite.to(target, duration, vars),
4047        results = [tween],
4048        b = [],
4049        e = [],
4050        targets = [],
4051        _reservedProps = TweenLite._internals.reservedProps,
4052        i,
4053        difs,
4054        p,
4055        from;
4056      target = tween._targets || tween.target;
4057      _getChildStyles2(target, b, targets);
4058      tween.render(duration, true, true);
4059      _getChildStyles2(target, e);
4060      tween.render(0, true, true);
4061      tween._enabled(true);
4062      i = targets.length;
4063      while (--i > -1) {
4064        difs = _cssDif(targets[i], b[i], e[i]);
4065        if (difs.firstMPT) {
4066          difs = difs.difs;
4067          for (p in vars) {
4068            if (_reservedProps[p]) {
4069              difs[p] = vars[p];
4070            }
4071          }
4072          from = {};
4073          for (p in difs) {
4074            from[p] = b[i][p];
4075          }
4076          results.push(TweenLite.fromTo(targets[i], duration, from, difs));
4077        }
4078      }
4079      return results;
4080    };
4081    TweenPlugin.activate([_CSSPlugin]);
4082    return _CSSPlugin;
4083  }, true);
4084});
4085if (_gsScope._gsDefine) {
4086  _gsScope._gsQueue.pop()();
4087}
4088
4089//export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date)
4090(function (name) {
4091  "use strict";
4092
4093  var getGlobal = function getGlobal() {
4094    return (_gsScope.GreenSockGlobals || _gsScope)[name];
4095  };
4096  if (typeof module !== "undefined" && module.exports) {
4097    //node
4098    require("gsap/TweenLite");
4099    module.exports = getGlobal();
4100  } else if (typeof define === "function" && define.amd) {
4101    //AMD
4102    define(["gsap/TweenLite"], getGlobal);
4103  }
4104})("CSSPlugin");
4105
4106}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
4107},{"gsap/TweenLite":4}],3:[function(require,module,exports){
4108(function (global){(function (){
4109"use strict";
4110
4111function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4112/*!
4113 * VERSION: 0.16.2
4114 * DATE: 2018-02-15
4115 * UPDATES AND DOCS AT: http://greensock.com
4116 *
4117 * Requires TweenLite and CSSPlugin version 1.17.0 or later (TweenMax contains both TweenLite and CSSPlugin). ThrowPropsPlugin is required for momentum-based continuation of movement after the mouse/touch is released (ThrowPropsPlugin is a membership benefit of Club GreenSock - http://greensock.com/club/).
4118 *
4119 * @license Copyright (c) 2008-2018, GreenSock. All rights reserved.
4120 * This work is subject to the terms at http://greensock.com/standard-license or for
4121 * Club GreenSock members, the software agreement that was issued with your membership.
4122 *
4123 * @author: Jack Doyle, [email protected]
4124 */
4125var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : void 0 || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node
4126(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () {
4127  "use strict";
4128
4129  _gsScope._gsDefine("utils.Draggable", ["events.EventDispatcher", "TweenLite", "plugins.CSSPlugin"], function (EventDispatcher, TweenLite, CSSPlugin) {
4130    var _tempVarsXY = {
4131        css: {},
4132        data: "_draggable"
4133      },
4134      //speed optimization - we reuse the same vars object for x/y TweenLite.set() calls to minimize garbage collection tasks and improve performance.
4135      _tempVarsX = {
4136        css: {},
4137        data: "_draggable"
4138      },
4139      _tempVarsY = {
4140        css: {},
4141        data: "_draggable"
4142      },
4143      _tempVarsRotation = {
4144        css: {}
4145      },
4146      _globals = _gsScope._gsDefine.globals,
4147      _tempEvent = {},
4148      //for populating with pageX/pageY in old versions of IE
4149      _dummyElement = {
4150        style: {}
4151      },
4152      _doc = _gsScope.document || {
4153        createElement: function createElement() {
4154          return _dummyElement;
4155        }
4156      },
4157      _docElement = _doc.documentElement || {},
4158      _createElement = function _createElement(type) {
4159        return _doc.createElementNS ? _doc.createElementNS("http://www.w3.org/1999/xhtml", type) : _doc.createElement(type);
4160      },
4161      _tempDiv = _createElement("div"),
4162      _emptyArray = [],
4163      _emptyFunc = function _emptyFunc() {
4164        return false;
4165      },
4166      _RAD2DEG = 180 / Math.PI,
4167      _max = 999999999999999,
4168      _getTime = Date.now || function () {
4169        return new Date().getTime();
4170      },
4171      _isOldIE = !!(!_doc.addEventListener && _doc.all),
4172      _placeholderDiv = _doc.createElement("div"),
4173      _renderQueue = [],
4174      _lookup = {},
4175      //when a Draggable is created, the target gets a unique _gsDragID property that allows gets associated with the Draggable instance for quick lookups in Draggable.get(). This avoids circular references that could cause gc problems.
4176      _lookupCount = 0,
4177      _clickableTagExp = /^(?:a|input|textarea|button|select)$/i,
4178      _dragCount = 0,
4179      //total number of elements currently being dragged
4180      _prefix,
4181      _isMultiTouching,
4182      _isAndroid = _gsScope.navigator && _gsScope.navigator.userAgent.toLowerCase().indexOf("android") !== -1,
4183      //Android handles touch events in an odd way and it's virtually impossible to "feature test" so we resort to UA sniffing
4184      _lastDragTime = 0,
4185      _temp1 = {},
4186      // a simple object we reuse and populate (usually x/y properties) to conserve memory and improve performance.
4187      _windowProxy = {},
4188      //memory/performance optimization - we reuse this object during autoScroll to store window-related bounds/offsets.
4189      _slice = function _slice(a) {
4190        //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
4191        if (typeof a === "string") {
4192          a = TweenLite.selector(a);
4193        }
4194        if (!a || a.nodeType) {
4195          //if it's not an array, wrap it in one.
4196          return [a];
4197        }
4198        var b = [],
4199          l = a.length,
4200          i;
4201        for (i = 0; i !== l; b.push(a[i++]));
4202        return b;
4203      },
4204      _copy = function _copy(obj, factor) {
4205        var copy = {},
4206          p;
4207        if (factor) {
4208          for (p in obj) {
4209            copy[p] = obj[p] * factor;
4210          }
4211        } else {
4212          for (p in obj) {
4213            copy[p] = obj[p];
4214          }
4215        }
4216        return copy;
4217      },
4218      ThrowPropsPlugin,
4219      _renderQueueTick = function _renderQueueTick() {
4220        var i = _renderQueue.length;
4221        while (--i > -1) {
4222          _renderQueue[i]();
4223        }
4224      },
4225      _addToRenderQueue = function _addToRenderQueue(func) {
4226        _renderQueue.push(func);
4227        if (_renderQueue.length === 1) {
4228          TweenLite.ticker.addEventListener("tick", _renderQueueTick, this, false, 1);
4229        }
4230      },
4231      _removeFromRenderQueue = function _removeFromRenderQueue(func) {
4232        var i = _renderQueue.length;
4233        while (--i > -1) {
4234          if (_renderQueue[i] === func) {
4235            _renderQueue.splice(i, 1);
4236          }
4237        }
4238        TweenLite.to(_renderQueueTimeout, 0, {
4239          overwrite: "all",
4240          delay: 15,
4241          onComplete: _renderQueueTimeout,
4242          data: "_draggable"
4243        }); //remove the "tick" listener only after the render queue is empty for 15 seconds (to improve performance). Adding/removing it constantly for every click/touch wouldn't deliver optimal speed, and we also don't want the ticker to keep calling the render method when things are idle for long periods of time (we want to improve battery life on mobile devices).
4244      },
4245      _renderQueueTimeout = function _renderQueueTimeout() {
4246        if (!_renderQueue.length) {
4247          TweenLite.ticker.removeEventListener("tick", _renderQueueTick);
4248        }
4249      },
4250      _extend = function _extend(obj, defaults) {
4251        var p;
4252        for (p in defaults) {
4253          if (obj[p] === undefined) {
4254            obj[p] = defaults[p];
4255          }
4256        }
4257        return obj;
4258      },
4259      _getDocScrollTop = function _getDocScrollTop() {
4260        return window.pageYOffset != null ? window.pageYOffset : _doc.scrollTop != null ? _doc.scrollTop : _docElement.scrollTop || _doc.body.scrollTop || 0;
4261      },
4262      _getDocScrollLeft = function _getDocScrollLeft() {
4263        return window.pageXOffset != null ? window.pageXOffset : _doc.scrollLeft != null ? _doc.scrollLeft : _docElement.scrollLeft || _doc.body.scrollLeft || 0;
4264      },
4265      _addScrollListener2 = function _addScrollListener(e, callback) {
4266        _addListener(e, "scroll", callback);
4267        if (!_isRoot(e.parentNode)) {
4268          _addScrollListener2(e.parentNode, callback);
4269        }
4270      },
4271      _removeScrollListener2 = function _removeScrollListener(e, callback) {
4272        _removeListener(e, "scroll", callback);
4273        if (!_isRoot(e.parentNode)) {
4274          _removeScrollListener2(e.parentNode, callback);
4275        }
4276      },
4277      _isRoot = function _isRoot(e) {
4278        return !!(!e || e === _docElement || e === _doc || e === _doc.body || e === window || !e.nodeType || !e.parentNode);
4279      },
4280      _getMaxScroll = function _getMaxScroll(element, axis) {
4281        var dim = axis === "x" ? "Width" : "Height",
4282          scroll = "scroll" + dim,
4283          client = "client" + dim,
4284          body = _doc.body;
4285        return Math.max(0, _isRoot(element) ? Math.max(_docElement[scroll], body[scroll]) - (window["inner" + dim] || _docElement[client] || body[client]) : element[scroll] - element[client]);
4286      },
4287      _recordMaxScrolls2 = function _recordMaxScrolls(e) {
4288        //records _gsMaxScrollX and _gsMaxScrollY properties for the element and all ancestors up the chain so that we can cap it, otherwise dragging beyond the edges with autoScroll on can endlessly scroll.
4289        var isRoot = _isRoot(e),
4290          x = _getMaxScroll(e, "x"),
4291          y = _getMaxScroll(e, "y");
4292        if (isRoot) {
4293          e = _windowProxy;
4294        } else {
4295          _recordMaxScrolls2(e.parentNode);
4296        }
4297        e._gsMaxScrollX = x;
4298        e._gsMaxScrollY = y;
4299        e._gsScrollX = e.scrollLeft || 0;
4300        e._gsScrollY = e.scrollTop || 0;
4301      },
4302      //just used for IE8 and earlier to normalize events and populate pageX/pageY
4303      _populateIEEvent = function _populateIEEvent(e, preventDefault) {
4304        e = e || window.event;
4305        _tempEvent.pageX = e.clientX + _doc.body.scrollLeft + _docElement.scrollLeft;
4306        _tempEvent.pageY = e.clientY + _doc.body.scrollTop + _docElement.scrollTop;
4307        if (preventDefault) {
4308          e.returnValue = false;
4309        }
4310        return _tempEvent;
4311      },
4312      //grabs the first element it finds (and we include the window as an element), so if it's selector text, it'll feed that value to TweenLite.selector, if it's a jQuery object or some other selector engine's result, it'll grab the first one, and same for an array. If the value doesn't contain a DOM element, it'll just return null.
4313      _unwrapElement = function _unwrapElement(value) {
4314        if (!value) {
4315          return value;
4316        }
4317        if (typeof value === "string") {
4318          value = TweenLite.selector(value);
4319        }
4320        if (value.length && value !== window && value[0] && value[0].style && !value.nodeType) {
4321          value = value[0];
4322        }
4323        return value === window || value.nodeType && value.style ? value : null;
4324      },
4325      _checkPrefix = function _checkPrefix(e, p) {
4326        var s = e.style,
4327          capped,
4328          i,
4329          a;
4330        if (s[p] === undefined) {
4331          a = ["O", "Moz", "ms", "Ms", "Webkit"];
4332          i = 5;
4333          capped = p.charAt(0).toUpperCase() + p.substr(1);
4334          while (--i > -1 && s[a[i] + capped] === undefined) {}
4335          if (i < 0) {
4336            return "";
4337          }
4338          _prefix = i === 3 ? "ms" : a[i];
4339          p = _prefix + capped;
4340        }
4341        return p;
4342      },
4343      _setStyle = function _setStyle(e, p, value) {
4344        var s = e.style;
4345        if (!s) {
4346          return;
4347        }
4348        if (s[p] === undefined) {
4349          p = _checkPrefix(e, p);
4350        }
4351        if (value == null) {
4352          if (s.removeProperty) {
4353            s.removeProperty(p.replace(/([A-Z])/g, "-$1").toLowerCase());
4354          } else {
4355            //note: old versions of IE use "removeAttribute()" instead of "removeProperty()"
4356            s.removeAttribute(p);
4357          }
4358        } else if (s[p] !== undefined) {
4359          s[p] = value;
4360        }
4361      },
4362      _getComputedStyle = _doc.defaultView ? _doc.defaultView.getComputedStyle : _emptyFunc,
4363      _horizExp = /(?:Left|Right|Width)/i,
4364      _suffixExp = /(?:\d|\-|\+|=|#|\.)*/g,
4365      _convertToPixels2 = function _convertToPixels(t, p, v, sfx, recurse) {
4366        if (sfx === "px" || !sfx) {
4367          return v;
4368        }
4369        if (sfx === "auto" || !v) {
4370          return 0;
4371        }
4372        var horiz = _horizExp.test(p),
4373          node = t,
4374          style = _tempDiv.style,
4375          neg = v < 0,
4376          pix;
4377        if (neg) {
4378          v = -v;
4379        }
4380        if (sfx === "%" && p.indexOf("border") !== -1) {
4381          pix = v / 100 * (horiz ? t.clientWidth : t.clientHeight);
4382        } else {
4383          style.cssText = "border:0 solid red;position:" + _getStyle(t, "position", true) + ";line-height:0;";
4384          if (sfx === "%" || !node.appendChild) {
4385            node = t.parentNode || _doc.body;
4386            style[horiz ? "width" : "height"] = v + sfx;
4387          } else {
4388            style[horiz ? "borderLeftWidth" : "borderTopWidth"] = v + sfx;
4389          }
4390          node.appendChild(_tempDiv);
4391          pix = parseFloat(_tempDiv[horiz ? "offsetWidth" : "offsetHeight"]);
4392          node.removeChild(_tempDiv);
4393          if (pix === 0 && !recurse) {
4394            pix = _convertToPixels2(t, p, v, sfx, true);
4395          }
4396        }
4397        return neg ? -pix : pix;
4398      },
4399      _calculateOffset = function _calculateOffset(t, p) {
4400        //for figuring out "top" or "left" in px when it's "auto". We need to factor in margin with the offsetLeft/offsetTop
4401        if (_getStyle(t, "position", true) !== "absolute") {
4402          return 0;
4403        }
4404        var dim = p === "left" ? "Left" : "Top",
4405          v = _getStyle(t, "margin" + dim, true);
4406        return t["offset" + dim] - (_convertToPixels2(t, p, parseFloat(v), (v + "").replace(_suffixExp, "")) || 0);
4407      },
4408      _getStyle = function _getStyle(element, prop, keepUnits) {
4409        var rv = (element._gsTransform || {})[prop],
4410          cs;
4411        if (rv || rv === 0) {
4412          return rv;
4413        } else if (element.style[prop]) {
4414          rv = element.style[prop];
4415        } else if (cs = _getComputedStyle(element)) {
4416          rv = cs.getPropertyValue(prop.replace(/([A-Z])/g, "-$1").toLowerCase());
4417          rv = rv || cs.length ? rv : cs[prop]; //Opera behaves VERY strangely - length is usually 0 and cs[prop] is the only way to get accurate results EXCEPT when checking for -o-transform which only works with cs.getPropertyValue()!
4418        } else if (element.currentStyle) {
4419          rv = element.currentStyle[prop];
4420        }
4421        if (rv === "auto" && (prop === "top" || prop === "left")) {
4422          rv = _calculateOffset(element, prop);
4423        }
4424        return keepUnits ? rv : parseFloat(rv) || 0;
4425      },
4426      _dispatchEvent = function _dispatchEvent(instance, type, callbackName) {
4427        var vars = instance.vars,
4428          callback = vars[callbackName],
4429          listeners = instance._listeners[type];
4430        if (typeof callback === "function") {
4431          callback.apply(vars[callbackName + "Scope"] || vars.callbackScope || instance, vars[callbackName + "Params"] || [instance.pointerEvent]);
4432        }
4433        if (listeners) {
4434          instance.dispatchEvent(type);
4435        }
4436      },
4437      _getBounds = function _getBounds(obj, context) {
4438        //accepts any of the following: a DOM element, jQuery object, selector text, or an object defining bounds as {top, left, width, height} or {minX, maxX, minY, maxY}. Returns an object with left, top, width, and height properties.
4439        var e = _unwrapElement(obj),
4440          top,
4441          left,
4442          offset;
4443        if (!e) {
4444          if (obj.left !== undefined) {
4445            offset = _getOffsetTransformOrigin(context); //the bounds should be relative to the origin
4446            return {
4447              left: obj.left - offset.x,
4448              top: obj.top - offset.y,
4449              width: obj.width,
4450              height: obj.height
4451            };
4452          }
4453          left = obj.min || obj.minX || obj.minRotation || 0;
4454          top = obj.min || obj.minY || 0;
4455          return {
4456            left: left,
4457            top: top,
4458            width: (obj.max || obj.maxX || obj.maxRotation || 0) - left,
4459            height: (obj.max || obj.maxY || 0) - top
4460          };
4461        }
4462        return _getElementBounds(e, context);
4463      },
4464      _svgBorderFactor,
4465      _svgBorderScales,
4466      _svgScrollOffset,
4467      _hasBorderBug,
4468      _hasReparentBug,
4469      //some browsers, like Chrome 49, alter the offsetTop/offsetLeft/offsetParent of elements when a non-identity transform is applied.
4470      _setEnvironmentVariables = function _setEnvironmentVariables() {
4471        //some browsers factor the border into the SVG coordinate space, some don't (like Firefox). Some apply transforms to them, some don't. We feature-detect here so we know how to handle the border(s). We can't do this immediately - we must wait for the document.body to exist.
4472        if (!_doc.createElementNS) {
4473          _svgBorderFactor = 0;
4474          _svgBorderScales = false;
4475          return;
4476        }
4477        var div = _createElement("div"),
4478          svg = _doc.createElementNS("http://www.w3.org/2000/svg", "svg"),
4479          wrapper = _createElement("div"),
4480          style = div.style,
4481          parent = _doc.body || _docElement,
4482          isFlex = _getStyle(parent, "display", true) === "flex",
4483          //Firefox bug causes getScreenCTM() to return null when parent is display:flex and the element isn't rendered inside the window (like if it's below the scroll position)
4484          matrix,
4485          e1,
4486          point,
4487          oldValue;
4488        if (_doc.body && _transformProp) {
4489          style.position = "absolute";
4490          parent.appendChild(wrapper);
4491          wrapper.appendChild(div);
4492          oldValue = div.offsetParent;
4493          wrapper.style[_transformProp] = "rotate(1deg)";
4494          _hasReparentBug = div.offsetParent === oldValue;
4495          wrapper.style.position = "absolute";
4496          style.height = "10px";
4497          oldValue = div.offsetTop;
4498          wrapper.style.border = "5px solid red";
4499          _hasBorderBug = oldValue !== div.offsetTop; //some browsers, like Firefox 38, cause the offsetTop/Left to be affected by a parent's border.
4500          parent.removeChild(wrapper);
4501        }
4502        style = svg.style;
4503        svg.setAttributeNS(null, "width", "400px");
4504        svg.setAttributeNS(null, "height", "400px");
4505        svg.setAttributeNS(null, "viewBox", "0 0 400 400");
4506        style.display = "block";
4507        style.boxSizing = "border-box";
4508        style.border = "0px solid red";
4509        style.transform = "none";
4510        // in some browsers (like certain flavors of Android), the getScreenCTM() matrix is contaminated by the scroll position. We can run some logic here to detect that condition, but we ended up not needing this because we found another workaround using getBoundingClientRect().
4511        div.style.cssText = "width:100px;height:100px;overflow:scroll;-ms-overflow-style:none;";
4512        parent.appendChild(div);
4513        div.appendChild(svg);
4514        point = svg.createSVGPoint().matrixTransform(svg.getScreenCTM());
4515        e1 = point.y;
4516        div.scrollTop = 100;
4517        point.x = point.y = 0;
4518        point = point.matrixTransform(svg.getScreenCTM());
4519        _svgScrollOffset = e1 - point.y < 100.1 ? 0 : e1 - point.y - 150;
4520        div.removeChild(svg);
4521        parent.removeChild(div);
4522        // -- end _svgScrollOffset calculation.
4523        parent.appendChild(svg);
4524        if (isFlex) {
4525          parent.style.display = "block"; //Firefox bug causes getScreenCTM() to return null when parent is display:flex and the element isn't rendered inside the window (like if it's below the scroll position)
4526        }
4527        matrix = svg.getScreenCTM();
4528        e1 = matrix.e;
4529        style.border = "50px solid red";
4530        matrix = svg.getScreenCTM();
4531        if (e1 === 0 && matrix.e === 0 && matrix.f === 0 && matrix.a === 1) {
4532          //Opera has a bunch of bugs - it doesn't adjust the x/y of the matrix, nor does it scale when box-sizing is border-box but it does so elsewhere; to get the correct behavior we set _svgBorderScales to true.
4533          _svgBorderFactor = 1;
4534          _svgBorderScales = true;
4535        } else {
4536          _svgBorderFactor = e1 !== matrix.e ? 1 : 0;
4537          _svgBorderScales = matrix.a !== 1;
4538        }
4539        if (isFlex) {
4540          parent.style.display = "flex";
4541        }
4542        parent.removeChild(svg);
4543      },
4544      _supports3D = _checkPrefix(_tempDiv, "perspective") !== "",
4545      // start matrix and point conversion methods...
4546      _transformOriginProp = _checkPrefix(_tempDiv, "transformOrigin").replace(/^ms/g, "Ms").replace(/([A-Z])/g, "-$1").toLowerCase(),
4547      _transformProp = _checkPrefix(_tempDiv, "transform"),
4548      _transformPropCSS = _transformProp.replace(/^ms/g, "Ms").replace(/([A-Z])/g, "-$1").toLowerCase(),
4549      _point1 = {},
4550      //we reuse _point1 and _point2 objects inside matrix and point conversion methods to conserve memory and minimize garbage collection tasks.
4551      _point2 = {},
4552      _SVGElement = _gsScope.SVGElement,
4553      _isSVG = function _isSVG(e) {
4554        return !!(_SVGElement && typeof e.getBBox === "function" && e.getCTM && (!e.parentNode || e.parentNode.getBBox && e.parentNode.getCTM));
4555      },
4556      _isIE10orBelow = (/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(navigator.userAgent) || /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(navigator.userAgent)) && parseFloat(RegExp.$1) < 11,
4557      //Ideally we'd avoid user agent sniffing, but there doesn't seem to be a way to feature-detect and sense a border-related bug that only affects IE10 and IE9.
4558      _tempTransforms = [],
4559      _tempElements = [],
4560      _getSVGOffsets2 = function _getSVGOffsets(e) {
4561        //SVG elements don't always report offsetTop/offsetLeft/offsetParent at all (I'm looking at you, Firefox 29 and Android), so we have to do some work to manufacture those values. You can pass any SVG element and it'll spit back an object with offsetTop, offsetLeft, offsetParent, scaleX, and scaleY properties. We need the scaleX and scaleY to handle the way SVG can resize itself based on the container.
4562        if (!e.getBoundingClientRect || !e.parentNode || !_transformProp) {
4563          return {
4564            offsetTop: 0,
4565            offsetLeft: 0,
4566            scaleX: 1,
4567            scaleY: 1,
4568            offsetParent: _docElement
4569          };
4570        }
4571        if (_Draggable.cacheSVGData !== false && e._dCache && e._dCache.lastUpdate === TweenLite.ticker.frame) {
4572          //performance optimization. Assume that if the offsets are requested again on the same tick, we can just feed back the values we already calculated (no need to keep recalculating until another tick elapses).
4573          return e._dCache;
4574        }
4575        var curElement = e,
4576          cache = _cache(e),
4577          eRect,
4578          parentRect,
4579          offsetParent,
4580          cs,
4581          m,
4582          i,
4583          point1,
4584          point2,
4585          borderWidth,
4586          borderHeight,
4587          width,
4588          height;
4589        cache.lastUpdate = TweenLite.ticker.frame;
4590        if (e.getBBox && !cache.isSVGRoot) {
4591          //if it's a nested/child SVG element, we must find the parent SVG canvas and measure the offset from there.
4592          curElement = e.parentNode;
4593          eRect = e.getBBox();
4594          while (curElement && (curElement.nodeName + "").toLowerCase() !== "svg") {
4595            curElement = curElement.parentNode;
4596          }
4597          cs = _getSVGOffsets2(curElement);
4598          cache.offsetTop = eRect.y * cs.scaleY;
4599          cache.offsetLeft = eRect.x * cs.scaleX;
4600          cache.scaleX = cs.scaleX;
4601          cache.scaleY = cs.scaleY;
4602          cache.offsetParent = curElement || _docElement;
4603          return cache;
4604        }
4605        //only root SVG elements continue here...
4606        offsetParent = cache.offsetParent;
4607        if (offsetParent === _doc.body) {
4608          offsetParent = _docElement; //avoids problems with margins/padding on the body
4609        }
4610        //walk up the ancestors and record any non-identity transforms (and reset them to "none") until we reach the offsetParent. We must do this so that the getBoundingClientRect() is accurate for measuring the offsetTop/offsetLeft. We'll revert the values later...
4611        _tempElements.length = _tempTransforms.length = 0;
4612        while (curElement) {
4613          m = _getStyle(curElement, _transformProp, true);
4614          if (m !== "matrix(1, 0, 0, 1, 0, 0)" && m !== "none" && m !== "translate3d(0px, 0px, 0px)") {
4615            _tempElements.push(curElement);
4616            _tempTransforms.push(curElement.style[_transformProp]);
4617            curElement.style[_transformProp] = "none";
4618          }
4619          if (curElement === offsetParent) {
4620            break;
4621          }
4622          curElement = curElement.parentNode;
4623        }
4624        parentRect = offsetParent.getBoundingClientRect();
4625        m = e.getScreenCTM();
4626        point2 = e.createSVGPoint();
4627        point1 = point2.matrixTransform(m);
4628        point2.x = point2.y = 10;
4629        point2 = point2.matrixTransform(m);
4630        cache.scaleX = (point2.x - point1.x) / 10;
4631        cache.scaleY = (point2.y - point1.y) / 10;
4632        if (_svgBorderFactor === undefined) {
4633          _setEnvironmentVariables();
4634        }
4635        if (cache.borderBox && !_svgBorderScales && e.getAttribute("width")) {
4636          //some browsers (like Safari) don't properly scale the matrix to accommodate the border when box-sizing is border-box, so we must calculate it here...
4637          cs = _getComputedStyle(e) || {};
4638          borderWidth = parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth) || 0;
4639          borderHeight = parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth) || 0;
4640          width = parseFloat(cs.width) || 0;
4641          height = parseFloat(cs.height) || 0;
4642          cache.scaleX *= (width - borderWidth) / width;
4643          cache.scaleY *= (height - borderHeight) / height;
4644        }
4645        if (_svgScrollOffset) {
4646          //some browsers (like Chrome for Android) have bugs in the way getScreenCTM() is reported (it doesn't factor in scroll position), so we must revert to a more expensive technique for calculating offsetTop/Left.
4647          eRect = e.getBoundingClientRect();
4648          cache.offsetLeft = eRect.left - parentRect.left;
4649          cache.offsetTop = eRect.top - parentRect.top;
4650        } else {
4651          cache.offsetLeft = point1.x - parentRect.left;
4652          cache.offsetTop = point1.y - parentRect.top;
4653        }
4654        cache.offsetParent = offsetParent;
4655        i = _tempElements.length;
4656        while (--i > -1) {
4657          _tempElements[i].style[_transformProp] = _tempTransforms[i];
4658        }
4659        return cache;
4660      },
4661      _getOffsetTransformOrigin = function _getOffsetTransformOrigin(e, decoratee) {
4662        //returns the x/y position of the transformOrigin of the element, in its own local coordinate system (pixels), offset from the top left corner.
4663        decoratee = decoratee || {};
4664        if (!e || e === _docElement || !e.parentNode || e === window) {
4665          return {
4666            x: 0,
4667            y: 0
4668          };
4669        }
4670        var cs = _getComputedStyle(e),
4671          v = _transformOriginProp && cs ? cs.getPropertyValue(_transformOriginProp) : "50% 50%",
4672          a = v.split(" "),
4673          x = v.indexOf("left") !== -1 ? "0%" : v.indexOf("right") !== -1 ? "100%" : a[0],
4674          y = v.indexOf("top") !== -1 ? "0%" : v.indexOf("bottom") !== -1 ? "100%" : a[1];
4675        if (y === "center" || y == null) {
4676          y = "50%";
4677        }
4678        if (x === "center" || isNaN(parseFloat(x))) {
4679          //remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it could be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative.
4680          x = "50%";
4681        }
4682        if (e.getBBox && _isSVG(e)) {
4683          //SVG elements must be handled in a special way because their origins are calculated from the top left.
4684          if (!e._gsTransform) {
4685            TweenLite.set(e, {
4686              x: "+=0",
4687              overwrite: false
4688            }); //forces creation of the _gsTransform where we store all the transform components including xOrigin and yOrigin for SVG elements, as of GSAP 1.15.0 which also takes care of calculating the origin from the upper left corner of the SVG canvas.
4689            if (e._gsTransform.xOrigin === undefined) {
4690              console.log("Draggable requires at least GSAP 1.17.0");
4691            }
4692          }
4693          v = e.getBBox();
4694          decoratee.x = e._gsTransform.xOrigin - v.x;
4695          decoratee.y = e._gsTransform.yOrigin - v.y;
4696        } else {
4697          if (e.getBBox && (x + y).indexOf("%") !== -1) {
4698            //Firefox doesn't report offsetWidth/height on <svg> elements.
4699            e = e.getBBox();
4700            e = {
4701              offsetWidth: e.width,
4702              offsetHeight: e.height
4703            };
4704          }
4705          decoratee.x = x.indexOf("%") !== -1 ? e.offsetWidth * parseFloat(x) / 100 : parseFloat(x);
4706          decoratee.y = y.indexOf("%") !== -1 ? e.offsetHeight * parseFloat(y) / 100 : parseFloat(y);
4707        }
4708        return decoratee;
4709      },
4710      _cache = function _cache(e) {
4711        //computes some important values and stores them in a _dCache object attached to the element itself so that we can optimize performance
4712        if (_Draggable.cacheSVGData !== false && e._dCache && e._dCache.lastUpdate === TweenLite.ticker.frame) {
4713          //performance optimization. Assume that if the offsets are requested again on the same tick, we can just feed back the values we already calculated (no need to keep recalculating until another tick elapses).
4714          return e._dCache;
4715        }
4716        var cache = e._dCache = e._dCache || {},
4717          cs = _getComputedStyle(e),
4718          isSVG = e.getBBox && _isSVG(e),
4719          isSVGRoot = (e.nodeName + "").toLowerCase() === "svg",
4720          curSVG;
4721        cache.isSVG = isSVG;
4722        cache.isSVGRoot = isSVGRoot;
4723        cache.borderBox = cs.boxSizing === "border-box";
4724        cache.computedStyle = cs;
4725        if (isSVGRoot) {
4726          //some browsers don't report parentNode on SVG elements.
4727          curSVG = e.parentNode || _docElement;
4728          curSVG.insertBefore(_tempDiv, e);
4729          cache.offsetParent = _tempDiv.offsetParent || _docElement; //in some cases, Firefox still reports offsetParent as null.
4730          curSVG.removeChild(_tempDiv);
4731        } else if (isSVG) {
4732          curSVG = e.parentNode;
4733          while (curSVG && (curSVG.nodeName + "").toLowerCase() !== "svg") {
4734            //offsetParent is always the SVG canvas for SVG elements.
4735            curSVG = curSVG.parentNode;
4736          }
4737          cache.offsetParent = curSVG;
4738        } else {
4739          cache.offsetParent = e.offsetParent;
4740        }
4741        return cache;
4742      },
4743      _getOffset2DMatrix2 = function _getOffset2DMatrix(e, offsetOrigin, parentOffsetOrigin, zeroOr
4743igin, isBase) {
4744        //"isBase" helps us discern context - it should only be true when the element is the base one (the one at which we're starting to walk up the chain). It only matters in cases when it's an <svg> element itself because that's a case when we don't apply scaling.
4745        if (e === window || !e || !e.style || !e.parentNode) {
4746          return [1, 0, 0, 1, 0, 0];
4747        }
4748        var cache = e._dCache || _cache(e),
4749          parent = e.parentNode,
4750          parentCache = parent._dCache || _cache(parent),
4751          cs = cache.computedStyle,
4752          parentOffsetParent = cache.isSVG ? parentCache.offsetParent : parent.offsetParent,
4753          m,
4754          isRoot,
4755          offsets,
4756          rect,
4757          t,
4758          sx,
4759          sy,
4760          offsetX,
4761          offsetY,
4762          parentRect,
4763          borderTop,
4764          borderLeft,
4765          borderTranslateX,
4766          borderTranslateY;
4767        m = cache.isSVG && (e.style[_transformProp] + "").indexOf("matrix") !== -1 ? e.style[_transformProp] : cs ? cs.getPropertyValue(_transformPropCSS) : e.currentStyle ? e.currentStyle[_transformProp] : "1,0,0,1,0,0"; //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
4768        if (e.getBBox && (e.getAttribute("transform") + "").indexOf("matrix") !== -1) {
4769          //SVG can store transform data in its "transform" attribute instead of the CSS, so look for that here (only accept matrix()).
4770          m = e.getAttribute("transform");
4771        }
4772        m = (m + "").match(/(?:\-|\.|\b)(\d|\.|e\-)+/g) || [1, 0, 0, 1, 0, 0];
4773        if (m.length > 6) {
4774          m = [m[0], m[1], m[4], m[5], m[12], m[13]];
4775        }
4776        if (zeroOrigin) {
4777          m[4] = m[5] = 0;
4778        } else if (cache.isSVG && (t = e._gsTransform) && (t.xOrigin || t.yOrigin)) {
4779          //SVGs handle origin very differently. Factor in GSAP's handling of origin values here:
4780          m[0] = parseFloat(m[0]);
4781          m[1] = parseFloat(m[1]);
4782          m[2] = parseFloat(m[2]);
4783          m[3] = parseFloat(m[3]);
4784          m[4] = parseFloat(m[4]) - (t.xOrigin - (t.xOrigin * m[0] + t.yOrigin * m[2]));
4785          m[5] = parseFloat(m[5]) - (t.yOrigin - (t.xOrigin * m[1] + t.yOrigin * m[3]));
4786        }
4787        if (offsetOrigin) {
4788          if (_svgBorderFactor === undefined) {
4789            _setEnvironmentVariables();
4790          }
4791          offsets = cache.isSVG || cache.isSVGRoot ? _getSVGOffsets2(e) : e;
4792          if (cache.isSVG) {
4793            //don't just rely on "instanceof _SVGElement" because if the SVG is embedded via an object tag, it won't work (SVGElement is mapped to a different object))
4794            rect = e.getBBox();
4795            parentRect = parentCache.isSVGRoot ? {
4796              x: 0,
4797              y: 0
4798            } : parent.getBBox();
4799            offsets = {
4800              offsetLeft: rect.x - parentRect.x,
4801              offsetTop: rect.y - parentRect.y,
4802              offsetParent: cache.offsetParent
4803            };
4804          } else if (cache.isSVGRoot) {
4805            borderTop = parseInt(cs.borderTopWidth, 10) || 0;
4806            borderLeft = parseInt(cs.borderLeftWidth, 10) || 0;
4807            borderTranslateX = (m[0] - _svgBorderFactor) * borderLeft + m[2] * borderTop;
4808            borderTranslateY = m[1] * borderLeft + (m[3] - _svgBorderFactor) * borderTop;
4809            sx = offsetOrigin.x;
4810            sy = offsetOrigin.y;
4811            offsetX = sx - (sx * m[0] + sy * m[2]); //accommodate the SVG root's transforms when the origin isn't in the top left.
4812            offsetY = sy - (sx * m[1] + sy * m[3]);
4813            m[4] = parseFloat(m[4]) + offsetX;
4814            m[5] = parseFloat(m[5]) + offsetY;
4815            offsetOrigin.x -= offsetX;
4816            offsetOrigin.y -= offsetY;
4817            sx = offsets.scaleX;
4818            sy = offsets.scaleY;
4819            if (!isBase) {
4820              //when getting the matrix for a root <svg> element itself (NOT in the context of an SVG element that's nested inside of it like a <path>), we do NOT apply the scaling!
4821              offsetOrigin.x *= sx;
4822              offsetOrigin.y *= sy;
4823            }
4824            m[0] *= sx;
4825            m[1] *= sy;
4826            m[2] *= sx;
4827            m[3] *= sy;
4828            if (!_isIE10orBelow) {
4829              offsetOrigin.x += borderTranslateX;
4830              offsetOrigin.y += borderTranslateY;
4831            }
4832            if (parentOffsetParent === _doc.body && offsets.offsetParent === _docElement) {
4833              //to avoid issues with margin/padding on the <body>, we always set the offsetParent to _docElement in the _getSVGOffsets() function but there's a condition we check later in this function for (parentOffsetParent === offsets.offsetParent) which w
4833ould fail if we don't run this logic. In other words, parentOffsetParent may be <body> and the <svg>'s offsetParent is also <body> but artificially set to _docElement to avoid margin/padding issues.
4834              parentOffsetParent = _docElement;
4835            }
4836          } else if (!_hasBorderBug && e.offsetParent) {
4837            offsetOrigin.x += parseInt(_getStyle(e.offsetParent, "borderLeftWidth"), 10) || 0;
4838            offsetOrigin.y += parseInt(_getStyle(e.offsetParent, "borderTopWidth"), 10) || 0;
4839          }
4840          isRoot = parent === _docElement || parent === _doc.body;
4841          m[4] = Number(m[4]) + offsetOrigin.x + (offsets.offsetLeft || 0) - parentOffsetOrigin.x - (isRoot ? 0 : parent.scrollLeft || 0);
4842          m[5] = Number(m[5]) + offsetOrigin.y + (offsets.offsetTop || 0) - parentOffsetOrigin.y - (isRoot ? 0 : parent.scrollTop || 0);
4843          if (parent && _getStyle(e, "position", cs) === "fixed") {
4844            //fixed position elements should factor in the scroll position of the document.
4845            m[4] += _getDocScrollLeft();
4846            m[5] += _getDocScrollTop();
4847          }
4848          if (parent && parent !== _docElement && parentOffsetParent === offsets.offsetParent && !parentCache.isSVG && (!_hasReparentBug || _getOffset2DMatrix2(parent).join("") === "100100")) {
4849            offsets = parentCache.isSVGRoot ? _getSVGOffsets2(parent) : parent;
4850            m[4] -= offsets.offsetLeft || 0;
4851            m[5] -= offsets.offsetTop || 0;
4852            if (!_hasBorderBug && parentCache.offsetParent && !cache.isSVG && !cache.isSVGRoot) {
4853              m[4] -= parseInt(_getStyle(parentCache.offsetParent, "borderLeftWidth"), 10) || 0;
4854              m[5] -= parseInt(_getStyle(parentCache.offsetParent, "borderTopWidth"), 10) || 0;
4855            }
4856          }
4857        }
4858        return m;
4859      },
4860      _getConcatenatedMatrix = function _getConcatenatedMatrix(e, invert) {
4861        if (!e || e === window || !e.parentNode) {
4862          return [1, 0, 0, 1, 0, 0];
4863        }
4864        //note: we keep reusing _point1 and _point2 in order to minimize memory usage and garbage collection chores.
4865        var originOffset = _getOffsetTransformOrigin(e, _point1),
4866          parentOriginOffset = _getOffsetTransformOrigin(e.parentNode, _point2),
4867          m = _getOffset2DMatrix2(e, originOffset, parentOriginOffset, false, !invert),
4868          a,
4869          b,
4870          c,
4871          d,
4872          tx,
4873          ty,
4874          m2,
4875          determinant;
4876        while ((e = e.parentNode) && e.parentNode && e !== _docElement) {
4877          originOffset = parentOriginOffset;
4878          parentOriginOffset = _getOffsetTransformOrigin(e.parentNode, originOffset === _point1 ? _point2 : _point1);
4879          m2 = _getOffset2DMatrix2(e, originOffset, parentOriginOffset);
4880          a = m[0];
4881          b = m[1];
4882          c = m[2];
4883          d = m[3];
4884          tx = m[4];
4885          ty = m[5];
4886          m[0] = a * m2[0] + b * m2[2];
4887          m[1] = a * m2[1] + b * m2[3];
4888          m[2] = c * m2[0] + d * m2[2];
4889          m[3] = c * m2[1] + d * m2[3];
4890          m[4] = tx * m2[0] + ty * m2[2] + m2[4];
4891          m[5] = tx * m2[1] + ty * m2[3] + m2[5];
4892        }
4893        if (invert) {
4894          a = m[0];
4895          b = m[1];
4896          c = m[2];
4897          d = m[3];
4898          tx = m[4];
4899          ty = m[5];
4900          determinant = a * d - b * c;
4901          m[0] = d / determinant;
4902          m[1] = -b / determinant;
4903          m[2] = -c / determinant;
4904          m[3] = a / determinant;
4905          m[4] = (c * ty - d * tx) / determinant;
4906          m[5] = -(a * ty - b * tx) / determinant;
4907        }
4908        return m;
4909      },
4910      _localToGlobal = function _localToGlobal(e, p, fromTopLeft, decoratee, zeroOrigin) {
4911        e = _unwrapElement(e);
4912        var m = _getConcatenatedMatrix(e, false, zeroOrigin),
4913          x = p.x,
4914          y = p.y;
4915        if (fromTopLeft) {
4916          _getOffsetTransformOrigin(e, p);
4917          x -= p.x;
4918          y -= p.y;
4919        }
4920        decoratee = decoratee === true ? p : decoratee || {};
4921        decoratee.x = x * m[0] + y * m[2] + m[4];
4922        decoratee.y = x * m[1] + y * m[3] + m[5];
4923        return decoratee;
4924      },
4925      _localizePoint = function _localizePoint(p, localToGlobal, globalToLocal) {
4926        var x = p.x * localToGlobal[0] + p.y * localToGlobal[2] + localToGlobal[4],
4927          y = p.x * localToGlobal[1] + p.y * localToGlobal[3] + localToGlobal[5];
4928        p.x = x * globalToLocal[0] + y * globalToLocal[2] + globalToLocal[4];
4929        p.y = x * globalToLocal[1] + y * globalToLocal[3] + globalToLocal[5];
4930        return p;
4931      },
4932      _getElementBounds = function _getElementBounds(e, context, fromTopLeft) {
4933        if (!(e = _unwrapElement(e))) {
4934          return null;
4935        }
4936        context = _unwrapElement(context);
4937        var isSVG = e.getBBox && _isSVG(e),
4938          origin,
4939          left,
4940          right,
4941          top,
4942          bottom,
4943          mLocalToGlobal,
4944          mGlobalToLocal,
4945          p1,
4946          p2,
4947          p3,
4948          p4,
4949          bbox,
4950          width,
4951          height,
4952          cache,
4953          borderLeft,
4954          borderTop,
4955          viewBox,
4956          viewBoxX,
4957          viewBoxY,
4958          computedDimensions,
4959          cs;
4960        if (e === window) {
4961          top = _getDocScrollTop();
4962          left = _getDocScrollLeft();
4963          right = left + (_docElement.clientWidth || e.innerWidth || _doc.body.clientWidth || 0);
4964          bottom = top + ((e.innerHeight || 0) - 20 < _docElement.clientHeight ? _docElement.clientHeight : e.innerHeight || _doc.body.clientHeight || 0); //some browsers (like Firefox) ignore absolutely positioned elements, and collapse the height of the documentElement, so it could be 8px, for example, if you have just an absolutely positioned div. In that case, we use the innerHeight to resolve this.
4965        } else if (context === undefined || context === window) {
4966          return e.getBoundingClientRect();
4967        } else {
4968          origin = _getOffsetTransformOrigin(e);
4969          left = -origin.x;
4970          top = -origin.y;
4971          if (isSVG) {
4972            bbox = e.getBBox();
4973            width = bbox.width;
4974            height = bbox.height;
4975          } else if ((e.nodeName + "").toLowerCase() !== "svg" && e.offsetWidth) {
4976            //Chrome dropped support for "offsetWidth" on SVG elements
4977            width = e.offsetWidth;
4978            height = e.offsetHeight;
4979          } else {
4980            computedDimensions = _getComputedStyle(e);
4981            width = parseFloat(computedDimensions.width);
4982            height = parseFloat(computedDimensions.height);
4983          }
4984          right = left + width;
4985          bottom = top + height;
4986          if (e.nodeName.toLowerCase() === "svg" && !_isOldIE) {
4987            //root SVG elements are a special beast because they have 2 types of scaling - transforms on themselves as well as the stretching of the SVG canvas itself based on the outer size and the viewBox. If, for example, the SVG's viewbox is "0 0 100 100" but the CSS is set to width:200px; height:200px, that'd make it appear at 2x scale even though the element itself has no CSS transforms but the offsetWidth/offsetHeight are based on that css, not the viewBox so we need to adjust them accordingly.
4988            cache = _getSVGOffsets2(e);
4989            cs = cache.computedStyle || {};
4990            viewBox = (e.getAttribute("viewBox") || "0 0").split(" ");
4991            viewBoxX = parseFloat(viewBox[0]);
4992            viewBoxY = parseFloat(viewBox[1]);
4993            borderLeft = parseFloat(cs.borderLeftWidth) || 0;
4994            borderTop = parseFloat(cs.borderTopWidth) || 0;
4995            right -= width - (width - borderLeft) / cache.scaleX - viewBoxX;
4996            bottom -= height - (height - borderTop) / cache.scaleY - viewBoxY;
4997            left -= borderLeft / cache.scaleX - viewBoxX;
4998            top -= borderTop / cache.scaleY - viewBoxY;
4999            if (computedDimensions) {
5000              //when we had to use computed styles, factor in the border now.
5001              right += (parseFloat(cs.borderRightWidth) + borderLeft) / cache.scaleX;
5002              bottom += (borderTop + parseFloat(cs.borderBottomWidth)) / cache.scaleY;
5003            }
5004          }
5005        }
5006        if (e === context) {
5007          return {
5008            left: left,
5009            top: top,
5010            width: right - left,
5011            height: bottom - top
5012          };
5013        }
5014        mLocalToGlobal = _getConcatenatedMatrix(e);
5015        mGlobalToLocal = _getConcatenatedMatrix(context, true);
5016        p1 = _localizePoint({
5017          x: left,
5018          y: top
5019        }, mLocalToGlobal, mGlobalToLocal);
5020        p2 = _localizePoint({
5021          x: right,
5022          y: top
5023        }, mLocalToGlobal, mGlobalToLocal);
5024        p3 = _localizePoint({
5025          x: right,
5026          y: bottom
5027        }, mLocalToGlobal, mGlobalToLocal);
5028        p4 = _localizePoint({
5029          x: left,
5030          y: bottom
5031        }, mLocalToGlobal, mGlobalToLocal);
5032        left = Math.min(p1.x, p2.x, p3.x, p4.x);
5033        top = Math.min(p1.y, p2.y, p3.y, p4.y);
5034        _temp1.x = _temp1.y = 0;
5035        if (fromTopLeft) {
5036          _getOffsetTransformOrigin(context, _temp1);
5037        }
5038        return {
5039          left: left + _temp1.x,
5040          top: top + _temp1.y,
5041          width: Math.max(p1.x, p2.x, p3.x, p4.x) - left,
5042          height: Math.max(p1.y, p2.y, p3.y, p4.y) - top
5043        };
5044      },
5045      // end matrix and point conversion methods
5046
5047      _isArrayLike = function _isArrayLike(e) {
5048        return e && e.length && e[0] && (e[0].nodeType && e[0].style && !e.nodeType || e[0].length && e[0][0]) ? true : false; //could be an array of jQuery objects too, so accommodate that.
5049      },
5050      _flattenArray = function _flattenArray(a) {
5051        var result = [],
5052          l = a.length,
5053          i,
5054          e,
5055          j;
5056        for (i = 0; i < l; i++) {
5057          e = a[i];
5058          if (_isArrayLike(e)) {
5059            j = e.length;
5060            for (j = 0; j < e.length; j++) {
5061              result.push(e[j]);
5062            }
5063          } else if (e && e.length !== 0) {
5064            result.push(e);
5065          }
5066        }
5067        return result;
5068      },
5069      _isTouchDevice = "ontouchstart" in _docElement && "orientation" in window,
5070      _touchEventLookup = function (types) {
5071        //we create an object that makes it easy to translate touch event types into their "pointer" counterparts if we're in a browser that uses those instead. Like IE10 uses "MSPointerDown" instead of "touchstart", for example.
5072        var standard = types.split(","),
5073          converted = (_tempDiv.onpointerdown !== undefined ? "pointerdown,pointermove,pointerup,pointercancel" : _tempDiv.onmspointerdown !== undefined ? "MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancel" : types).split(","),
5074          obj = {},
5075          i = 4;
5076        while (--i > -1) {
5077          obj[standard[i]] = converted[i];
5078          obj[converted[i]] = standard[i];
5079        }
5080        return obj;
5081      }("touchstart,touchmove,touchend,touchcancel"),
5082      _addListener = function _addListener(element, type, func, capture) {
5083        if (element.addEventListener) {
5084          element.addEventListener(_touchEventLookup[type], func, capture);
5085          if (type !== _touchEventLookup[type]) {
5086            //some browsers actually support both, so must we.
5087            element.addEventListener(type, func, capture);
5088          }
5089        } else if (element.attachEvent) {
5090          element.attachEvent("on" + type, func);
5091        }
5092      },
5093      _removeListener = function _removeListener(element, type, func) {
5094        if (element.removeEventListener) {
5095          element.removeEventListener(_touchEventLookup[type], func);
5096          if (type !== _touchEventLookup[type]) {
5097            element.removeEventListener(type, func);
5098          }
5099        } else if (element.detachEvent) {
5100          element.detachEvent("on" + type, func);
5101        }
5102      },
5103      _hasTouchID = function _hasTouchID(list, ID) {
5104        var i = list.length;
5105        while (--i > -1) {
5106          if (list[i].identifier === ID) {
5107            return true;
5108          }
5109        }
5110        return false;
5111      },
5112      _onMultiTouchDocumentEnd2 = function _onMultiTouchDocumentEnd(e) {
5113        _isMultiTouching = e.touches && _dragCount < e.touches.length;
5114        _removeListener(e.target, "touchend", _onMultiTouchDocumentEnd2);
5115      },
5116      _onMultiTouchDocument = function _onMultiTouchDocument(e) {
5117        _isMultiTouching = e.touches && _dragCount < e.touches.length;
5118        _addListener(e.target, "touchend", _onMultiTouchDocumentEnd2);
5119      },
5120      _parseThrowProps = function _parseThrowProps(draggable, snap, max, min, factor, forceZeroVelocity) {
5121        var vars = {},
5122          a,
5123          i,
5124          l;
5125        if (snap) {
5126          if (factor !== 1 && snap instanceof Array) {
5127            //some data must be altered to make sense, like if the user passes in an array of rotational values in degrees, we must convert it to radians. Or for scrollLeft and scrollTop, we invert the values.
5128            vars.end = a = [];
5129            l = snap.length;
5130            if (_typeof(snap[0]) === "object") {
5131              //if the array is populated with objects, like points ({x:100, y:200}), make copies before multiplying by the factor, otherwise we'll mess up the originals and the user may reuse it elsewhere.
5132              for (i = 0; i < l; i++) {
5133                a[i] = _copy(snap[i], factor);
5134              }
5135            } else {
5136              for (i = 0; i < l; i++) {
5137                a[i] = snap[i] * factor;
5138              }
5139            }
5140            max += 1.1; //allow 1.1 pixels of wiggle room when snapping in order to work around some browser inconsistencies in the way bounds are reported which can make them roughly a pixel off. For example, if "snap:[-$('#menu').width(), 0]" was defined and #menu had a wrapper that was used as the bounds, some browsers would be one pixel off, making the minimum -752 for example when snap was [-753,0], thus instead of snapping to -753, it would snap to 0 since -753 was below the minimum.
5141            min -= 1.1;
5142          } else if (typeof snap === "function") {
5143            vars.end = function (value) {
5144              var result = snap.call(draggable, value),
5145                copy,
5146                p;
5147              if (factor !== 1) {
5148                if (_typeof(result) === "object") {
5149                  copy = {};
5150                  for (p in result) {
5151                    copy[p] = result[p] * factor;
5152                  }
5153                  result = copy;
5154                } else {
5155                  result *= factor;
5156                }
5157              }
5158              return result; //we need to ensure that we can scope the function call to the Draggable instance itself so that users can access important values like maxX, minX, maxY, minY, x, and 
5158y from within that function.
5159            };
5160          } else {
5161            vars.end = snap;
5162          }
5163        }
5164        if (max || max === 0) {
5165          vars.max = max;
5166        }
5167        if (min || min === 0) {
5168          vars.min = min;
5169        }
5170        if (forceZeroVelocity) {
5171          vars.velocity = 0;
5172        }
5173        return vars;
5174      },
5175      _isClickable2 = function _isClickable(e) {
5176        //sometimes it's convenient to mark an element as clickable by adding a data-clickable="true" attribute (in which case we won't preventDefault() the mouse/touch event). This method checks if the element is an <a>, <input>, or <button> or has an onclick or has the data-clickable or contentEditable attribute set to true (or any of its parent elements).
5177        var data;
5178        return !e || !e.getAttribute || e.nodeName === "BODY" ? false : (data = e.getAttribute("data-clickable")) === "true" || data !== "false" && (e.onclick || _clickableTagExp.test(e.nodeName + "") || e.getAttribute("contentEditable") === "true") ? true : _isClickable2(e.parentNode);
5179      },
5180      _setSelectable = function _setSelectable(elements, selectable) {
5181        var i = elements.length,
5182          e;
5183        while (--i > -1) {
5184          e = elements[i];
5185          e.ondragstart = e.onselectstart = selectable ? null : _emptyFunc;
5186          _setStyle(e, "userSelect", selectable ? "text" : "none");
5187        }
5188      },
5189      _addPaddingBR,
5190      _addPaddingLeft = function () {
5191        //this function is in charge of analyzing browser behavior related to padding. It sets the _addPaddingBR to true if the browser doesn't normally factor in the bottom or right padding on the element inside the scrolling area, and it sets _addPaddingLeft to true if it's a browser that requires the extra offset (offsetLeft) to be added to the paddingRight (like Opera).
5192        var div = _doc.createElement("div"),
5193          child = _doc.createElement("div"),
5194          childStyle = child.style,
5195          parent = _doc.body || _tempDiv,
5196          val;
5197        childStyle.display = "inline-block";
5198        childStyle.position = "relative";
5199        div.style.cssText = child.innerHTML = "width:90px; height:40px; padding:10px; overflow:auto; visibility: hidden";
5200        div.appendChild(child);
5201        parent.appendChild(div);
5202        _addPaddingBR = child.offsetHeight + 18 > div.scrollHeight; //div.scrollHeight should be child.offsetHeight + 20 because of the 10px of padding on each side, but some browsers ignore one side. We allow a 2px margin of error.
5203        childStyle.width = "100%";
5204        if (!_transformProp) {
5205          childStyle.paddingRight = "500px";
5206          val = div.scrollLeft = div.scrollWidth - div.clientWidth;
5207          childStyle.left = "-90px";
5208          val = val !== div.scrollLeft;
5209        }
5210        parent.removeChild(div);
5211        return val;
5212      }(),
5213      //The ScrollProxy class wraps an element's contents into another div (we call it "content") that we either add padding when necessary or apply a translate3d() transform in order to overscroll (scroll past the boundaries). This allows us to simply set the scrollTop/scrollLeft (or top/left for easier reverse-axis orientation, which is what we do in Draggable) and it'll do all the work for us. For example, if we tried setting scrollTop to -100 on a normal DOM element, it wouldn't work - it'd look the same as setting it to 0, but if we set scrollTop of a ScrollProxy to -100, it'll give the correct appearance by either setting paddingTop of the wrapper to 100 or applying a 100-pixel translateY.
5214      ScrollProxy = function ScrollProxy(element, vars) {
5215        element = _unwrapElement(element);
5216        vars = vars || {};
5217        var content = _doc.createElement("div"),
5218          style = content.style,
5219          node = element.firstChild,
5220          offsetTop = 0,
5221          offsetLeft = 0,
5222          prevTop = element.scrollTop,
5223          prevLeft = element.scrollLeft,
5224          scrollWidth = element.scrollWidth,
5225          scrollHeight = element.scrollHeight,
5226          extraPadRight = 0,
5227          maxLeft = 0,
5228          maxTop = 0,
5229          elementWidth,
5230          elementHeight,
5231          contentHeight,
5232          nextNode,
5233          transformStart,
5234          transformEnd;
5235        if (_supports3D && vars.force3D !== false) {
5236          transformStart = "translate3d(";
5237          transformEnd = "px,0px)";
5238        } else if (_transformProp) {
5239          transformStart = "translate(";
5240          transformEnd = "px)";
5241        }
5242        this.scrollTop = function (value, force) {
5243          if (!arguments.length) {
5244            return -this.top();
5245          }
5246          this.top(-value, force);
5247        };
5248        this.scrollLeft = function (value, force) {
5249          if (!arguments.length) {
5250            return -this.left();
5251          }
5252          this.left(-value, force);
5253        };
5254        this.left = function (value, force) {
5255          if (!arguments.length) {
5256            return -(element.scrollLeft + offsetLeft);
5257          }
5258          var dif = element.scrollLeft - prevLeft,
5259            oldOffset = offsetLeft;
5260          if ((dif > 2 || dif < -2) && !force) {
5261            //if the user interacts with the scrollbar (or something else scrolls it, like the mouse wheel), we should kill any tweens of the ScrollProxy.
5262            prevLeft = element.scrollLeft;
5263            TweenLite.killTweensOf(this, true, {
5264              left: 1,
5265              scrollLeft: 1
5266            });
5267            this.left(-prevLeft);
5268            if (vars.onKill) {
5269              vars.onKill();
5270            }
5271            return;
5272          }
5273          value = -value; //invert because scrolling works in the opposite direction
5274          if (value < 0) {
5275            offsetLeft = value - 0.5 | 0;
5276            value = 0;
5277          } else if (value > maxLeft) {
5278            offsetLeft = value - maxLeft | 0;
5279            value = maxLeft;
5280          } else {
5281            offsetLeft = 0;
5282          }
5283          if (offsetLeft || oldOffset) {
5284            if (transformStart) {
5285              if (!this._suspendTransforms) {
5286                style[_transformProp] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd;
5287              }
5288            } else {
5289              style.left = -offsetLeft + "px";
5290            }
5291            if (_addPaddingLeft && offsetLeft + extraPadRight >= 0) {
5292              style.paddingRight = offsetLeft + extraPadRight + "px";
5293            }
5294          }
5295          element.scrollLeft = value | 0;
5296          prevLeft = element.scrollLeft; //don't merge this with the line above because some browsers adjsut the scrollLeft after it's set, so in order to be 100% accurate in tracking it, we need to ask the browser to report it.
5297        };
5298        this.top = function (value, force) {
5299          if (!arguments.length) {
5300            return -(element.scrollTop + offsetTop);
5301          }
5302          var dif = element.scrollTop - prevTop,
5303            oldOffset = offsetTop;
5304          if ((dif > 2 || dif < -2) && !force) {
5305            //if the user interacts with the scrollbar (or something else scrolls it, like the mouse wheel), we should kill any tweens of the ScrollProxy.
5306            prevTop = element.scrollTop;
5307            TweenLite.killTweensOf(this, true, {
5308              top: 1,
5309              scrollTop: 1
5310            });
5311            this.top(-prevTop);
5312            if (vars.onKill) {
5313              vars.onKill();
5314            }
5315            return;
5316          }
5317          value = -value; //invert because scrolling works in the opposite direction
5318          if (value < 0) {
5319            offsetTop = value - 0.5 | 0;
5320            value = 0;
5321          } else if (value > maxTop) {
5322            offsetTop = value - maxTop | 0;
5323            value = maxTop;
5324          } else {
5325            offsetTop = 0;
5326          }
5327          if (offsetTop || oldOffset) {
5328            if (transformStart) {
5329              if (!this._suspendTransforms) {
5330                style[_transformProp] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd;
5331              }
5332            } else {
5333              style.top = -offsetTop + "px";
5334            }
5335          }
5336          element.scrollTop = value | 0;
5337          prevTop = element.scrollTop;
5338        };
5339        this.maxScrollTop = function () {
5340          return maxTop;
5341        };
5342        this.maxScrollLeft = function () {
5343          return maxLeft;
5344        };
5345        this.disable = function () {
5346          node = content.firstChild;
5347          while (node) {
5348            nextNode = node.nextSibling;
5349            element.appendChild(node);
5350            node = nextNode;
5351          }
5352          if (element === content.parentNode) {
5353            //in case disable() is called when it's already disabled.
5354            element.removeChild(content);
5355          }
5356        };
5357        this.enable = function () {
5358          node = element.firstChild;
5359          if (node === content) {
5360            return;
5361          }
5362          while (node) {
5363            nextNode = node.nextSibling;
5364            content.appendChild(node);
5365            node = nextNode;
5366          }
5367          element.appendChild(content);
5368          this.calibrate();
5369        };
5370        this.calibrate = function (force) {
5371          var widthMatches = element.clientWidth === elementWidth,
5372            x,
5373            y;
5374          prevTop = element.scrollTop;
5375          prevLeft = element.scrollLeft;
5376          if (widthMatches && element.clientHeight === elementHeight && content.offsetHeight === contentHeight && scrollWidth === element.scrollWidth && scrollHeight === element.scrollHeight && !force) {
5377            return; //no need to recalculate things if the width and height haven't changed.
5378          }
5379          if (offsetTop || offsetLeft) {
5380            x = this.left();
5381            y = this.top();
5382            this.left(-element.scrollLeft);
5383            this.top(-element.scrollTop);
5384          }
5385          //first, we need to remove any width constraints to see how the content naturally flows so that we can see if it's wider than the containing element. If so, we've got to re
5385cord the amount of overage so that we can apply that as padding in order for browsers to correctly handle things. Then we switch back to a width of 100% (without that, some browsers don't flow the content correctly)
5386          if (!widthMatches || force) {
5387            style.display = "block";
5388            style.width = "auto";
5389            style.paddingRight = "0px";
5390            extraPadRight = Math.max(0, element.scrollWidth - element.clientWidth);
5391            //if the content is wider than the container, we need to add the paddingLeft and paddingRight in order for things to behave correctly.
5392            if (extraPadRight) {
5393              extraPadRight += _getStyle(element, "paddingLeft") + (_addPaddingBR ? _getStyle(element, "paddingRight") : 0);
5394            }
5395          }
5396          style.display = "inline-block";
5397          style.position = "relative";
5398          style.overflow = "visible";
5399          style.verticalAlign = "top";
5400          style.width = "100%";
5401          style.paddingRight = extraPadRight + "px";
5402          //some browsers neglect to factor in the bottom padding when calculating the scrollHeight, so we need to add that padding to the content when that happens. Allow a 2px margin for error
5403          if (_addPaddingBR) {
5404            style.paddingBottom = _getStyle(element, "paddingBottom", true);
5405          }
5406          if (_isOldIE) {
5407            style.zoom = "1";
5408          }
5409          elementWidth = element.clientWidth;
5410          elementHeight = element.clientHeight;
5411          scrollWidth = element.scrollWidth;
5412          scrollHeight = element.scrollHeight;
5413          maxLeft = element.scrollWidth - elementWidth;
5414          maxTop = element.scrollHeight - elementHeight;
5415          contentHeight = content.offsetHeight;
5416          style.display = "block";
5417          if (x || y) {
5418            this.left(x);
5419            this.top(y);
5420          }
5421        };
5422        this.content = content;
5423        this.element = element;
5424        this._suspendTransforms = false;
5425        this.enable();
5426      },
5427      _Draggable = function Draggable(target, vars) {
5428        EventDispatcher.call(this, target);
5429        target = _unwrapElement(target); //in case the target is a selector object or selector text
5430        if (!ThrowPropsPlugin) {
5431          ThrowPropsPlugin = _globals.com.greensock.plugins.ThrowPropsPlugin;
5432        }
5433        this.vars = vars = _copy(vars || {});
5434        this.target = target;
5435        this.x = this.y = this.rotation = 0;
5436        this.dragResistance = parseFloat(vars.dragResistance) || 0;
5437        this.edgeResistance = isNaN(vars.edgeResistance) ? 1 : parseFloat(vars.edgeResistance) || 0;
5438        this.lockAxis = vars.lockAxis;
5439        this.autoScroll = vars.autoScroll || 0;
5440        this.lockedAxis = null;
5441        this.allowEventDefault = !!vars.allowEventDefault;
5442        var type = (vars.type || (_isOldIE ? "top,left" : "x,y")).toLowerCase(),
5443          xyMode = type.indexOf("x") !== -1 || type.indexOf("y") !== -1,
5444          rotationMode = type.indexOf("rotation") !== -1,
5445          xProp = rotationMode ? "rotation" : xyMode ? "x" : "left",
5446          yProp = xyMode ? "y" : "top",
5447          allowX = type.indexOf("x") !== -1 || type.indexOf("left") !== -1 || type === "scroll",
5448          allowY = type.indexOf("y") !== -1 || type.indexOf("top") !== -1 || type === "scroll",
5449          minimumMovement = vars.minimumMovement || 2,
5450          self = this,
5451          triggers = _slice(vars.trigger || vars.handle || target),
5452          killProps = {},
5453          dragEndTime = 0,
5454          checkAutoScrollBounds = false,
5455          autoScrollMarginTop = vars.autoScrollMarginTop || 40,
5456          autoScrollMarginRight = vars.autoScrollMarginRight || 40,
5457          autoScrollMarginBottom = vars.autoScrollMarginBottom || 40,
5458          autoScrollMarginLeft = vars.autoScrollMarginLeft || 40,
5459          isClickable = vars.clickableTest || _isClickable2,
5460          clickTime = 0,
5461          enabled,
5462          scrollProxy,
5463          startPointerX,
5464          startPointerY,
5465          startElementX,
5466          startElementY,
5467          hasBounds,
5468          hasDragCallback,
5469          maxX,
5470          minX,
5471          maxY,
5472          minY,
5473          tempVars,
5474          cssVars,
5475          touch,
5476          touchID,
5477          rotationOrigin,
5478          dirty,
5479          old,
5480          snapX,
5481          snapY,
5482          snapXY,
5483          isClicking,
5484          touchEventTarget,
5485          matrix,
5486          interrupted,
5487          startScrollTop,
5488          startScrollLeft,
5489          applyObj,
5490          allowNativeTouchScrolling,
5491          touchDragAxis,
5492          isDispatching,
5493          clickDispatch,
5494          trustedClickDispatch,
5495          onContextMenu = function onContextMenu(e) {
5496            //used to prevent long-touch from triggering a context menu.
5497            if (self.isPressed && e.which < 2) {
vendor: 4,204 bytes, lines 5498-5571
5498              self.endDrag();
5499            } else {
5500              e.preventDefault();
5501              e.stopPropagation();
5502              return false;
5503            }
5504          },
5505          //this method gets called on every tick of TweenLite.ticker which allows us to synchronize the renders to the core engine (which is typically synchronized with the display refresh via requestAnimationFrame). This is an optimization - it's better than applying the values inside the "mousemove" or "touchmove" event handler which may get called many times inbetween refreshes.
5506          render = function render(suppressEvents) {
5507            if (self.autoScroll && self.isDragging && (checkAutoScrollBounds || dirty)) {
5508              var e = target,
5509                autoScrollFactor = self.autoScroll * 15,
5510                //multiplying by 15 just gives us a better "feel" speed-wise.
5511                parent,
5512                isRoot,
5513                rect,
5514                pointerX,
5515                pointerY,
5516                changeX,
5517                changeY,
5518                gap;
5519              checkAutoScrollBounds = false;
5520              _windowProxy.scrollTop = window.pageYOffset != null ? window.pageYOffset : _docElement.scrollTop != null ? _docElement.scrollTop : _doc.body.scrollTop;
5521              _windowProxy.scrollLeft = window.pageXOffset != null ? window.pageXOffset : _docElement.scrollLeft != null ? _docElement.scrollLeft : _doc.body.scrollLeft;
5522              pointerX = self.pointerX - _windowProxy.scrollLeft;
5523              pointerY = self.pointerY - _windowProxy.scrollTop;
5524              while (e && !isRoot) {
5525                //walk up the chain and sense wherever the pointer is within 40px of an edge that's scrollable.
5526                isRoot = _isRoot(e.parentNode);
5527                parent = isRoot ? _windowProxy : e.parentNode;
5528                rect = isRoot ? {
5529                  bottom: Math.max(_docElement.clientHeight, window.innerHeight || 0),
5530                  right: Math.max(_docElement.clientWidth, window.innerWidth || 0),
5531                  left: 0,
5532                  top: 0
5533                } : parent.getBoundingClientRect();
5534                changeX = changeY = 0;
5535                if (allowY) {
5536                  gap = parent._gsMaxScrollY - parent.scrollTop;
5537                  if (gap < 0) {
5538                    changeY = gap;
5539                  } else if (pointerY > rect.bottom - autoScrollMarginBottom && gap) {
5540                    checkAutoScrollBounds = true;
5541                    changeY = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.bottom - pointerY) / autoScrollMarginBottom) | 0);
5542                  } else if (pointerY < rect.top + autoScrollMarginTop && parent.scrollTop) {
5543                    checkAutoScrollBounds = true;
5544                    changeY = -Math.min(parent.scrollTop, autoScrollFactor * (1 - Math.max(0, pointerY - rect.top) / autoScrollMarginTop) | 0);
5545                  }
5546                  if (changeY) {
5547                    parent.scrollTop += changeY;
5548                  }
5549                }
5550                if (allowX) {
5551                  gap = parent._gsMaxScrollX - parent.scrollLeft;
5552                  if (gap < 0) {
5553                    changeX = gap;
5554                  } else if (pointerX > rect.right - autoScrollMarginRight && gap) {
5555                    checkAutoScrollBounds = true;
5556                    changeX = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.right - pointerX) / autoScrollMarginRight) | 0);
5557                  } else if (pointerX < rect.left + autoScrollMarginLeft && parent.scrollLeft) {
5558                    checkAutoScrollBounds = true;
5559                    changeX = -Math.min(parent.scrollLeft, autoScrollFactor * (1 - Math.max(0, pointerX - rect.left) / autoScrollMarginLeft) | 0);
5560                  }
5561                  if (changeX) {
5562                    parent.scrollLeft += changeX;
5563                  }
5564                }
5565                if (isRoot && (changeX || changeY)) {
5566                  window.scrollTo(parent.scrollLeft, parent.scrollTop);
5567                  setPointerPosition(self.pointerX + changeX, self.pointerY + changeY);
5568                }
5569                e = parent;
5570              }
5571            }
5572            if (dirty) {
5573              var x = self.x,
5574                y = self.y,
5575                min = 0.000001;
5576              if (x < min && x > -min) {
5577                //browsers don't handle super small decimals well.
5578                x = 0;
5579              }
5580              if (y < min && y > -min) {
5581                y = 0;
5582              }
5583              if (rotationMode) {
5584                self.deltaX = x - applyObj.data.rotation;
5585                applyObj.data.rotation = self.rotation = x;
5586                applyObj.setRatio(1); //note: instead of doing TweenLite.set(), as a performance optimization we skip right to the method that renders the transforms inside CSSPlugin. For old versions of IE, though, we do a normal TweenLite.set() to leverage its ability to re-reroute to an IE-specific 2D renderer.
5587              } else {
5588                if (scrollProxy) {
5589                  if (allowY) {
5590                    self.deltaY = y - scrollProxy.top();
5591                    scrollProxy.top(y);
5592                  }
5593                  if (allowX) {
5594                    self.deltaX = x - scrollProxy.left();
5595                    scrollProxy.left(x);
5596                  }
5597                } else if (xyMode) {
5598                  if (allowY) {
5599                    self.deltaY = y - applyObj.data.y;
5600                    applyObj.data.y = y;
5601                  }
5602                  if (allowX) {
5603                    self.deltaX = x - applyObj.data.x;
5604                    applyObj.data.x = x;
5605                  }
5606                  applyObj.setRatio(1); //note: instead of doing TweenLite.set(), as a performance optimization we skip right to the method that renders the transforms inside CSSPlugin. For old versions of IE, though, we do a normal TweenLite.set() to leverage its ability to re-reroute to an IE-specific 2D renderer.
5607                } else {
5608                  if (allowY) {
5609                    self.deltaY = y - parseFloat(target.style.top || 0);
5610                    target.style.top = y + "px";
5611                  }
5612                  if (allowX) {
5613                    self.deltaY = x - parseFloat(target.style.left || 0);
5614                    target.style.left = x + "px";
5615                  }
5616                }
5617              }
5618              if (hasDragCallback && !suppressEvents && !isDispatching) {
5619                isDispatching = true; //in case onDrag has an update() call (avoid endless loop)
5620                _dispatchEvent(self, "drag", "onDrag");
5621                isDispatching = false;
5622              }
5623            }
5624            dirty = false;
5625          },
5626          //copies the x/y from the element (whether that be transforms, top/left, or ScrollProxy's top/left) to the Draggable's x and y (and rotation if necessary) properties so that they reflect reality and it also (optionally) applies any snapping necessary. This is used by the ThrowPropsPlugin tween in an onUpdate to ensure things are synced and snapped.
5627          syncXY = function syncXY(skipOnUpdate, skipSnap) {
5628            var x = self.x,
5629              y = self.y,
5630              snappedValue;
5631            if (!target._gsTransform && (xyMode || rotationMode)) {
5632              //just in case the _gsTransform got wiped, like if the user called clearProps on the transform or something (very rare), doing an x tween forces a re-parsing of the transforms and population of the _gsTransform.
5633              TweenLite.set(target, {
5634                x: "+=0",
5635                overwrite: false,
5636                data: "_draggable"
5637              });
5638            }
5639            if (xyMode) {
5640              self.y = target._gsTransform.y;
5641              self.x = target._gsTransform.x;
5642            } else if (rotationMode) {
5643              self.x = self.rotation = target._gsTransform.rotation;
5644            } else if (scrollProxy) {
5645              self.y = scrollProxy.top();
5646              self.x = scrollProxy.left();
5647            } else {
5648              self.y = parseInt(target.style.top, 10) || 0;
5649              self.x = parseInt(target.style.left, 10) || 0;
5650            }
5651            if ((snapX || snapY || snapXY) && !skipSnap && (self.isDragging || self.isThrowing)) {
5652              if (snapXY) {
5653                _temp1.x = self.x;
5654                _temp1.y = self.y;
5655                snappedValue = snapXY(_temp1);
5656                if (snappedValue.x !== self.x) {
5657                  self.x = snappedValue.x;
5658                  dirty = true;
5659                }
5660                if (snappedValue.y !== self.y) {
5661                  self.y = snappedValue.y;
5662                  dirty = true;
5663                }
5664              }
5665              if (snapX) {
5666                snappedValue = snapX(self.x);
5667                if (snappedValue !== self.x) {
5668                  self.x = snappedValue;
5669                  if (rotationMode) {
5670                    self.rotation = snappedValue;
5671                  }
5672                  dirty = true;
5673                }
5674              }
5675              if (snapY) {
5676                snappedValue = snapY(self.y);
5677                if (snappedValue !== self.y) {
5678                  self.y = snappedValue;
5679                }
5680                dirty = true;
5681              }
5682            }
5683            if (dirty) {
5684              render(true);
5685            }
5686            if (!skipOnUpdate) {
5687              self.deltaX = self.x - x;
5688              self.deltaY = self.y - y;
5689              _dispatchEvent(self, "throwupdate", "onThrowUpdate");
5690            }
5691          },
5692          calculateBounds = function calculateBounds() {
5693            var bounds, targetBounds, snap, snapIsRaw;
5694            hasBounds = false;
5695            if (scrollProxy) {
5696              scrollProxy.calibrate();
5697              self.minX = minX = -scrollProxy.maxScrollLeft();
5698              self.minY = minY = -scrollProxy.maxScrollTop();
5699              self.maxX = maxX = self.maxY = maxY = 0;
5700              hasBounds = true;
5701            } else if (!!vars.bounds) {
5702              bounds = _getBounds(vars.bounds, target.parentNode); //could be a selector/jQuery object or a DOM element or a generic object like {top:0, left:100, width:1000, height:800} or {minX:100, maxX:1100, minY:0, maxY:800}
5703              if (rotationMode) {
5704                self.minX = minX = bounds.left;
5705                self.maxX = maxX = bounds.left + bounds.width;
5706                self.minY = minY = self.maxY = maxY = 0;
5707              } else if (vars.bounds.maxX !== undefined || vars.bounds.maxY !== undefined) {
5708                bounds = vars.bounds;
5709                self.minX = minX = bounds.minX;
5710                self.minY = minY = bounds.minY;
5711                self.maxX = maxX = bounds.maxX;
5712                self.maxY = maxY = bounds.maxY;
5713              } else {
5714                targetBounds = _getBounds(target, target.parentNode);
5715                self.minX = minX = _getStyle(target, xProp) + bounds.left - targetBounds.left;
5716                self.minY = minY = _getStyle(target, yProp) + bounds.top - targetBounds.top;
5717                self.maxX = maxX = minX + (bounds.width - targetBounds.width);
5718                self.maxY = maxY = minY + (bounds.height - targetBounds.height);
5719              }
5720              if (minX > maxX) {
5721                self.minX = maxX;
5722                self.maxX = maxX = minX;
5723                minX = self.minX;
5724              }
5725              if (minY > maxY) {
5726                self.minY = maxY;
5727                self.maxY = maxY = minY;
5728                minY = self.minY;
5729              }
5730              if (rotationMode) {
5731                self.minRotation = minX;
5732                self.maxRotation = maxX;
5733              }
5734              hasBounds = true;
5735            }
5736            if (vars.liveSnap) {
5737              snap = vars.liveSnap === true ? vars.snap || {} : vars.liveSnap;
5738              snapIsRaw = snap instanceof Array || typeof snap === "function";
5739              if (rotationMode) {
5740                snapX = buildSnapFunc(snapIsRaw ? snap : snap.rotation, minX, maxX, 1);
5741                snapY = null;
5742              } else {
5743                if (snap.points) {
5744                  snapXY = buildPointSnapFunc(snapIsRaw ? snap : snap.points, minX, maxX, minY, maxY, snap.radius, scrollProxy ? -1 : 1);
5745                } else {
5746                  if (allowX) {
5747                    snapX = buildSnapFunc(snapIsRaw ? snap : snap.x || snap.left || snap.scrollLeft, minX, maxX, scrollProxy ? -1 : 1);
5748                  }
5749                  if (allowY) {
5750                    snapY = buildSnapFunc(snapIsRaw ? snap : snap.y || snap.top || snap.scrollTop, minY, maxY, scrollProxy ? -1 : 1);
5751                  }
5752                }
5753              }
5754            }
5755          },
5756          onThrowComplete = function onThrowComplete() {
5757            self.isThrowing = false;
5758            _dispatchEvent(self, "throwcomplete", "onThrowComplete");
5759          },
5760          onThrowOverwrite = function onThrowOverwrite() {
5761            self.isThrowing = false;
5762          },
5763          animate = function animate(throwProps, forceZeroVelocity) {
5764            var snap, snapIsRaw, tween, overshootTolerance;
5765            if (throwProps && ThrowPropsPlugin) {
5766              if (throwProps === true) {
5767                snap = vars.snap || vars.liveSnap || {};
5768                snapIsRaw = snap instanceof Array || typeof snap === "function";
5769                throwProps = {
5770                  resistance: (vars.throwResistance || vars.resistance || 1000) / (rotationMode ? 10 : 1)
5771                };
5772                if (rotationMode) {
5773                  throwProps.rotation = _parseThrowProps(self, snapIsRaw ? snap : snap.rotation, maxX, minX, 1, forceZeroVelocity);
5774                } else {
5775                  if (allowX) {
5776                    throwProps[xProp] = _parseThrowProps(self, snapIsRaw ? snap : snap.points || snap.x || snap.left || snap.scrollLeft, maxX, minX, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "x");
5777                  }
5778                  if (allowY) {
5779                    throwProps[yProp] = _parseThrowProps(self, snapIsRaw ? snap : snap.points || snap.y || snap.top || snap.scrollTop, maxY, minY, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "y");
5780                  }
5781                  if (snap.points || snap instanceof Array && _typeof(snap[0]) === "object") {
5782                    throwProps.linkedProps = xProp + "," + yProp;
5783                    throwProps.radius = snap.radius; //note: we also disable liveSnapping while throwing if there's a "radius" defined, otherwise it looks weird to have the item thrown past a snapping point but live-snapping mid-tween. We do this by altering the onUpdateParams so that "skipSnap" parameter is true for syncXY.
5784                  }
5785                }
5786              }
5787              self.isThrowing = true;
5788              overshootTolerance = !isNaN(vars.overshootTolerance) ? vars.overshootTolerance : vars.edgeResistance === 1 ? 0 : 1 - self.edgeResistance + 0.2;
5789              self.tween = tween = ThrowPropsPlugin.to(scrollProxy || target, {
5790                throwProps: throwProps,
5791                data: "_draggable",
5792                ease: vars.ease || _globals.Power3.easeOut,
5793                onComplete: onThrowComplete,
5794                onOverwrite: onThrowOverwrite,
5795                onUpdate: vars.fastMode ? _dispatchEvent : syncXY,
5796                onUpdateParams: vars.fastMode ? [self, "onthrowupdate", "onThrowUpdate"] : snap && snap.radius ? [false, true] : _emptyArray
5797              }, isNaN(vars.maxDuration) ? 2 : vars.maxDuration, !isNaN(vars.minDuration) ? vars.minDuration : overshootTolerance === 0 || _typeof(throwProps) === "object" && throwProps.resistance > 1000 ? 0 : 0.5, overshootTolerance);
5798              if (!vars.fastMode) {
5799                //to populate the end values, we just scrub the tween to the end, record the values, and then jump back to the beginning.
5800                if (scrollProxy) {
5801                  scrollProxy._suspendTransforms = true; //Microsoft browsers have a bug that causes them to briefly render the position incorrectly (it flashes to the end state when we seek() the tween even though we jump right back to the current position, and this only seems to happen when we're affecting both top and left), so we set a _suspendTransforms flag to prevent it from actually applying the values in the ScrollProxy.
5802                }
5803                tween.render(tween.duration(), true, true);
5804                syncXY(true, true);
5805                self.endX = self.x;
5806                self.endY = self.y;
5807                if (rotationMode) {
5808                  self.endRotation = self.x;
5809                }
5810                tween.play(0);
5811                syncXY(true, true);
5812                if (scrollProxy) {
5813                  scrollProxy._suspendTransforms = false;
5814                }
5815              }
5816            } else if (hasBounds) {
5817              self.applyBounds();
5818            }
5819          },
5820          updateMatrix = function updateMatrix(shiftStart) {
5821            var start = matrix || [1, 0, 0, 1, 0, 0],
5822              a,
5823              b,
5824              c,
5825              d,
5826              tx,
5827              ty,
5828              determinant,
5829              pointerX,
5830              pointerY;
5831            matrix = _getConcatenatedMatrix(target.parentNode, true);
5832            if (shiftStart && self.isPressed && start.join(",") !== matrix.join(",")) {
5833              //if the matrix changes WHILE the element is pressed, we must adjust the startPointerX and startPointerY accordingly, so we invert the original matrix and figure out where the pointerX and pointerY were in the global space, then apply the new matrix to get the updated coordinates.
5834              a = start[0];
5835              b = start[1];
5836              c = start[2];
5837              d = start[3];
5838              tx = start[4];
5839              ty = start[5];
5840              determinant = a * d - b * c;
5841              pointerX = startPointerX * (d / determinant) + startPointerY * (-c / determinant) + (c * ty - d * tx) / determinant;
5842              pointerY = startPointerX * (-b / determinant) + startPointerY * (a / determinant) + -(a * ty - b * tx) / determinant;
5843              startPointerY = pointerX * matrix[1] + pointerY * matrix[3] + matrix[5];
5844              startPointerX = pointerX * matrix[0] + pointerY * matrix[2] + matrix[4];
5845            }
5846            if (!matrix[1] && !matrix[2] && matrix[0] == 1 && matrix[3] == 1 && matrix[4] == 0 && matrix[5] == 0) {
5847              //if there are no transforms, we can optimize performance by not factoring in the matrix
5848              matrix = null;
5849            }
5850          },
5851          recordStartPositions = function recordStartPositions() {
5852            var edgeTolerance = 1 - self.edgeResistance;
5853            updateMatrix(false);
5854            if (matrix) {
5855              startPointerX = self.pointerX * matrix[0] + self.pointerY * matrix[2] + matrix[4]; //translate to local coordinate system
5856              startPointerY = self.pointerX * matrix[1] + self.pointerY * matrix[3] + matrix[5];
5857            }
5858            if (dirty) {
5859              setPointerPosition(self.pointerX, self.pointerY);
5860              render(true);
5861            }
5862            if (scrollProxy) {
5863              calculateBounds();
5864              startElementY = scrollProxy.top();
5865              startElementX = scrollProxy.left();
5866            } else {
5867              //if the element is in the process of tweening, don't force snapping to occur because it could make it jump. Imagine the user throwing, then before it's done, clicking on the element in its inbetween state.
5868              if (isTweening()) {
5869                syncXY(true, true);
5870                calculateBounds();
5871              } else {
5872                self.applyBounds();
5873              }
5874              if (rotationMode) {
5875                rotationOrigin = self.rotationOrigin = _localToGlobal(target, {
5876                  x: 0,
5877                  y: 0
5878                });
5879                syncXY(true, true);
5880                startElementX = self.x; //starting rotation (x always refers to rotation in type:"rotation", measured in degrees)
5881                startElementY = self.y = Math.atan2(rotationOrigin.y - self.pointerY, self.pointerX - rotationOrigin.x) * _RAD2DEG;
5882              } else {
5883                startScrollTop = target.parentNode ? target.parentNode.scrollTop || 0 : 0;
5884                startScrollLeft = target.parentNode ? target.parentNode.scrollLeft || 0 : 0;
5885                startElementY = _getStyle(target, yProp); //record the starting top and left values so that we can just add the mouse's movement to them later.
5886                startElementX = _getStyle(target, xProp);
5887              }
5888            }
5889            if (hasBounds && edgeTolerance) {
5890              if (startElementX > maxX) {
5891                startElementX = maxX + (startElementX - maxX) / edgeTolerance;
5892              } else if (startElementX < minX) {
5893                startElementX = minX - (minX - startElementX) / edgeTolerance;
5894              }
5895              if (!rotationMode) {
5896                if (startElementY > maxY) {
5897                  startElementY = maxY + (startElementY - maxY) / edgeTolerance;
5898                } else if (startElementY < minY) {
5899                  startElementY = minY - (minY - startElementY) / edgeTolerance;
5900                }
5901              }
5902            }
5903            self.startX = startElementX;
5904            self.startY = startElementY;
5905          },
5906          isTweening = function isTweening() {
5907            return self.tween && self.tween.isActive();
5908          },
5909          removePlaceholder = function removePlaceholder() {
5910            if (_placeholderDiv.parentNode && !isTweening() && !self.isDragging) {
5911              //_placeholderDiv just props open auto-scrolling containers so they don't collapse as the user drags left/up. We remove it after dragging (and throwing, if necessary) finishes.
5912              _placeholderDiv.parentNode.removeChild(_placeholderDiv);
5913            }
5914          },
5915          buildSnapFunc = function buildSnapFunc(snap, min, max, factor) {
5916            if (typeof snap === "function") {
5917              return function (n) {
5918                var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance; //if we're tweening, disable the edgeTolerance because it's already factored 
5918into the tweening values (we don't want to apply it multiple times)
5919                return snap.call(self, n > max ? max + (n - max) * edgeTolerance : n < min ? min + (n - min) * edgeTolerance : n) * factor;
5920              };
5921            }
5922            if (snap instanceof Array) {
5923              return function (n) {
5924                var i = snap.length,
5925                  closest = 0,
5926                  absDif = _max,
5927                  val,
5928                  dif;
5929                while (--i > -1) {
5930                  val = snap[i];
5931                  dif = val - n;
5932                  if (dif < 0) {
5933                    dif = -dif;
5934                  }
5935                  if (dif < absDif && val >= min && val <= max) {
5936                    closest = i;
5937                    absDif = dif;
5938                  }
5939                }
5940                return snap[closest];
5941              };
5942            }
5943            return isNaN(snap) ? function (n) {
5944              return n;
5945            } : function () {
5946              return snap * factor;
5947            };
5948          },
5949          buildPointSnapFunc = function buildPointSnapFunc(snap, minX, maxX, minY, maxY, radius, factor) {
5950            radius = radius && radius < _max ? radius * radius : _max; //so we don't have to Math.sqrt() in the functions. Performance optimization.
5951            if (typeof snap === "function") {
5952              return function (point) {
5953                var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance,
5954                  x = point.x,
5955                  y = point.y,
5956                  result,
5957                  dx,
5958                  dy; //if we're tweening, disable the edgeTolerance because it's already factored into the tweening values (we don't want to apply it multiple times)
5959                point.x = x = x > maxX ? maxX + (x - maxX) * edgeTolerance : x < minX ? minX + (x - minX) * edgeTolerance : x;
5960                point.y = y = y > maxY ? maxY + (y - maxY) * edgeTolerance : y < minY ? minY + (y - minY) * edgeTolerance : y;
5961                result = snap.call(self, point);
5962                if (result !== point) {
5963                  point.x = result.x;
5964                  point.y = result.y;
5965                }
5966                if (factor !== 1) {
5967                  point.x *= factor;
5968                  point.y *= factor;
5969                }
5970                if (radius < _max) {
5971                  dx = point.x - x;
5972                  dy = point.y - y;
5973                  if (dx * dx + dy * dy > radius) {
5974                    point.x = x;
5975                    point.y = y;
5976                  }
5977                }
5978                return point;
5979              };
5980            }
5981            if (snap instanceof Array) {
5982              return function (p) {
5983                var i = snap.length,
5984                  closest = 0,
5985                  minDist = _max,
5986                  x,
5987                  y,
5988                  point,
5989                  dist;
5990                while (--i > -1) {
5991                  point = snap[i];
5992                  x = point.x - p.x;
5993                  y = point.y - p.y;
5994                  dist = x * x + y * y;
5995                  if (dist < minDist) {
5996                    closest = i;
5997                    minDist = dist;
5998                  }
5999                }
6000                return minDist <= radius ? snap[closest] : p;
6001              };
6002            }
6003            return function (n) {
6004              return n;
6005            };
6006          },
6007          //called when the mouse is pressed (or touch starts)
6008          onPress = function onPress(e, force) {
6009            var i;
6010            if (!enabled || self.isPressed || !e || (e.type === "mousedown" || e.type === "pointerdown") && !force && _getTime() - clickTime < 30 && _touchEventLookup[self.pointerEvent.type]) {
6011              //when we DON'T preventDefault() in order to accommodate touch-scrolling and the user just taps, many browsers also fire a mousedown/mouseup sequence AFTER the touchstart/touchend sequence, thus it'd result in two quick "click" events being dispatched. This line senses that condition and halts it on the subsequent mousedown.
6012              return;
6013            }
6014            interrupted = isTweening();
6015            self.pointerEvent = e;
6016            if (_touchEventLookup[e.type]) {
6017              //note: on iOS, BOTH touchmove and mousemove are dispatched, but the mousemove has pageY and pageX of 0 which w
6017ould mess up the calculations and needlessly hurt performance.
6018              touchEventTarget = e.type.indexOf("touch") !== -1 ? e.currentTarget || e.target : _doc; //pointer-based touches (for Microsoft browsers) don't remain locked to the original target like other browsers, so we must use the document instead. The event type would be "MSPointerDown" or "pointerdown".
6019              _addListener(touchEventTarget, "touchend", _onRelease);
6020              _addListener(touchEventTarget, "touchmove", onMove);
6021              _addListener(touchEventTarget, "touchcancel", _onRelease);
6022              _addListener(_doc, "touchstart", _onMultiTouchDocument);
6023            } else {
6024              touchEventTarget = null;
6025              _addListener(_doc, "mousemove", onMove); //attach these to the document instead of the box itself so that if the user's mouse moves too quickly (and off of the box), things still work.
6026            }
6027            touchDragAxis = null;
6028            _addListener(_doc, "mouseup", _onRelease);
6029            if (e && e.target) {
6030              _addListener(e.target, "mouseup", _onRelease); //we also have to listen directly on the element because some browsers don't bubble up the event to the _doc on elements with contentEditable="true"
6031            }
6032            isClicking = isClickable.call(self, e.target) && !vars.dragClickables && !force;
6033            if (isClicking) {
6034              _addListener(e.target, "change", _onRelease); //in some browsers, when you mousedown on a <select> element, no mouseup gets dispatched! So we listen for a "change" event instead.
6035              _dispatchEvent(self, "press", "onPress");
6036              _setSelectable(triggers, true); //accommodates things like inputs and elements with contentEditable="true" (otherwise user couldn't drag to select text)
6037              return;
6038            }
6039            allowNativeTouchScrolling = !touchEventTarget || allowX === allowY || self.vars.allowNativeTouchScrolling === false ? false : allowX ? "y" : "x";
6040            if (_isOldIE) {
6041              e = _populateIEEvent(e, true);
6042            } else if (!allowNativeTouchScrolling && !self.allowEventDefault) {
6043              e.preventDefault();
6044              if (e.preventManipulation) {
6045                e.preventManipulation(); //for some Microsoft browsers
6046              }
6047            }
6048            if (e.changedTouches) {
6049              //touch events store the data slightly differently
6050              e = touch = e.changedTouches[0];
6051              touchID = e.identifier;
6052            } else if (e.pointerId) {
6053              touchID = e.pointerId; //for some Microsoft browsers
6054            } else {
6055              touch = touchID = null;
6056            }
6057            _dragCount++;
6058            _addToRenderQueue(render); //causes the Draggable to render on each "tick" of TweenLite.ticker (performance optimization - updating values in a mousemove can cause them to happen too frequently, like multiple times between frame redraws which is wasteful, and it also prevents values from updating properly in IE8)
6059            startPointerY = self.pointerY = e.pageY; //record the starting x and y so that we can calculate the movement from the original in _onMouseMove
6060            startPointerX = self.pointerX = e.pageX;
6061            if (allowNativeTouchScrolling || self.autoScroll) {
6062              _recordMaxScrolls2(target.parentNode);
6063            }
6064            if (target.parentNode && self.autoScroll && !scrollProxy && !rotationMode && target.parentNode._gsMaxScrollX && !_placeholderDiv.parentNode && !target.getBBox) {
6065              //add a placeholder div to prevent the parent container from collapsing when the user drags the element left.
6066              _placeholderDiv.style.width = target.parentNode.scrollWidth + "px";
6067              target.parentNode.appendChild(_placeholderDiv);
6068            }
6069            recordStartPositions();
6070            if (self.tween) {
6071              self.tween.kill();
6072            }
6073            self.isThrowing = false;
6074            TweenLite.killTweensOf(scrollProxy || target, true, killProps); //in case the user tries to drag it before the last tween is done.
6075            if (scrollProxy) {
6076              TweenLite.killTweensOf(target, true, {
6077                scrollTo: 1
6078              }); //just in case the original target's scroll position is being tweened somewhere else.
6079            }
6080            self.tween = self.lockedAxis = null;
6081            if (vars.zIndexBoost || !rotationMode && !scrollProxy && vars.zIndexBoost !== false) {
6082              target.style.zIndex = _Draggable.zIndex++;
6083            }
6084            self.isPressed = true;
6085            hasDragCallback = !!(vars.onDrag || self._listeners.drag);
6086            if (!rotationMode) {
6087              i = triggers.length;
6088              while (--i > -1) {
6089                _setStyle(triggers[i], "cursor", vars.cursor || "move");
6090              }
6091            }
6092            _dispatchEvent(self, "press", "onPress");
6093          },
6094          //called every time the mouse/touch moves
6095          onMove = function onMove(e) {
6096            var originalEvent = e,
6097              touches,
6098              pointerX,
6099              pointerY,
6100              i,
6101              dx,
6102              dy;
6103            if (!enabled || _isMultiTouching || !self.isPressed || !e) {
6104              return;
6105            }
6106            self.pointerEvent = e;
6107            touches = e.changedTouches;
6108            if (touches) {
6109              //touch events store the data slightly differently
6110              e = touches[0];
6111              if (e !== touch && e.identifier !== touchID) {
6112                //Usually changedTouches[0] will be what we're looking for, but in case it's not, look through the rest of the array...(and Android browsers don't reuse the event like iOS)
6113                i = touches.length;
6114                while (--i > -1 && (e = touches[i]).identifier !== touchID) {}
6115                if (i < 0) {
6116                  return;
6117                }
6118              }
6119            } else if (e.pointerId && touchID && e.pointerId !== touchID) {
6120              //for some Microsoft browsers, we must attach the listener to the doc rather than the trigger so that when the finger moves outside the bounds of the trigger, things still work. So if the event we're receiving has a pointerId that doesn't match the touchID, ignore it (for multi-touch)
6121              return;
6122            }
6123            if (_isOldIE) {
6124              e = _populateIEEvent(e, true);
6125            } else {
6126              if (touchEventTarget && allowNativeTouchScrolling && !touchDragAxis) {
6127                //Android browsers force us to decide on the first "touchmove" event if we should allow the default (scrolling) behavior or preventDefault(). Otherwise, a "touchcancel" will be fired and then no "touchmove" or "touchend" will fire during the scrolling (no good).
6128                pointerX = e.pageX;
6129                pointerY = e.pageY;
6130                if (matrix) {
6131                  i = pointerX * matrix[0] + pointerY * matrix[2] + matrix[4];
6132                  pointerY = pointerX * matrix[1] + pointerY * matrix[3] + matrix[5];
6133                  pointerX = i;
6134                }
6135                dx = Math.abs(pointerX - startPointerX);
6136                dy = Math.abs(pointerY - startPointerY);
6137                if (dx !== dy && (dx > minimumMovement || dy > minimumMovement) || _isAndroid && allowNativeTouchScrolling === touchDragAxis) {
6138                  touchDragAxis = dx > dy && allowX ? "x" : "y";
6139                  if (self.vars.lockAxisOnTouchScroll !== false) {
6140                    self.lockedAxis = touchDragAxis === "x" ? "y" : "x";
6141                    if (typeof self.vars.onLockAxis === "function") {
6142                      self.vars.onLockAxis.call(self, originalEvent);
6143                    }
6144                  }
6145                  if (_isAndroid && allowNativeTouchScrolling === touchDragAxis) {
6146                    _onRelease(originalEvent);
6147                    return;
6148                  }
6149                }
6150              }
6151              if (!self.allowEventDefault && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling !== touchDragAxis) && originalEvent.cancelable !== false) {
6152                originalEvent.preventDefault();
6153                if (originalEvent.preventManipulation) {
6154                  //for some Microsoft browsers
6155                  originalEvent.preventManipulation();
6156                }
6157              }
6158            }
6159            if (self.autoScroll) {
6160              checkAutoScrollBounds = true;
6161            }
6162            setPointerPosition(e.pageX, e.pageY);
6163          },
6164          setPointerPosition = function setPointerPosition(pointerX, pointerY) {
6165            var dragTolerance = 1 - self.dragResistance,
6166              edgeTolerance = 1 - self.edgeResistance,
6167              xChange,
6168              yChange,
6169              x,
6170              y,
6171              dif,
6172              temp;
6173            self.pointerX = pointerX;
6174            self.pointerY = pointerY;
6175            if (rotationMode) {
6176              y = Math.atan2(rotationOrigin.y - pointerY, pointerX - rotationOrigin.x) * _RAD2DEG;
6177              dif = self.y - y;
6178              if (dif > 180) {
6179                startElementY -= 360;
6180                self.y = y;
6181              } else if (dif < -180) {
6182                startElementY += 360;
6183                self.y = y;
6184              }
6185              if (self.x !== startElementX || Math.abs(startElementY - y) > minimumMovement) {
6186                self.y = y;
6187                x = startElementX + (startElementY - y) * dragTolerance;
6188              } else {
6189                x = startElementX;
6190              }
6191            } else {
6192              if (matrix) {
6193                temp = pointerX * matrix[0] + pointerY * matrix[2] + matrix[4];
6194                pointerY = pointerX * matrix[1] + pointerY * matrix[3] + matrix[5];
6195                pointerX = temp;
6196              }
6197              yChange = pointerY - startPointerY;
6198              xChange = pointerX - startPointerX;
6199              if (yChange < minimumMovement && yChange > -minimumMovement) {
6200                yChange = 0;
6201              }
6202              if (xChange < minimumMovement && xChange > -minimumMovement) {
6203                xChange = 0;
6204              }
6205              if ((self.lockAxis || self.lockedAxis) && (xChange || yChange)) {
6206                temp = self.lockedAxis;
6207                if (!temp) {
6208                  self.lockedAxis = temp = allowX && Math.abs(xChange) > Math.abs(yChange) ? "y" : allowY ? "x" : null;
6209                  if (temp && typeof self.vars.onLockAxis === "function") {
6210                    self.vars.onLockAxis.call(self, self.pointerEvent);
6211                  }
6212                }
6213                if (temp === "y") {
6214                  yChange = 0;
6215                } else if (temp === "x") {
6216                  xChange = 0;
6217                }
6218              }
6219              x = startElementX + xChange * dragTolerance;
6220              y = startElementY + yChange * dragTolerance;
6221            }
6222            if ((snapX || snapY || snapXY) && (self.x !== x || self.y !== y && !rotationMode)) {
6223              if (snapXY) {
6224                _temp1.x = x;
6225                _temp1.y = y;
6226                temp = snapXY(_temp1);
6227                x = temp.x;
6228                y = temp.y;
6229              }
6230              if (snapX) {
6231                x = snapX(x);
6232              }
6233              if (snapY) {
6234                y = snapY(y);
6235              }
6236            } else if (hasBounds) {
6237              if (x > maxX) {
6238                x = maxX + (x - maxX) * edgeTolerance;
6239              } else if (x < minX) {
6240                x = minX + (x - minX) * edgeTolerance;
6241              }
6242              if (!rotationMode) {
6243                if (y > maxY) {
6244                  y = maxY + (y - maxY) * edgeTolerance;
6245                } else if (y < minY) {
6246                  y = minY + (y - minY) * edgeTolerance;
6247                }
6248              }
6249            }
6250            if (!rotationMode && !matrix) {
6251              x = Math.round(x); //helps work around an issue with some Win Touch devices
6252              y = Math.round(y);
6253            }
6254            if (self.x !== x || self.y !== y && !rotationMode) {
6255              if (rotationMode) {
6256                self.endRotation = self.x = self.endX = x;
6257                dirty = true;
6258              } else {
6259                if (allowY) {
6260                  self.y = self.endY = y;
6261                  dirty = true; //a flag that indicates we need to render the target next time the TweenLite.ticker dispatches a "tick" event (typically on a requestAnimationFrame) - this is a performance optimization (we shouldn't render on every move because sometimes many move events can get dispatched between screen refreshes, and that'd be wasteful to render every time)
6262                }
6263                if (allowX) {
6264                  self.x = self.endX = x;
6265                  dirty = true;
6266                }
6267              }
6268              if (!self.isDragging && self.isPressed) {
6269                self.isDragging = true;
6270                _dispatchEvent(self, "dragstart", "onDragStart");
6271              }
6272            }
6273          },
6274          //called when the mouse/touch is released
6275          _onRelease = function onRelease(e, force) {
6276            if (!enabled || !self.isPressed || e && touchID != null && !force && (e.pointerId && e.pointerId !== touchID || e.changedTouches && !_hasTouchID(e.changedTouches, touchID))) {
6277              //for some Microsoft browsers, we must attach the listener to the doc rather than the trigger so that when the finger moves outside the bounds of the trigger, things still work. So if the event we're receiving has a pointerId that doesn't match the touchID, ignore it (for multi-touch)
6278              return;
6279            }
6280            self.isPressed = false;
6281            var originalEvent = e,
6282              wasDragging = self.isDragging,
6283              placeholderDelayedCall = TweenLite.delayedCall(0.001, removePlaceholder),
6284              touches,
6285              i,
6286              syntheticEvent,
6287              eventTarget,
6288              syntheticClick;
6289            if (touchEventTarget) {
6290              _removeListener(touchEventTarget, "touchend", _onRelease);
6291              _removeListener(touchEventTarget, "touchmove", onMove);
6292              _removeListener(touchEventTarget, "touchcancel", _onRelease);
6293              _removeListener(_doc, "touchstart", _onMultiTouchDocument);
6294            } else {
6295              _removeListener(_doc, "mousemove", onMove);
6296            }
6297            _removeListener(_doc, "mouseup", _onRelease);
6298            if (e && e.target) {
6299              _removeListener(e.target, "mouseup", _onRelease);
6300            }
6301            dirty = false;
6302            if (isClicking) {
6303              if (e) {
6304                _removeListener(e.target, "change", _onRelease);
6305                self.pointerEvent = originalEvent;
6306              }
6307              _setSelectable(triggers, false);
6308              _dispatchEvent(self, "release", "onRelease");
6309              _dispatchEvent(self, "click", "onClick");
6310              isClicking = false;
6311              return;
6312            }
6313            _removeFromRenderQueue(render);
6314            if (!rotationMode) {
6315              i = triggers.length;
6316              while (--i > -1) {
6317                _setStyle(triggers[i], "cursor", vars.cursor || "move");
6318              }
6319            }
6320            if (wasDragging) {
6321              dragEndTime = _lastDragTime = _getTime();
6322              self.isDragging = false;
6323            }
6324            _dragCount--;
6325            if (e) {
6326              if (_isOldIE) {
6327                e = _populateIEEvent(e, false);
6328              }
6329              touches = e.changedTouches;
6330              if (touches) {
6331                //touch events store the data slightly differently
6332                e = touches[0];
6333                if (e !== touch && e.identifier !== touchID) {
6334                  //Usually changedTouches[0] will be what we're looking for, but in case it's not, look through the rest of the array...(and Android browsers don't reuse the event like iOS)
6335                  i = touches.length;
6336                  while (--i > -1 && (e = touches[i]).identifier !== touchID) {}
6337                  if (i < 0) {
6338                    return;
6339                  }
6340                }
6341              }
6342              self.pointerEvent = originalEvent;
6343              self.pointerX = e.pageX;
6344              self.pointerY = e.pageY;
6345            }
6346            if (originalEvent && !wasDragging) {
6347              if (interrupted && (vars.snap || vars.bounds)) {
6348                //otherwise, if the user clicks on the object while it's animating to a snapped position, and then releases without moving 3 pixels, it will just stay there (it should animate/snap)
6349                animate(vars.throwProps);
6350              }
6351              _dispatchEvent(self, "release", "onRelease");
6352              if ((!_isAndroid || originalEvent.type !== "touchmove") && originalEvent.type.indexOf("cancel") === -1) {
6353                //to accommodate native scrolling on Android devices, we have to immediately call onRelease() on the first touchmove event, but that shouldn't trigger a "click".
6354                _dispatchEvent(self, "click", "onClick");
6355                if (_getTime() - clickTime < 300) {
6356                  _dispatchEvent(self, "doubleclick", "onDoubleClick");
6357                }
6358                eventTarget = originalEvent.target || originalEvent.srcElement || target; //old IE uses srcElement
6359                clickTime = _getTime();
6360                syntheticClick = function syntheticClick() {
6361                  // some browsers (like Firefox) won't trust script-generated clicks, so if the user tries to click on a video to play it, for example, it simply won't work. Since a regular "click" event will most likely be generated anyway (one that has its isTrusted flag set to true), we must slightly delay our script-generated click so that the "real"/trusted one is prioritized. Remember, when there are duplicate events in quick succession, we suppress all but the first one. Some browsers don't even trigger the "real" one at all, so our synthetic one is a safety valve that ensures that no matter what, a click event does get dispatched.
6362                  if (clickTime !== clickDispatch && self.enabled() && !self.isPressed) {
6363                    if (eventTarget.click) {
6364                      //some browsers (like mobile Safari) don't properly trigger the click event
6365                      eventTarget.click();
6366                    } else if (_doc.createEvent) {
6367                      syntheticEvent = _doc.createEvent("MouseEvents");
6368                      syntheticEvent.initMouseEvent("click", true, true, window, 1, self.pointerEvent.
6368screenX, self.pointerEvent.screenY, self.pointerX, self.pointerY, false, false, false, false, 0, null);
6369                      eventTarget.dispatchEvent(syntheticEvent);
6370                    }
6371                  }
6372                };
6373                if (!_isAndroid && !originalEvent.defaultPrevented) {
6374                  //iOS Safari requires the synthetic click to happen immediately or else it simply won't work, but Android doesn't play nice.
6375                  TweenLite.delayedCall(0.00001, syntheticClick); //in addition to the iOS bug workaround, there's a Firefox issue with clicking on things like a video to play, so we must fake a click event in a slightly delayed fashion. Previously, we listened for the "click" event with "capture" false which solved the video-click-to-play issue, but it would allow the "click" event to be dispatched twice like if you were using a jQuery.click() because that was handled in the capture phase, thus we had to switch to the capture phase to avoid the double-dispatching, but do the delayed synthetic click.
6376                }
6377              }
6378            } else {
6379              animate(vars.throwProps); //will skip if throwProps isn't defined or ThrowPropsPlugin isn't loaded.
6380              if (!_isOldIE && !self.allowEventDefault && originalEvent && (vars.dragClickables || !isClickable.call(self, originalEvent.target)) && wasDragging && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling === touchDragAxis) && originalEvent.cancelable !== false) {
6381                originalEvent.preventDefault();
6382                if (originalEvent.preventManipulation) {
6383                  originalEvent.preventManipulation(); //for some Microsoft browsers
6384                }
6385              }
6386              _dispatchEvent(self, "release", "onRelease");
6387            }
6388            if (isTweening()) {
6389              placeholderDelayedCall.duration(self.tween.duration()); //sync the timing so that the placeholder DIV gets
6390            }
6391            if (wasDragging) {
6392              _dispatchEvent(self, "dragend", "onDragEnd");
6393            }
6394            return true;
6395          },
6396          updateScroll = function updateScroll(e) {
6397            if (e && self.isDragging && !scrollProxy) {
6398              var parent = e.target || e.srcElement || target.parentNode,
6399                deltaX = parent.scrollLeft - parent._gsScrollX,
6400                deltaY = parent.scrollTop - parent._gsScrollY;
6401              if (deltaX || deltaY) {
6402                if (matrix) {
6403                  startPointerX -= deltaX * matrix[0] + deltaY * matrix[2];
6404                  startPointerY -= deltaY * matrix[3] + deltaX * matrix[1];
6405                } else {
6406                  startPointerX -= deltaX;
6407                  startPointerY -= deltaY;
6408                }
6409                parent._gsScrollX += deltaX;
6410                parent._gsScrollY += deltaY;
6411                setPointerPosition(self.pointerX, self.pointerY);
6412              }
6413            }
6414          },
6415          onClick = function onClick(e) {
6416            //this was a huge pain in the neck to align all the various browsers and their behaviors. Chrome, Firefox, Safari, Opera, Android, and Microsoft Edge all handle events differently! Some will only trigger native behavior (like checkbox toggling) from trusted events. Others don't even support isTrusted, but require 2 events to flow through before triggering native behavior. Edge treats everything as trusted but also mandates that 2 flow through to trigger the correct native behavior.
6417            var time = _getTime(),
6418              recentlyClicked = time - clickTime < 40,
6419              recentlyDragged = time - dragEndTime < 40,
6420              alreadyDispatched = recentlyClicked && clickDispatch === clickTime,
6421              isModern = !!e.preventDefault,
6422              defaultPrevented = self.pointerEvent && self.pointerEvent.defaultPrevented,
6423              alreadyDispatchedTrusted = recentlyClicked && trustedClickDispatch === clickTime,
6424              trusted = e.isTrusted || e.isTrusted == null && recentlyClicked && alreadyDispatched; //note: Safari doesn't support isTrusted, and it won't properly execute native behavior (like toggling checkboxes) on the first synthetic "click" event - we must wait for the 2nd and treat it as trusted (but stop propagation at that point). Confusing, I know. Don't you love cross-browser compatibility challenges?
6425            if (isModern && (alreadyDispatched || recentlyDragged && self.vars.suppressClickOnDrag !== false)) {
6426              e.stopImmediatePropagation();
6427            }
6428            if (recentlyClicked && !(self.pointerEvent && self.pointerEvent.defaultPrevented) && (!alreadyDispatched || trusted !== alreadyDispatchedTrusted)) {
6429              //let the first click pass through unhindered. Let the next one only if it's trusted, then no more (stop quick-succession ones)
6430              if (trusted && alreadyDispatched) {
6431                trustedClickDispatch = clickTime;
6432              }
6433              clickDispatch = clickTime;
6434              return;
6435            }
6436            if (self.isPressed || recentlyDragged || recentlyClicked) {
6437              if (!isModern) {
6438                e.returnValue = false;
6439              } else if (!trusted || !e.detail || !recentlyClicked || defaultPrevented) {
6440                e.preventDefault();
6441                if (e.preventManipulation) {
6442                  e.preventManipulation(); //for some Microsoft browsers
6443                }
6444              }
6445            }
6446          },
6447          localizePoint = function localizePoint(p) {
6448            return matrix ? {
6449              x: p.x * matrix[0] + p.y * matrix[2] + matrix[4],
6450              y: p.x * matrix[1] + p.y * matrix[3] + matrix[5]
6451            } : {
6452              x: p.x,
6453              y: p.y
6454            };
6455          };
6456        old = _Draggable.get(this.target);
6457        if (old) {
6458          old.kill(); // avoids duplicates (an element can only be controlled by one Draggable)
6459        }
6460
6461        //give the user access to start/stop dragging...
6462        this.startDrag = function (e, align) {
6463          var r1, r2, p1, p2;
6464          onPress(e || self.pointerEvent, true);
6465          //if the pointer isn't on top of the element, adjust things accordingly
6466          if (align && !self.hitTest(e || self.pointerEvent)) {
6467            r1 = _parseRect(e || self.pointerEvent);
6468            r2 = _parseRect(target);
6469            p1 = localizePoint({
6470              x: r1.left + r1.width / 2,
6471              y: r1.top + r1.height / 2
6472            });
6473            p2 = localizePoint({
6474              x: r2.left + r2.width / 2,
6475              y: r2.top + r2.height / 2
6476            });
6477            startPointerX -= p1.x - p2.x;
6478            startPointerY -= p1.y - p2.y;
6479          }
6480          if (!self.isDragging) {
6481            self.isDragging = true;
6482            _dispatchEvent(self, "dragstart", "onDragStart");
6483          }
6484        };
6485        this.drag = onMove;
6486        this.endDrag = function (e) {
6487          _onRelease(e || self.pointerEvent, true);
6488        };
6489        this.timeSinceDrag = function () {
6490          return self.isDragging ? 0 : (_getTime() - dragEndTime) / 1000;
6491        };
6492        this.timeSinceClick = function () {
6493          return (_getTime() - clickTime) / 1000;
6494        };
6495        this.hitTest = function (target, threshold) {
6496          return _Draggable.hitTest(self.target, target, threshold);
6497        };
6498        this.getDirection = function (from, diagonalThreshold) {
6499          //from can be "start" (default), "velocity", or an element
6500          var mode = from === "velocity" && ThrowPropsPlugin ? from : _typeof(from) === "object" && !rotationMode ? "element" : "start",
6501            xChange,
6502            yChange,
6503            ratio,
6504            direction,
6505            r1,
6506            r2;
6507          if (mode === "element") {
6508            r1 = _parseRect(self.target);
6509            r2 = _parseRect(from);
6510          }
6511          xChange = mode === "start" ? self.x - startElementX : mode === "velocity" ? ThrowPropsPlugin.getVelocity(this.target, xProp) : r1.left + r1.width / 2 - (r2.left + r2.width / 2);
6512          if (rotationMode) {
6513            return xChange < 0 ? "counter-clockwise" : "clockwise";
6514          } else {
6515            diagonalThreshold = diagonalThreshold || 2;
6516            yChange = mode === "start" ? self.y - startElementY : mode === "velocity" ? ThrowPropsPlugin.getVelocity(this.target, yProp) : r1.top + r1.height / 2 - (r2.top + r2.height / 2);
6517            ratio = Math.abs(xChange / yChange);
6518            direction = ratio < 1 / diagonalThreshold ? "" : xChange < 0 ? "left" : "right";
6519            if (ratio < diagonalThreshold) {
6520              if (direction !== "") {
6521                direction += "-";
6522              }
6523              direction += yChange < 0 ? "up" : "down";
6524            }
6525          }
6526          return direction;
6527        };
6528        this.applyBounds = function (newBounds) {
6529          var x, y, forceZeroVelocity, e, parent, isRoot;
6530          if (newBounds && vars.bounds !== newBounds) {
6531            vars.bounds = newBounds;
6532            return self.update(true);
6533          }
6534          syncXY(true);
6535          calculateBounds();
6536          if (hasBounds) {
6537            x = self.x;
6538            y = self.y;
6539            if (x > maxX) {
6540              x = maxX;
6541            } else if (x < minX) {
6542              x = minX;
6543            }
6544            if (y > maxY) {
6545              y = maxY;
6546            } else if (y < minY) {
6547              y = minY;
6548            }
6549            if (self.x !== x || self.y !== y) {
6550              forceZeroVelocity = true;
6551              self.x = self.endX = x;
6552              if (rotationMode) {
6553                self.endRotation = x;
6554              } else {
6555                self.y = self.endY = y;
6556              }
6557              dirty = true;
6558              render(true);
6559              if (self.autoScroll && !self.isDragging) {
6560                _recordMaxScrolls2(target.parentNode);
6561                e = target;
6562                _windowProxy.scrollTop = window.pageYOffset != null ? window.pageYOffset : _docElement.scrollTop != null ? _docElement.scrollTop : _doc.body.scrollTop;
6563                _windowProxy.scrollLeft = window.pageXOffset != null ? window.pageXOffset : _docElement.scrollLeft != null ? _docElement.scrollLeft : _doc.body.scrollLeft;
6564                while (e && !isRoot) {
6565                  //walk up the chain and sense wherever the scrollTop/scrollLeft exceeds the maximum.
6566                  isRoot = _isRoot(e.parentNode);
6567                  parent = isRoot ? _windowProxy : e.parentNode;
6568                  if (allowY && parent.scrollTop > parent._gsMaxScrollY) {
6569                    parent.scrollTop = parent._gsMaxScrollY;
6570                  }
6571                  if (allowX && parent.scrollLeft > parent._gsMaxScrollX) {
6572                    parent.scrollLeft = parent._gsMaxScrollX;
6573                  }
6574                  e = parent;
6575                }
6576              }
6577            }
6578            if (self.isThrowing && (forceZeroVelocity || self.endX > maxX || self.endX < minX || self.endY > maxY || self.endY < minY)) {
6579              animate(vars.throwProps, forceZeroVelocity);
6580            }
6581          }
6582          return self;
6583        };
6584        this.update = function (applyBounds, sticky, ignoreExternalChanges) {
6585          var x = self.x,
6586            y = self.y;
6587          updateMatrix(!sticky);
6588          if (applyBounds) {
6589            self.applyBounds();
6590          } else {
6591            if (dirty && ignoreExternalChanges) {
6592              render(true);
6593            }
6594            syncXY(true);
6595          }
6596          if (sticky) {
6597            setPointerPosition(self.pointerX, self.pointerY);
6598            if (dirty) {
6599              render(true);
6600            }
6601          }
6602          if (self.isPressed && !sticky && (allowX && Math.abs(x - self.x) > 0.01 || allowY && Math.abs(y - self.y) > 0.01 && !rotationMode)) {
6603            recordStartPositions();
6604          }
6605          if (self.autoScroll) {
6606            _recordMaxScrolls2(target.parentNode);
6607            checkAutoScrollBounds = self.isDragging;
6608            render(true);
6609          }
6610          if (self.autoScroll) {
6611            //in case reparenting occurred.
6612            _removeScrollListener2(target, updateScroll);
6613            _addScrollListener2(target, updateScroll);
6614          }
6615          return self;
6616        };
6617        this.enable = function (type) {
6618          var id, i, trigger;
6619          if (type !== "soft") {
6620            i = triggers.length;
6621            while (--i > -1) {
6622              trigger = triggers[i];
6623              _addListener(trigger, "mousedown", onPress);
6624              _addListener(trigger, "touchstart", onPress);
6625              _addListener(trigger, "click", onClick, true); //note: used to pass true for capture but it prevented click-to-play-video functionality in Firefox.
6626              if (!rotationMode) {
6627                _setStyle(trigger, "cursor", vars.cursor || "move");
6628              }
6629              _setStyle(trigger, "touchCallout", "none");
6630              _setStyle(trigger, "touchAction", allowX === allowY ? "none" : allowX ? "pan-y" : "pan-x");
6631              if (_isSVG(trigger)) {
6632                // a bug in chrome doesn't respect touch-action on SVG elements - it only works if we set it on the parent SVG.
6633                _setStyle(trigger.ownerSVGElement || trigger, "touchAction", allowX === allowY ? "none" : allowX ? "pan-y" : "pan-x");
6634              }
6635              if (!this.vars.allowContextMenu) {
6636                _addListener(trigger, "contextmenu", onContextMenu);
6637              }
6638            }
6639            _setSelectable(triggers, false);
6640          }
6641          _addScrollListener2(target, updateScroll);
6642          enabled = true;
6643          if (ThrowPropsPlugin && type !== "soft") {
6644            ThrowPropsPlugin.track(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left");
6645          }
6646          if (scrollProxy) {
6647            scrollProxy.enable();
6648          }
6649          target._gsDragID = id = "d" + _lookupCount++;
6650          _lookup[id] = this;
6651          if (scrollProxy) {
6652            scrollProxy.element._gsDragID = id;
6653          }
6654          TweenLite.set(target, {
6655            x: "+=0",
6656            overwrite: false,
6657            data: "_draggable"
6658          }); //simply ensures that there's a _gsTransform on the element.
6659          applyObj = {
6660            t: target,
6661            data: _isOldIE ? cssVars : target._gsTransform,
6662            tween: {},
6663            setRatio: _isOldIE ? function () {
6664              TweenLite.set(target, tempVars);
6665            } : CSSPlugin._internals.setTransformRatio || CSSPlugin._internals.set3DTransformRatio
6666          };
6667          recordStartPositions();
6668          self.update(true);
6669          return self;
6670        };
6671        this.disable = function (type) {
6672          var dragging = self.isDragging,
6673            i,
6674            trigger;
6675          if (!rotationMode) {
6676            i = triggers.length;
6677            while (--i > -1) {
6678              _setStyle(triggers[i], "cursor", null);
6679            }
6680          }
6681          if (type !== "soft") {
6682            i = triggers.length;
6683            while (--i > -1) {
6684              trigger = triggers[i];
6685              _setStyle(trigger, "touchCallout", null);
6686              _setStyle(trigger, "touchAction", null);
6687              _removeListener(trigger, "mousedown", onPress);
6688              _removeListener(trigger, "touchstart", onPress);
6689              _removeListener(trigger, "click", onClick);
6690              _removeListener(trigger, "contextmenu", onContextMenu);
6691            }
6692            _setSelectable(triggers, true);
6693            if (touchEventTarget) {
6694              _removeListener(touchEventTarget, "touchcancel", _onRelease);
6695              _removeListener(touchEventTarget, "touchend", _onRelease);
6696              _removeListener(touchEventTarget, "touchmove", onMove);
6697            }
6698            _removeListener(_doc, "mouseup", _onRelease);
6699            _removeListener(_doc, "mousemove", onMove);
6700          }
6701          _removeScrollListener2(target, updateScroll);
6702          enabled = false;
6703          if (ThrowPropsPlugin && type !== "soft") {
6704            ThrowPropsPlugin.untrack(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left");
6705          }
6706          if (scrollProxy) {
6707            scrollProxy.disable();
6708          }
6709          _removeFromRenderQueue(render);
6710          self.isDragging = self.isPressed = isClicking = false;
6711          if (dragging) {
6712            _dispatchEvent(self, "dragend", "onDragEnd");
6713          }
6714          return self;
6715        };
6716        this.enabled = function (value, type) {
6717          return arguments.length ? value ? self.enable(type) : self.disable(type) : enabled;
6718        };
6719        this.kill = function () {
6720          self.isThrowing = false;
6721          TweenLite.killTweensOf(scrollProxy || target, true, killProps);
6722          self.disable();
6723          delete _lookup[target._gsDragID];
6724          return self;
6725        };
6726        if (type.indexOf("scroll") !== -1) {
6727          scrollProxy = this.scrollProxy = new ScrollProxy(target, _extend({
6728            onKill: function onKill() {
6729              //ScrollProxy's onKill() gets called if/when the ScrollProxy senses that the user interacted with the scroll position manually (like using the scrollbar). IE9 doesn't fire the "mouseup" properly when users drag the scrollbar of an element, so this works around that issue.
6730              if (self.isPressed) {
6731                _onRelease(null);
6732              }
6733            }
6734          }, vars));
6735          //a bug in many Android devices' stock browser causes scrollTop to get forced back to 0 after it is altered via JS, so we set overflow to "hidden" on mobile/touch devices (they hide the scroll bar anyway). That works around the bug. (This bug is discussed at https://code.google.com/p/android/issues/detail?id=19625)
6736          target.style.overflowY = allowY && !_isTouchDevice ? "auto" : "hidden";
6737          target.style.overflowX = allowX && !_isTouchDevice ? "auto" : "hidden";
6738          target = scrollProxy.content;
6739        }
6740        if (vars.force3D !== false) {
6741          TweenLite.set(target, {
6742            force3D: true
6743          }); //improve performance by forcing a GPU layer when possible
6744        }
6745        if (rotationMode) {
6746          killProps.rotation = 1;
6747        } else {
6748          if (allowX) {
6749            killProps[xProp] = 1;
6750          }
6751          if (allowY) {
6752            killProps[yProp] = 1;
6753          }
6754        }
6755        if (rotationMode) {
6756          tempVars = _tempVarsRotation;
6757          cssVars = tempVars.css;
6758          tempVars.overwrite = false;
6759        } else if (xyMode) {
6760          tempVars = allowX && allowY ? _tempVarsXY : allowX ? _tempVarsX : _tempVarsY;
6761          cssVars = tempVars.css;
6762          tempVars.overwrite = false;
6763        }
6764        this.enable();
6765      },
6766      p = _Draggable.prototype = new EventDispatcher();
6767    p.constructor = _Draggable;
6768    p.pointerX = p.pointerY = p.startX = p.startY = p.deltaX = p.deltaY = 0;
6769    p.isDragging = p.isPressed = false;
6770    _Draggable.version = "0.16.1";
6771    _Draggable.zIndex = 1000;
6772    _addListener(_doc, "touchcancel", function () {
6773      //some older Android devices intermittently stop dispatching "touchmove" events if we don't listen for "touchcancel" on the document. Very strange indeed.
6774    });
6775    _addListener(_doc, "contextmenu", function (e) {
6776      var p;
6777      for (p in _lookup) {
6778        if (_lookup[p].isPressed) {
6779          _lookup[p].endDrag();
6780        }
6781      }
6782    });
6783    _Draggable.create = function (targets, vars) {
6784      if (typeof targets === "string") {
6785        targets = TweenLite.selector(targets);
6786      }
6787      var a = !targets || targets.length === 0 ? [] : _isArrayLike(targets) ? _flattenArray(targets) : [targets],
6788        i = a.length;
6789      while (--i > -1) {
6790        a[i] = new _Draggable(a[i], vars);
6791      }
6792      return a;
6793    };
6794    _Draggable.get = function (target) {
6795      return _lookup[(_unwrapElement(target) || {})._gsDragID];
6796    };
6797    _Draggable.timeSinceDrag = function () {
6798      return (_getTime() - _lastDragTime) / 1000;
6799    };
6800    var _tempRect = {},
6801      //reuse to reduce garbage collection tasks
6802      _oldIERect = function _oldIERect(e) {
6803        //IE8 doesn't support getBoundingClientRect(), so we use this as a backup.
6804        var top = 0,
6805          left = 0,
6806          width,
6807          height;
6808        e = _unwrapElement(e);
6809        width = e.offsetWidth;
6810        height = e.offsetHeight;
6811        while (e) {
6812          top += e.offsetTop;
6813          left += e.offsetLeft;
6814          e = e.offsetParent;
6815        }
6816        return {
6817          top: top,
6818          left: left,
6819          width: width,
6820          height: height
6821        };
6822      },
6823      _parseRect = function _parseRect(e, undefined) {
6824        //accepts a DOM element, a mouse event, or a rectangle object and returns the corresponding rectangle with left, right, width, height, top, and bottom properties
6825        if (e === window) {
6826          _tempRect.left = _tempRect.top = 0;
6827          _tempRect.width = _tempRect.right = _docElement.clientWidth || e.innerWidth || _doc.body.clientWidth || 0;
6828          _tempRect.height = _tempRect.bottom = (e.innerHeight || 0) - 20 < _docElement.clientHeight ? _docElement.clientHeight : e.innerHeight || _doc.body.clientHeight || 0;
6829          return _tempRect;
6830        }
6831        var r = e.pageX !== undefined ? {
6832          left: e.pageX - _getDocScrollLeft(),
6833          top: e.pageY - _getDocScrollTop(),
6834          right: e.pageX - _getDocScrollLeft() + 1,
6835          bottom: e.pageY - _getDocScrollTop() + 1
6836        } : !e.nodeType && e.left !== undefined && e.top !== undefined ? e : _isOldIE ? _oldIERect(e) : _unwrapElement(e).getBoundingClientRect();
6837        if (r.right === undefined && r.width !== undefined) {
6838          r.right = r.left + r.width;
6839          r.bottom = r.top + r.height;
6840        } else if (r.width === undefined) {
6841          //some browsers don't include width and height properties. We can't just set them directly on r because some browsers throw errors, so create a new generic object.
6842          r = {
6843            width: r.right - r.left,
6844            height: r.bottom - r.top,
6845            right: r.right,
6846            left: r.left,
6847            bottom: r.bottom,
6848            top: r.top
6849          };
6850        }
6851        return r;
6852      };
6853    _Draggable.hitTest = function (obj1, obj2, threshold) {
6854      if (obj1 === obj2) {
6855        return false;
6856      }
6857      var r1 = _parseRect(obj1),
6858        r2 = _parseRect(obj2),
6859        isOutside = r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top,
6860        overlap,
6861        area,
6862        isRatio;
6863      if (isOutside || !threshold) {
6864        return !isOutside;
6865      }
6866      isRatio = (threshold + "").indexOf("%") !== -1;
6867      threshold = parseFloat(threshold) || 0;
6868      overlap = {
6869        left: Math.max(r1.left, r2.left),
6870        top: Math.max(r1.top, r2.top)
6871      };
6872      overlap.width = Math.min(r1.right, r2.right) - overlap.left;
6873      overlap.height = Math.min(r1.bottom, r2.bottom) - overlap.top;
6874      if (overlap.width < 0 || overlap.height < 0) {
6875        return false;
6876      }
6877      if (isRatio) {
6878        threshold *= 0.01;
6879        area = overlap.width * overlap.height;
6880        return area >= r1.width * r1.height * threshold || area >= r2.width * r2.height * threshold;
6881      }
6882      return overlap.width > threshold && overlap.height > threshold;
6883    };
6884    _placeholderDiv.style.cssText = "visibility:hidden;height:1px;top:-1px;pointer-events:none;position:relative;clear:both;";
6885    return _Draggable;
6886  }, true);
6887});
6888if (_gsScope._gsDefine) {
6889  _gsScope._gsQueue.pop()();
6890}
6891
6892//export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date)
6893(function (name) {
6894  "use strict";
6895
6896  var getGlobal = function getGlobal() {
6897    return (_gsScope.GreenSockGlobals || _gsScope)[name];
6898  };
6899  if (typeof module !== "undefined" && module.exports) {
6900    //node
6901    require("gsap/TweenLite");
6902    require("gsap/CSSPlugin");
6903    module.exports = getGlobal();
6904  } else if (typeof define === "function" && define.amd) {
6905    //AMD
6906    define(["gsap/TweenLite", "gsap/CSSPlugin"], getGlobal);
6907  }
6908})("Draggable");
6909
6910}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
6911},{"gsap/CSSPlugin":2,"gsap/TweenLite":4}],4:[function(require,module,exports){
6912(function (global){(function (){
6913"use strict";
6914
6915function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
6916/*!
6917 * VERSION: 1.20.4
6918 * DATE: 2018-02-15
6919 * UPDATES AND DOCS AT: http://greensock.com
6920 *
6921 * @license Copyright (c) 2008-2018, GreenSock. All rights reserved.
6922 * This work is subject to the terms at http://greensock.com/standard-license or for
6923 * Club GreenSock members, the software agreement that was issued with your membership.
6924 * 
6925 * @author: Jack Doyle, [email protected]
6926 */
6927(function (window, moduleName) {
6928  "use strict";
6929
6930  var _exports = {},
6931    _doc = window.document,
6932    _globals = window.GreenSockGlobals = window.GreenSockGlobals || window;
6933  if (_globals.TweenLite) {
6934    return; //in case the core set of classes is already loaded, don't instantiate twice.
6935  }
6936  var _namespace = function _namespace(ns) {
6937      var a = ns.split("."),
6938        p = _globals,
6939        i;
6940      for (i = 0; i < a.length; i++) {
6941        p[a[i]] = p = p[a[i]] || {};
6942      }
6943      return p;
6944    },
6945    gs = _namespace("com.greensock"),
6946    _tinyNum = 0.0000000001,
6947    _slice = function _slice(a) {
6948      //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
6949      var b = [],
6950        l = a.length,
6951        i;
6952      for (i = 0; i !== l; b.push(a[i++])) {}
6953      return b;
6954    },
6955    _emptyFunc = function _emptyFunc() {},
6956    _isArray = function () {
6957      //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)
6958      var toString = Object.prototype.toString,
6959        array = toString.call([]);
6960      return function (obj) {
6961        return obj != null && (obj instanceof Array || _typeof(obj) === "object" && !!obj.push && toString.call(obj) === array);
6962      };
6963    }(),
6964    a,
6965    i,
6966    p,
6967    _ticker,
6968    _tickerActive,
6969    _defLookup = {},
6970    /**
6971     * @constructor
6972     * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition.
6973     * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is
6974     * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin
6975     * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally.
6976     *
6977     * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found,
6978     * 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,
6979     * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so
6980     * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything
6981     * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock
6982     * 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
6983     * sandbox the banner one like:
6984     *
6985     * <script>
6986     *     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.
6987     * </script>
6988     * <script src="js/greensock/v1.7/TweenMax.js"></script>
6989     * <script>
6990     *     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(...)
6991     * </script>
6992     * <script src="js/greensock/v1.6/TweenMax.js"></script>
6993     * <script>
6994     *     gs.TweenLite.to(...); //would use v1.7
6995     *     TweenLite.to(...); //would use v1.6
6996     * </script>
6997     *
6998     * @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".
6999     * @param {!Array.<string>} dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"]
7000     * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition.
7001     * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object)
7002     */
7003    _Definition = function Definition(ns, dependencies, func, global) {
7004      this.sc = _defLookup[ns] ? _defLookup[ns].sc : []; //subclasses
7005      _defLookup[ns] = this;
7006      this.gsClass = null;
7007      this.func = func;
7008      var _classes = [];
7009      this.check = function (init) {
7010        var i = dependencies.length,
7011          missing = i,
7012          cur,
7013          a,
7014          n,
7015          cl;
7016        while (--i > -1) {
7017          if ((cur = _defLookup[dependencies[i]] || new _Definition(dependencies[i], [])).gsClass) {
7018            _classes[i] = cur.gsClass;
7019            missing--;
7020          } else if (init) {
7021            cur.sc.push(this);
7022          }
7023        }
7024        if (missing === 0 && func) {
7025          a = ("com.greensock." + ns).split(".");
7026          n = a.pop();
7027          cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes);
7028
7029          //exports to multiple environments
7030          if (global) {
7031            _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.)
7032            if (typeof module !== "undefined" && module.exports) {
7033              //node
7034              if (ns === moduleName) {
7035                module.exports = _exports[moduleName] = cl;
7036                for (i in _exports) {
7037                  cl[i] = _exports[i];
7038                }
7039              } else if (_exports[moduleName]) {
7040                _exports[moduleName][n] = cl;
7041              }
7042            } else if (typeof define === "function" && define.amd) {
7043              //AMD
7044              define((window.GreenSockAMDPath ? window.GreenSockAMDPath + "/" : "") + ns.split(".").pop(), [], function () {
7045                return cl;
7046              });
7047            }
7048          }
7049          for (i = 0; i < this.sc.length; i++) {
7050            this.sc[i].check();
7051          }
7052        }
7053      };
7054      this.check(true);
7055    },
7056    //used to create Definition instances (which basically registers a class that has dependencies).
7057    _gsDefine = window._gsDefine = function (ns, dependencies, func, global) {
7058      return new _Definition(ns, dependencies, func, global);
7059    },
7060    //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).
7061    _class = gs._class = function (ns, func, global) {
7062      func = func || function () {};
7063      _gsDefine(ns, [], function () {
7064        return func;
7065      }, global);
7066      return func;
7067    };
7068  _gsDefine.globals = _globals;
7069
7070  /*
7071   * ----------------------------------------------------------------
7072   * Ease
7073   * ----------------------------------------------------------------
7074   */
7075  var _baseParams = [0, 0, 1, 1],
7076    Ease = _class("easing.Ease", function (func, extraParams, type, power) {
7077      this._func = func;
7078      this._type = type || 0;
7079      this._power = power || 0;
7080      this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams;
7081    }, true),
7082    _easeMap = Ease.map = {},
7083    _easeReg = Ease.register = function (ease, names, types, create) {
7084      var na = names.split(","),
7085        i = na.length,
7086        ta = (types || "easeIn,easeOut,easeInOut").split(","),
7087        e,
7088        name,
7089        j,
7090        type;
7091      while (--i > -1) {
7092        name = na[i];
7093        e = create ? _class("easing." + name, null, true) : gs.easing[name] || {};
7094        j = ta.length;
7095        while (--j > -1) {
7096          type = ta[j];
7097          _easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease();
7098        }
7099      }
7100    };
7101  p = Ease.prototype;
7102  p._calcEnd = false;
7103  p.getRatio = function (p) {
7104    if (this._func) {
7105      this._params[0] = p;
7106      return this._func.apply(null, this._params);
7107    }
7108    var t = this._type,
7109      pw = this._power,
7110      r = t === 1 ? 1 - p : t === 2 ? p : p < 0.5 ? p * 2 : (1 - p) * 2;
7111    if (pw === 1) {
7112      r *= r;
7113    } else if (pw === 2) {
7114      r *= r * r;
7115    } else if (pw === 3) {
7116      r *= r * r * r;
7117    } else if (pw === 4) {
7118      r *= r * r * r * r;
7119    }
7120    return t === 1 ? 1 - r : t === 2 ? r : p < 0.5 ? r / 2 : 1 - r / 2;
7121  };
7122
7123  //create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut)
7124  a = ["Linear", "Quad", "Cubic", "Quart", "Quint,Strong"];
7125  i = a.length;
7126  while (--i > -1) {
7127    p = a[i] + ",Power" + i;
7128    _easeReg(new Ease(null, null, 1, i), p, "easeOut", true);
7129    _easeReg(new Ease(null, null, 2, i), p, "easeIn" + (i === 0 ? ",easeNone" : ""));
7130    _easeReg(new Ease(null, null, 3, i), p, "easeInOut");
7131  }
7132  _easeMap.linear = gs.easing.Linear.easeIn;
7133  _easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks
7134
7135  /*
7136   * ----------------------------------------------------------------
7137   * EventDispatcher
7138   * ----------------------------------------------------------------
7139   */
7140  var EventDispatcher = _class("events.EventDispatcher", function (target) {
7141    this._listeners = {};
7142    this._eventTarget = target || this;
7143  });
7144  p = EventDispatcher.prototype;
7145  p.addEventListener = function (type, callback, scope, useParam, priority) {
7146    priority = priority || 0;
7147    var list = this._listeners[type],
7148      index = 0,
7149      listener,
7150      i;
7151    if (this === _ticker && !_tickerActive) {
7152      _ticker.wake();
7153    }
7154    if (list == null) {
7155      this._listeners[type] = list = [];
7156    }
7157    i = list.length;
7158    while (--i > -1) {
7159      listener = list[i];
7160      if (listener.c === callback && listener.s === scope) {
7161        list.splice(i, 1);
7162      } else if (index === 0 && listener.pr < priority) {
7163        index = i + 1;
7164      }
7165    }
7166    list.splice(index, 0, {
7167      c: callback,
7168      s: scope,
7169      up: useParam,
7170      pr: priority
7171    });
7172  };
7173  p.removeEventListener = function (type, callback) {
7174    var list = this._listeners[type],
7175      i;
7176    if (list) {
7177      i = list.length;
7178      while (--i > -1) {
7179        if (list[i].c === callback) {
7180          list.splice(i, 1);
7181          return;
7182        }
7183      }
7184    }
7185  };
7186  p.dispatchEvent = function (type) {
7187    var list = this._listeners[type],
7188      i,
7189      t,
7190      listener;
7191    if (list) {
7192      i = list.length;
7193      if (i > 1) {
7194        list = list.slice(0); //in case addEventListener() is called from within a listener/callback (otherwise the index could change, resulting in a skip)
7195      }
7196      t = this._eventTarget;
7197      while (--i > -1) {
7198        listener = list[i];
7199        if (listener) {
7200          if (listener.up) {
7201            listener.c.call(listener.s || t, {
7202              type: type,
7203              target: t
7204            });
7205          } else {
7206            listener.c.call(listener.s || t);
7207          }
7208        }
7209      }
7210    }
7211  };
7212
7213  /*
7214   * ----------------------------------------------------------------
7215   * Ticker
7216   * ----------------------------------------------------------------
7217   */
7218  var _reqAnimFrame = window.requestAnimationFrame,
7219    _cancelAnimFrame = window.cancelAnimationFrame,
7220    _getTime = Date.now || function () {
7221      return new Date().getTime();
7222    },
7223    _lastUpdate = _getTime();
7224
7225  //now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill.
7226  a = ["ms", "moz", "webkit", "o"];
7227  i = a.length;
7228  while (--i > -1 && !_reqAnimFrame) {
7229    _reqAnimFrame = window[a[i] + "RequestAnimationFrame"];
7230    _cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"];
7231  }
7232  _class("Ticker", function (fps, useRAF) {
7233    var _self = this,
7234      _startTime = _getTime(),
7235      _useRAF = useRAF !== false && _reqAnimFrame ? "auto" : false,
7236      _lagThreshold = 500,
7237      _adjustedLag = 33,
7238      _tickWord = "tick",
7239      //helps reduce gc burden
7240      _fps,
7241      _req,
7242      _id,
7243      _gap,
7244      _nextTime,
7245      _tick2 = function _tick(manual) {
7246        var elapsed = _getTime() - _lastUpdate,
7247          overlap,
7248          dispatch;
7249        if (elapsed > _lagThreshold) {
7250          _startTime += elapsed - _adjustedLag;
7251        }
7252        _lastUpdate += elapsed;
7253        _self.time = (_lastUpdate - _startTime) / 1000;
7254        overlap = _self.time - _nextTime;
7255        if (!_fps || overlap > 0 || manual === true) {
7256          _self.frame++;
7257          _nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap);
7258          dispatch = true;
7259        }
7260        if (manual !== true) {
7261          //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.
7262          _id = _req(_tick2);
7263        }
7264        if (dispatch) {
7265          _self.dispatchEvent(_tickWord);
7266        }
7267      };
7268    EventDispatcher.call(_self);
7269    _self.time = _self.frame = 0;
7270    _self.tick = function () {
7271      _tick2(true);
7272    };
7273    _self.lagSmoothing = function (threshold, adjustedLag) {
7274      if (!arguments.length) {
7275        //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.
7276        return _lagThreshold < 1 / _tinyNum;
7277      }
7278      _lagThreshold = threshold || 1 / _tinyNum; //zero should be interpreted as basically unlimited
7279      _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0);
7280    };
7281    _self.sleep = function () {
7282      if (_id == null) {
7283        return;
7284      }
7285      if (!_useRAF || !_cancelAnimFrame) {
7286        clearTimeout(_id);
7287      } else {
7288        _cancelAnimFrame(_id);
7289      }
7290      _req = _emptyFunc;
7291      _id = null;
7292      if (_self === _ticker) {
7293        _tickerActive = false;
7294      }
7295    };
7296    _self.wake = function (seamless) {
7297      if (_id !== null) {
7298        _self.sleep();
7299      } else if (seamless) {
7300        _startTime += -_lastUpdate + (_lastUpdate = _getTime());
7301      } else if (_self.frame > 10) {
7302        //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().
7303        _lastUpdate = _getTime() - _lagThreshold + 5;
7304      }
7305      _req = _fps === 0 ? _emptyFunc : !_useRAF || !_reqAnimFrame ? function (f) {
7306        return setTimeout(f, (_nextTime - _self.time) * 1000 + 1 | 0);
7307      } : _reqAnimFrame;
7308      if (_self === _ticker) {
7309        _tickerActive = true;
7310      }
7311      _tick2(2);
7312    };
7313    _self.fps = function (value) {
7314      if (!arguments.length) {
7315        return _fps;
7316      }
7317      _fps = value;
7318      _gap = 1 / (_fps || 60);
7319      _nextTime = this.time + _gap;
7320      _self.wake();
7321    };
7322    _self.useRAF = function (value) {
7323      if (!arguments.length) {
7324        return _useRAF;
7325      }
7326      _self.sleep();
7327      _useRAF = value;
7328      _self.fps(_fps);
7329    };
7330    _self.fps(fps);
7331
7332    //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.
7333    setTimeout(function () {
7334      if (_useRAF === "auto" && _self.frame < 5 && (_doc || {}).visibilityState !== "hidden") {
7335        _self.useRAF(false);
7336      }
7337    }, 1500);
7338  });
7339  p = gs.Ticker.prototype = new gs.events.EventDispatcher();
7340  p.constructor = gs.Ticker;
7341
7342  /*
7343   * ----------------------------------------------------------------
7344   * Animation
7345   * ----------------------------------------------------------------
7346   */
7347  var Animation = _class("core.Animation", function (duration, vars) {
7348    this.vars = vars = vars || {};
7349    this._duration = this._totalDuration = duration || 0;
7350    this._delay = Number(vars.delay) || 0;
7351    this._timeScale = 1;
7352    this._active = vars.immediateRender === true;
7353    this.data = vars.data;
7354    this._reversed = vars.reversed === true;
7355    if (!_rootTimeline) {
7356      return;
7357    }
7358    if (!_tickerActive) {
7359      //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.
7360      _ticker.wake();
7361    }
7362    var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline;
7363    tl.add(this, tl._time);
7364    if (this.vars.paused) {
7365      this.paused(true);
7366    }
7367  });
7368  _ticker = Animation.ticker = new gs.Ticker();
7369  p = Animation.prototype;
7370  p._dirty = p._gc = p._initted = p._paused = false;
7371  p._totalTime = p._time = 0;
7372  p._rawPrevTime = -1;
7373  p._next = p._last = p._onUpdate = p._timeline = p.timeline = null;
7374  p._paused = false;
7375
7376  //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.
7377  var _checkTimeout2 = function _checkTimeout() {
7378    if (_tickerActive && _getTime() - _lastUpdate > 2000 && ((_doc || {}).visibilityState !== "hidden" || !_ticker.lagSmoothing())) {
7379      //note: if the tab is hidden, we should still wake if lagSmoothing has been disabled.
7380      _ticker.wake();
7381    }
7382    var t = setTimeout(_checkTimeout2, 2000);
7383    if (t.unref) {
7384      // 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.
7385      t.unref();
7386    }
7387  };
7388  _checkTimeout2();
7389  p.play = function (from, suppressEvents) {
7390    if (from != null) {
7391      this.seek(from, suppressEvents);
7392    }
7393    return this.reversed(false).paused(false);
7394  };
7395  p.pause = function (atTime, suppressEvents) {
7396    if (atTime != null) {
7397      this.seek(atTime, suppressEvents);
7398    }
7399    return this.paused(true);
7400  };
7401  p.resume = function (from, suppressEvents) {
7402    if (from != null) {
7403      this.seek(from, suppressEvents);
7404    }
7405    return this.paused(false);
7406  };
7407  p.seek = function (time, suppressEvents) {
7408    return this.totalTime(Number(time), suppressEvents !== false);
7409  };
7410  p.restart = function (includeDelay, suppressEvents) {
7411    return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, suppressEvents !== false, true);
7412  };
7413  p.reverse = function (from, suppressEvents) {
7414    if (from != null) {
7415      this.seek(from || this.totalDuration(), suppressEvents);
7416    }
7417    return this.reversed(true).paused(false);
7418  };
7419  p.render = function (time, suppressEvents, force) {
7420    //stub - we override this method in subclasses.
7421  };
7422  p.invalidate = function () {
7423    this._time = this._totalTime = 0;
7424    this._initted = this._gc = false;
7425    this._rawPrevTime = -1;
7426    if (this._gc || !this.timeline) {
7427      this._enabled(true);
7428    }
7429    return this;
7430  };
7431  p.isActive = function () {
7432    var tl = this._timeline,
7433      //the 2 root timelines won't have a _timeline; they're always active.
7434      startTime = this._startTime,
7435      rawTime;
7436    return !tl || !this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime(true)) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale - 0.0000001;
7437  };
7438  p._enabled = function (enabled, ignoreTimeline) {
7439    if (!_tickerActive) {
7440      _ticker.wake();
7441    }
7442    this._gc = !enabled;
7443    this._active = this.isActive();
7444    if (ignoreTimeline !== true) {
7445      if (enabled && !this.timeline) {
7446        this._timeline.add(this, this._startTime - this._delay);
7447      } else if (!enabled && this.timeline) {
7448        this._timeline._remove(this, true);
7449      }
7450    }
7451    return false;
7452  };
7453  p._kill = function (vars, target) {
7454    return this._enabled(false, false);
7455  };
7456  p.kill = function (vars, target) {
7457    this._kill(vars, target);
7458    return this;
7459  };
7460  p._uncache = function (includeSelf) {
7461    var tween = includeSelf ? this : this.timeline;
7462    while (tween) {
7463      tween._dirty = true;
7464      tween = tween.timeline;
7465    }
7466    return this;
7467  };
7468  p._swapSelfInParams = function (params) {
7469    var i = params.length,
7470      copy = params.concat();
7471    while (--i > -1) {
7472      if (params[i] === "{self}") {
7473        copy[i] = this;
7474      }
7475    }
7476    return copy;
7477  };
7478  p._callback = function (type) {
7479    var v = this.vars,
7480      callback = v[type],
7481      params = v[type + "Params"],
7482      scope = v[type + "Scope"] || v.callbackScope || this,
7483      l = params ? params.length : 0;
7484    switch (l) {
7485      //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);
7486      case 0:
7487        callback.call(scope);
7488        break;
7489      case 1:
7490        callback.call(scope, params[0]);
7491        break;
7492      case 2:
7493        callback.call(scope, params[0], params[1]);
7494        break;
7495      default:
7496        callback.apply(scope, params);
7497    }
7498  };
7499
7500  //----Animation getters/setters --------------------------------------------------------
7501
7502  p.eventCallback = function (type, callback, params, scope) {
7503    if ((type || "").substr(0, 2) === "on") {
7504      var v = this.vars;
7505      if (arguments.length === 1) {
7506        return v[type];
7507      }
7508      if (callback == null) {
7509        delete v[type];
7510      } else {
7511        v[type] = callback;
7512        v[type + "Params"] = _isArray(params) && params.join("").indexOf("{self}") !== -1 ? this._swapSelfInParams(params) : params;
7513        v[type + "Scope"] = scope;
7514      }
7515      if (type === "onUpdate") {
7516        this._onUpdate = callback;
7517      }
7518    }
7519    return this;
7520  };
7521  p.delay = function (value) {
7522    if (!arguments.length) {
7523      return this._delay;
7524    }
7525    if (this._timeline.smoothChildTiming) {
7526      this.startTime(this._startTime + value - this._delay);
7527    }
7528    this._delay = value;
7529    return this;
7530  };
7531  p.duration = function (value) {
7532    if (!arguments.length) {
7533      this._dirty = false;
7534      return this._duration;
7535    }
7536    this._duration = this._totalDuration = value;
7537    this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration.
7538    if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) {
7539      this.totalTime(this._totalTime * (value / this._duration), true);
7540    }
7541    return this;
7542  };
7543  p.totalDuration = function (value) {
7544    this._dirty = false;
7545    return !arguments.length ? this._totalDuration : this.duration(value);
7546  };
7547  p.time = function (value, suppressEvents) {
7548    if (!arguments.length) {
7549      return this._time;
7550    }
7551    if (this._dirty) {
7552      this.totalDuration();
7553    }
7554    return this.totalTime(value > this._duration ? this._duration : value, suppressEvents);
7555  };
7556  p.totalTime = function (time, suppressEvents, uncapped) {
7557    if (!_tickerActive) {
7558      _ticker.wake();
7559    }
7560    if (!arguments.length) {
7561      return this._totalTime;
7562    }
7563    if (this._timeline) {
7564      if (time < 0 && !uncapped) {
7565        time += this.totalDuration();
7566      }
7567      if (this._timeline.smoothChildTiming) {
7568        if (this._dirty) {
7569          this.totalDuration();
7570        }
7571        var totalDuration = this._totalDuration,
7572          tl = this._timeline;
7573        if (time > totalDuration && !uncapped) {
7574          time = totalDuration;
7575        }
7576        this._startTime = (this._paused ? this._pauseTime : tl._time) - (!this._reversed ? time : totalDuration - time) / this._timeScale;
7577        if (!tl._dirty) {
7578          //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.
7579          this._uncache(false);
7580        }
7581        //in case any of the ancestor timelines had completed but should now be enabled, we should reset their 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.
7582        if (tl._timeline) {
7583          while (tl._timeline) {
7584            if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) {
7585              tl.totalTime(tl._totalTime, true);
7586            }
7587            tl = tl._timeline;
7588          }
7589        }
7590      }
7591      if (this._gc) {
7592        this._enabled(true, false);
7593      }
7594      if (this._totalTime !== time || this._duration === 0) {
7595        if (_lazyTweens.length) {
7596          _lazyRender();
7597        }
7598        this.render(time, suppressEvents, false);
7599        if (_lazyTweens.length) {
7600          //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.
7601          _lazyRender();
7602        }
7603      }
7604    }
7605    return this;
7606  };
7607  p.progress = p.totalProgress = function (value, suppressEvents) {
7608    var duration = this.duration();
7609    return !arguments.length ? duration ? this._time / duration : this.ratio : this.totalTime(duration * value, suppressEvents);
7610  };
7611  p.startTime = function (value) {
7612    if (!arguments.length) {
7613      return this._startTime;
7614    }
7615    if (value !== this._startTime) {
7616      this._startTime = value;
7617      if (this.timeline) if (this.timeline._sortChildren) {
7618        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.
7619      }
7620    }
7621    return this;
7622  };
7623  p.endTime = function (includeRepeats) {
7624    return this._startTime + (includeRepeats != false ? this.totalDuration() : this.duration()) / this._timeScale;
7625  };
7626  p.timeScale = function (value) {
7627    if (!arguments.length) {
7628      return this._timeScale;
7629    }
7630    var pauseTime, t;
7631    value = value || _tinyNum; //can't allow zero because it'll throw the math off
7632    if (this._timeline && this._timeline.smoothChildTiming) {
7633      pauseTime = this._pauseTime;
7634      t = pauseTime || pauseTime === 0 ? pauseTime : this._timeline.totalTime();
7635      this._startTime = t - (t - this._startTime) * this._timeScale / value;
7636    }
7637    this._timeScale = value;
7638    t = this.timeline;
7639    while (t && t.timeline) {
7640      //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.
7641      t._dirty = true;
7642      t.totalDuration();
7643      t = t.timeline;
7644    }
7645    return this;
7646  };
7647  p.reversed = function (value) {
7648    if (!arguments.length) {
7649      return this._reversed;
7650    }
7651    if (value != this._reversed) {
7652      this._reversed = value;
7653      this.totalTime(this._timeline && !this._timeline.smoothChildTiming ? this.totalDuration() - this._totalTime : this._totalTime, true);
7654    }
7655    return this;
7656  };
7657  p.paused = function (value) {
7658    if (!arguments.length) {
7659      return this._paused;
7660    }
7661    var tl = this._timeline,
7662      raw,
7663      elapsed;
7664    if (value != this._paused) if (tl) {
7665      if (!_tickerActive && !value) {
7666        _ticker.wake();
7667      }
7668      raw = tl.rawTime();
7669      elapsed = raw - this._pauseTime;
7670      if (!value && tl.smoothChildTiming) {
7671        this._startTime += elapsed;
7672        this._uncache(false);
7673      }
7674      this._pauseTime = value ? raw : null;
7675      this._paused = value;
7676      this._active = this.isActive();
7677      if (!value && elapsed !== 0 && this._initted && this.duration()) {
7678        raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale;
7679        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.
7680      }
7681    }
7682    if (this._gc && !value) {
7683      this._enabled(true, false);
7684    }
7685    return this;
7686  };
7687
7688  /*
7689   * ----------------------------------------------------------------
7690   * SimpleTimeline
7691   * ----------------------------------------------------------------
7692   */
7693  var SimpleTimeline = _class("core.SimpleTimeline", function (vars) {
7694    Animation.call(this, 0, vars);
7695    this.autoRemoveChildren = this.smoothChildTiming = true;
7696  });
7697  p = SimpleTimeline.prototype = new Animation();
7698  p.constructor = SimpleTimeline;
7699  p.kill()._gc = false;
7700  p._first = p._last = p._recent = null;
7701  p._sortChildren = false;
7702  p.add = p.insert = function (child, position, align, stagger) {
7703    var prevTween, st;
7704    child._startTime = Number(position || 0) + child._delay;
7705    if (child._paused) if (this !== child._timeline) {
7706      //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).
7707      child._pauseTime = child._startTime + (this.rawTime() - child._startTime) / child._timeScale;
7708    }
7709    if (child.timeline) {
7710      child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one.
7711    }
7712    child.timeline = child._timeline = this;
7713    if (child._gc) {
7714      child._enabled(true, true);
7715    }
7716    prevTween = this._last;
7717    if (this._sortChildren) {
7718      st = child._startTime;
7719      while (prevTween && prevTween._startTime > st) {
7720        prevTween = prevTween._prev;
7721      }
7722    }
7723    if (prevTween) {
7724      child._next = prevTween._next;
7725      prevTween._next = child;
7726    } else {
7727      child._next = this._first;
7728      this._first = child;
7729    }
7730    if (child._next) {
7731      child._next._prev = child;
7732    } else {
7733      this._last = child;
7734    }
7735    child._prev = prevTween;
7736    this._recent = child;
7737    if (this._timeline) {
7738      this._uncache(true);
7739    }
7740    return this;
7741  };
7742  p._remove = function (tween, skipDisable) {
7743    if (tween.timeline === this) {
7744      if (!skipDisable) {
7745        tween._enabled(false, true);
7746      }
7747      if (tween._prev) {
7748        tween._prev._next = tween._next;
7749      } else if (this._first === tween) {
7750        this._first = tween._next;
7751      }
7752      if (tween._next) {
7753        tween._next._prev = tween._prev;
7754      } else if (this._last === tween) {
7755        this._last = tween._prev;
7756      }
7757      tween._next = tween._prev = tween.timeline = null;
7758      if (tween === this._recent) {
7759        this._recent = this._last;
7760      }
7761      if (this._timeline) {
7762        this._uncache(true);
7763      }
7764    }
7765    return this;
7766  };
7767  p.render = function (time, suppressEvents, force) {
7768    var tween = this._first,
7769      next;
7770    this._totalTime = this._time = this._rawPrevTime = time;
7771    while (tween) {
7772      next = tween._next; //record it here because the value could change after rendering...
7773      if (tween._active || time >= tween._startTime && !tween._paused && !tween._gc) {
7774        if (!tween._reversed) {
7775          tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
7776        } else {
7777          tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
7778        }
7779      }
7780      tween = next;
7781    }
7782  };
7783  p.rawTime = function () {
7784    if (!_tickerActive) {
7785      _ticker.wake();
7786    }
7787    return this._totalTime;
7788  };
7789
7790  /*
7791   * ----------------------------------------------------------------
7792   * TweenLite
7793   * ----------------------------------------------------------------
7794   */
7795  var TweenLite = _class("TweenLite", function (target, duration, vars) {
7796      Animation.call(this, duration, vars);
7797      this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
7798
7799      if (target == null) {
7800        throw "Cannot tween a null target.";
7801      }
7802      this.target = target = typeof target !== "string" ? target : TweenLite.selector(target) || target;
7803      var isSelector = target.jquery || target.length && target !== window && target[0] && (target[0] === window || target[0].nodeType && target[0].style && !target.nodeType),
7804        overwrite = this.vars.overwrite,
7805        i,
7806        targ,
7807        targets;
7808      this._overwrite = overwrite = overwrite == null ? _overwriteLookup[TweenLite.defaultOverwrite] : typeof overwrite === "number" ? overwrite >> 0 : _overwriteLookup[overwrite];
7809      if ((isSelector || target instanceof Array || target.push && _isArray(target)) && typeof target[0] !== "number") {
7810        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()
7811        this._propLookup = [];
7812        this._siblings = [];
7813        for (i = 0; i < targets.length; i++) {
7814          targ = targets[i];
7815          if (!targ) {
7816            targets.splice(i--, 1);
7817            continue;
7818          } else if (typeof targ === "string") {
7819            targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings
7820            if (typeof targ === "string") {
7821              targets.splice(i + 1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case)
7822            }
7823            continue;
7824          } else if (targ.length && targ !== window && targ[0] && (targ[0] === window || targ[0].nodeType && targ[0].style && !targ.nodeType)) {
7825            //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.
7826            targets.splice(i--, 1);
7827            this._targets = targets = targets.concat(_slice(targ));
7828            continue;
7829          }
7830          this._siblings[i] = _register(targ, this, false);
7831          if (overwrite === 1) if (this._siblings[i].length > 1) {
7832            _applyOverwrite(targ, this, null, 1, this._siblings[i]);
7833          }
7834        }
7835      } else {
7836        this._propLookup = {};
7837        this._siblings = _register(target, this, false);
7838        if (overwrite === 1) if (this._siblings.length > 1) {
7839          _applyOverwrite(target, this, null, 1, this._siblings);
7840        }
7841      }
7842      if (this.vars.immediateRender || duration === 0 && this._delay === 0 && this.vars.immediateRender !== false) {
7843        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)
7844        this.render(Math.min(0, -this._delay)); //in case delay is negative
7845      }
7846    }, true),
7847    _isSelector = function _isSelector(v) {
7848      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.
7849    },
7850    _autoCSS = function _autoCSS(vars, target) {
7851      var css = {},
7852        p;
7853      for (p in vars) {
7854        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)) {
7855          //note: <img> elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties.
7856          css[p] = vars[p];
7857          delete vars[p];
7858        }
7859      }
7860      vars.css = css;
7861    };
7862  p = TweenLite.prototype = new Animation();
7863  p.constructor = TweenLite;
7864  p.kill()._gc = false;
7865
7866  //----TweenLite defaults, overwrite management, and root updates ----------------------------------------------------
7867
7868  p.ratio = 0;
7869  p._firstPT = p._targets = p._overwrittenProps = p._startAt = null;
7870  p._notifyPluginsOfEnabled = p._lazy = false;
7871  TweenLite.version = "1.20.4";
7872  TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1);
7873  TweenLite.defaultOverwrite = "auto";
7874  TweenLite.ticker = _ticker;
7875  TweenLite.autoSleep = 120;
7876  TweenLite.lagSmoothing = function (threshold, adjustedLag) {
7877    _ticker.lagSmoothing(threshold, adjustedLag);
7878  };
7879  TweenLite.selector = window.$ || window.jQuery || function (e) {
7880    var selector = window.$ || window.jQuery;
7881    if (selector) {
7882      TweenLite.selector = selector;
7883      return selector(e);
7884    }
7885    return typeof _doc === "undefined" ? e : _doc.querySelectorAll ? _doc.querySelectorAll(e) : _doc.getElementById(e.charAt(0) === "#" ? e.substr(1) : e);
7886  };
7887  var _lazyTweens = [],
7888    _lazyLookup = {},
7889    _numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
7890    _relExp = /[\+-]=-?[\.\d]/,
7891    //_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig,
7892    _setRatio = function _setRatio(v) {
7893      var pt = this._firstPT,
7894        min = 0.000001,
7895        val;
7896      while (pt) {
7897        val = !pt.blob ? pt.c * v + pt.s : v === 1 && this.end != null ? this.end : v ? this.join("") : this.start;
7898        if (pt.m) {
7899          val = pt.m(val, this._target || pt.t);
7900        } else if (val < min) if (val > -min && !pt.blob) {
7901          //prevents issues with converting very small numbers to strings in the browser
7902          val = 0;
7903        }
7904        if (!pt.f) {
7905          pt.t[pt.p] = val;
7906        } else if (pt.fp) {
7907          pt.t[pt.p](pt.fp, val);
7908        } else {
7909          pt.t[pt.p](val);
7910        }
7911        pt = pt._next;
7912      }
7913    },
7914    //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("")).
7915    _blobDif = function _blobDif(start, end, filter, pt) {
7916      var a = [],
7917        charIndex = 0,
7918        s = "",
7919        color = 0,
7920        startNums,
7921        endNums,
7922        num,
7923        i,
7924        l,
7925        nonNumbers,
7926        currentNum;
7927      a.start = start;
7928      a.end = end;
7929      start = a[0] = start + ""; //ensure values are strings
7930      end = a[1] = end + "";
7931      if (filter) {
7932        filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.
7933        start = a[0];
7934        end = a[1];
7935      }
7936      a.length = 0;
7937      startNums = start.match(_numbersExp) || [];
7938      endNums = end.match(_numbersExp) || [];
7939      if (pt) {
7940        pt._next = null;
7941        pt.blob = 1;
7942        a._firstPT = a._applyPT = pt; //apply last in the linked list (which means inserting it first)
7943      }
7944      l = endNums.length;
7945      for (i = 0; i < l; i++) {
7946        currentNum = endNums[i];
7947        nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex) - charIndex);
7948        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.
7949        charIndex += nonNumbers.length;
7950        if (color) {
7951          //sense rgba() values and round them.
7952          color = (color + 1) % 5;
7953        } else if (nonNumbers.substr(-5) === "rgba(") {
7954          color = 1;
7955        }
7956        if (currentNum === startNums[i] || startNums.length <= i) {
7957          s += currentNum;
7958        } else {
7959          if (s) {
7960            a.push(s);
7961            s = "";
7962          }
7963          num = parseFloat(startNums[i]);
7964          a.push(num);
7965          a._firstPT = {
7966            _next: a._firstPT,
7967            t: a,
7968            p: a.length - 1,
7969            s: num,
7970            c: (currentNum.charAt(1) === "=" ? parseInt(currentNum.charAt(0) + "1", 10) * parseFloat(currentNum.substr(2)) : parseFloat(currentNum) - num) || 0,
7971            f: 0,
7972            m: color && color < 4 ? Math.round : 0
7973          };
7974          //note: we don't set _prev because we'll never need to remove individual PropTweens from this list.
7975        }
7976        charIndex += currentNum.length;
7977      }
7978      s += end.substr(charIndex);
7979      if (s) {
7980        a.push(s);
7981      }
7982      a.setRatio = _setRatio;
7983      if (_relExp.test(end)) {
7984        //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).
7985        a.end = null;
7986      }
7987      return a;
7988    },
7989    //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.
7990    _addPropTween = function _addPropTween(target, prop, start, end, overwriteProp, mod, funcParam, stringFilter, index) {
7991      if (typeof end === "function") {
7992        end = end(index || 0, target);
7993      }
7994      var type = _typeof(target[prop]),
7995        getterName = type !== "function" ? "" : prop.indexOf("set") || typeof target["get" + prop.substr(3)] !== "function" ? prop : "get" + prop.substr(3),
7996        s = start !== "get" ? start : !getterName ? target[prop] : funcParam ? target[getterName](funcParam) : target[getterName](),
7997        isRelative = typeof end === "string" && end.charAt(1) === "=",
7998        pt = {
7999          t: target,
8000          p: prop,
8001          s: s,
8002          f: type === "function",
8003          pg: 0,
8004          n: overwriteProp || prop,
8005          m: !mod ? 0 : typeof mod === "function" ? mod : Math.round,
8006          pr: 0,
8007          c: isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : parseFloat(end) - s || 0
8008        },
8009        blob;
8010      if (typeof s !== "number" || typeof end !== "number" && !isRelative) {
8011        if (funcParam || isNaN(s) || !isRelative && isNaN(end) || typeof s === "boolean" || typeof end === "boolean") {
8012          //a blob (string that has multiple numbers in it)
8013          pt.fp = funcParam;
8014          blob = _blobDif(s, isRelative ? parseFloat(pt.s) + pt.c + (pt.s + "").replace(/[0-9\-\.]/g, "") : end, stringFilter || TweenLite.defaultStringFilter, pt);
8015          pt = {
8016            t: blob,
8017            p: "setRatio",
8018            s: 0,
8019            c: 1,
8020            f: 2,
8021            pg: 0,
8022            n: overwriteProp || prop,
8023            pr: 0,
8024            m: 0
8025          }; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example.
8026        } else {
8027          pt.s = parseFloat(s);
8028          if (!isRelative) {
8029            pt.c = parseFloat(end) - pt.s || 0;
8030          }
8031        }
8032      }
8033      if (pt.c) {
8034        //only add it to the linked list if there's a change.
8035        if (pt._next = this._firstPT) {
8036          pt._next._prev = pt;
8037        }
8038        this._firstPT = pt;
8039        return pt;
8040      }
8041    },
8042    _internals = TweenLite._internals = {
8043      isArray: _isArray,
8044      isSelector: _isSelector,
8045      lazyTweens: _lazyTweens,
8046      blobDif: _blobDif
8047    },
8048    //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object.
8049    _plugins = TweenLite._plugins = {},
8050    _tweenLookup = _internals.tweenLookup = {},
8051    _tweenLookupNum = 0,
8052    _reservedProps = _internals.reservedProps = {
8053      ease: 1,
8054      delay: 1,
8055      overwrite: 1,
8056      onComplete: 1,
8057      onCompleteParams: 1,
8058      onCompleteScope: 1,
8059      useFrames: 1,
8060      runBackwards: 1,
8061      startAt: 1,
8062      onUpdate: 1,
8063      onUpdateParams: 1,
8064      onUpdateScope: 1,
8065      onStart: 1,
8066      onStartParams: 1,
8067      onStartScope: 1,
8068      onReverseComplete: 1,
8069      onReverseCompleteParams: 1,
8070      onReverseCompleteScope: 1,
8071      onRepeat: 1,
8072      onRepeatParams: 1,
8073      onRepeatScope: 1,
8074      easeParams: 1,
8075      yoyo: 1,
8076      immediateRender: 1,
8077      repeat: 1,
8078      repeatDelay: 1,
8079      data: 1,
8080      paused: 1,
8081      reversed: 1,
8082      autoCSS: 1,
8083      lazy: 1,
8084      onOverwrite: 1,
8085      callbackScope: 1,
8086      stringFilter: 1,
8087      id: 1,
8088      yoyoEase: 1
8089    },
8090    _overwriteLookup = {
8091      none: 0,
8092      all: 1,
8093      auto: 2,
8094      concurrent: 3,
8095      allOnStart: 4,
8096      preexisting: 5,
8097      "true": 1,
8098      "false": 0
8099    },
8100    _rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(),
8101    _rootTimeline = Animation._rootTimeline = new SimpleTimeline(),
8102    _nextGCFrame = 30,
8103    _lazyRender = _internals.lazyRender = function () {
8104      var i = _lazyTweens.length,
8105        tween;
8106      _lazyLookup = {};
8107      while (--i > -1) {
8108        tween = _lazyTweens[i];
8109        if (tween && tween._lazy !== false) {
8110          tween.render(tween._lazy[0], tween._lazy[1], true);
8111          tween._lazy = false;
8112        }
8113      }
8114      _lazyTweens.length = 0;
8115    };
8116  _rootTimeline._startTime = _ticker.time;
8117  _rootFramesTimeline._startTime = _ticker.frame;
8118  _rootTimeline._active = _rootFramesTimeline._active = true;
8119  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".
8120
8121  Animation._updateRoot = TweenLite.render = function () {
8122    var i, a, p;
8123    if (_lazyTweens.length) {
8124      //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.
8125      _lazyRender();
8126    }
8127    _rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false);
8128    _rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false);
8129    if (_lazyTweens.length) {
8130      _lazyRender();
8131    }
8132    if (_ticker.frame >= _nextGCFrame) {
8133      //dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to
8134      _nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120);
8135      for (p in _tweenLookup) {
8136        a = _tweenLookup[p].tweens;
8137        i = a.length;
8138        while (--i > -1) {
8139          if (a[i]._gc) {
8140            a.splice(i, 1);
8141          }
8142        }
8143        if (a.length === 0) {
8144          delete _tweenLookup[p];
8145        }
8146      }
8147      //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
8148      p = _rootTimeline._first;
8149      if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) {
8150        while (p && p._paused) {
8151          p = p._next;
8152        }
8153        if (!p) {
8154          _ticker.sleep();
8155        }
8156      }
8157    }
8158  };
8159  _ticker.addEventListener("tick", Animation._updateRoot);
8160  var _register = function _register(target, tween, scrub) {
8161      var id = target._gsTweenID,
8162        a,
8163        i;
8164      if (!_tweenLookup[id || (target._gsTweenID = id = "t" + _tweenLookupNum++)]) {
8165        _tweenLookup[id] = {
8166          target: target,
8167          tweens: []
8168        };
8169      }
8170      if (tween) {
8171        a = _tweenLookup[id].tweens;
8172        a[i = a.length] = tween;
8173        if (scrub) {
8174          while (--i > -1) {
8175            if (a[i] === tween) {
8176              a.splice(i, 1);
8177            }
8178          }
8179        }
8180      }
8181      return _tweenLookup[id].tweens;
8182    },
8183    _onOverwrite = function _onOverwrite(overwrittenTween, overwritingTween, target, killedProps) {
8184      var func = overwrittenTween.vars.onOverwrite,
8185        r1,
8186        r2;
8187      if (func) {
8188        r1 = func(overwrittenTween, overwritingTween, target, killedProps);
8189      }
8190      func = TweenLite.onOverwrite;
8191      if (func) {
8192        r2 = func(overwrittenTween, overwritingTween, target, killedProps);
8193      }
8194      return r1 !== false && r2 !== false;
8195    },
8196    _applyOverwrite = function _applyOverwrite(target, tween, props, mode, siblings) {
8197      var i, changed, curTween, l;
8198      if (mode === 1 || mode >= 4) {
8199        l = siblings.length;
8200        for (i = 0; i < l; i++) {
8201          if ((curTween = siblings[i]) !== tween) {
8202            if (!curTween._gc) {
8203              if (curTween._kill(null, target, tween)) {
8204                changed = true;
8205              }
8206            }
8207          } else if (mode === 5) {
8208            break;
8209          }
8210        }
8211        return changed;
8212      }
8213      //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)
8214      var startTime = tween._startTime + _tinyNum,
8215        overlaps = [],
8216        oCount = 0,
8217        zeroDur = tween._duration === 0,
8218        globalStart;
8219      i = siblings.length;
8220      while (--i > -1) {
8221        if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) {
8222          //ignore
8223        } else if (curTween._timeline !== tween._timeline) {
8224          globalStart = globalStart || _checkOverlap(tween, 0, zeroDur);
8225          if (_checkOverlap(curTween, globalStart, zeroDur) === 0) {
8226            overlaps[oCount++] = curTween;
8227          }
8228        } else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) {
8229          overlaps[oCount++] = curTween;
8230        }
8231      }
8232      i = oCount;
8233      while (--i > -1) {
8234        curTween = overlaps[i];
8235        if (mode === 2) if (curTween._kill(props, target, tween)) {
8236          changed = true;
8237        }
8238        if (mode !== 2 || !curTween._firstPT && curTween._initted) {
8239          if (mode !== 2 && !_onOverwrite(curTween, tween)) {
8240            continue;
8241          }
8242          if (curTween._enabled(false, false)) {
8243            //if all property tweens have been overwritten, kill the tween.
8244            changed = true;
8245          }
8246        }
8247      }
8248      return changed;
8249    },
8250    _checkOverlap = function _checkOverlap(tween, reference, zeroDur) {
8251      var tl = tween._timeline,
8252        ts = tl._timeScale,
8253        t = tween._startTime;
8254      while (tl._timeline) {
8255        t += tl._startTime;
8256        ts *= tl._timeScale;
8257        if (tl._paused) {
8258          return -100;
8259        }
8260        tl = tl._timeline;
8261      }
8262      t /= ts;
8263      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;
8264    };
8265
8266  //---- TweenLite instance methods -----------------------------------------------------------------------------
8267
8268  p._init = function () {
8269    var v = this.vars,
8270      op = this._overwrittenProps,
8271      dur = this._duration,
8272      immediate = !!v.immediateRender,
8273      ease = v.ease,
8274      i,
8275      initPlugins,
8276      pt,
8277      p,
8278      startVars,
8279      l;
8280    if (v.startAt) {
8281      if (this._startAt) {
8282        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.
8283        this._startAt.kill();
8284      }
8285      startVars = {};
8286      for (p in v.startAt) {
8287        //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);
8288        startVars[p] = v.startAt[p];
8289      }
8290      startVars.data = "isStart";
8291      startVars.overwrite = false;
8292      startVars.immediateRender = true;
8293      startVars.lazy = immediate && v.lazy !== false;
8294      startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop).
8295      startVars.onUpdate = v.onUpdate;
8296      startVars.onUpdateParams = v.onUpdateParams;
8297      startVars.onUpdateScope = v.onUpdateScope || v.callbackScope || this;
8298      this._startAt = TweenLite.to(this.target, 0, startVars);
8299      if (immediate) {
8300        if (this._time > 0) {
8301          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()).
8302        } else if (dur !== 0) {
8303          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.
8304        }
8305      }
8306    } else if (v.runBackwards && dur !== 0) {
8307      //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)
8308      if (this._startAt) {
8309        this._startAt.render(-1, true);
8310        this._startAt.kill();
8311        this._startAt = null;
8312      } else {
8313        if (this._time !== 0) {
8314          //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
8315          immediate = false;
8316        }
8317        pt = {};
8318        for (p in v) {
8319          //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.
8320          if (!_reservedProps[p] || p === "autoCSS") {
8321            pt[p] = v[p];
8322          }
8323        }
8324        pt.overwrite = 0;
8325        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.
8326        pt.lazy = immediate && v.lazy !== false;
8327        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)
8328        this._startAt = TweenLite.to(this.target, 0, pt);
8329        if (!immediate) {
8330          this._startAt._init(); //ensures that the initial values are recorded
8331          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.
8332          if (this.vars.immediateRender) {
8333            this._startAt = null;
8334          }
8335        } else if (this._time === 0) {
8336          return;
8337        }
8338      }
8339    }
8340    this._ease = ease = !ease ? TweenLite.defaultEase : ease instanceof Ease ? ease : typeof ease === "function" ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase;
8341    if (v.easeParams instanceof Array && ease.config) {
8342      this._ease = ease.config.apply(ease, v.easeParams);
8343    }
8344    this._easeType = this._ease._type;
8345    this._easePower = this._ease._power;
8346    this._firstPT = null;
8347    if (this._targets) {
8348      l = this._targets.length;
8349      for (i = 0; i < l; i++) {
8350        if (this._initProps(this._targets[i], this._propLookup[i] = {}, this._siblings[i], op ? op[i] : null, i)) {
8351          initPlugins = true;
8352        }
8353      }
8354    } else {
8355      initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op, 0);
8356    }
8357    if (initPlugins) {
8358      TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite
8359    }
8360    if (op) if (!this._firstPT) if (typeof this.target !== "function") {
8361      //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.
8362      this._enabled(false, false);
8363    }
8364    if (v.runBackwards) {
8365      pt = this._firstPT;
8366      while (pt) {
8367        pt.s += pt.c;
8368        pt.c = -pt.c;
8369        pt = pt._next;
8370      }
8371    }
8372    this._onUpdate = v.onUpdate;
8373    this._initted = true;
8374  };
8375  p._initProps = function (target, propLookup, siblings, overwrittenProps, index) {
8376    var p, i, initPlugins, plugin, pt, v;
8377    if (target == null) {
8378      return false;
8379    }
8380    if (_lazyLookup[target._gsTweenID]) {
8381      _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)
8382    }
8383    if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) {
8384      //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.
8385      _autoCSS(this.vars, target);
8386    }
8387    for (p in this.vars) {
8388      v = this.vars[p];
8389      if (_reservedProps[p]) {
8390        if (v) if (v instanceof Array || v.push && _isArray(v)) if (v.join("").indexOf("{self}") !== -1) {
8391          this.vars[p] = v = this._swapSelfInParams(v, this);
8392        }
8393      } else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this, index)) {
8394        //t - target 		[object]
8395        //p - property 		[string]
8396        //s - start			[number]
8397        //c - change		[number]
8398        //f - isFunction	[boolean]
8399        //n - name			[string]
8400        //pg - isPlugin 	[boolean]
8401        //pr - priority		[number]
8402        //m - mod           [function | 0]
8403        this._firstPT = pt = {
8404          _next: this._firstPT,
8405          t: plugin,
8406          p: "setRatio",
8407          s: 0,
8408          c: 1,
8409          f: 1,
8410          n: p,
8411          pg: 1,
8412          pr: plugin._priority,
8413          m: 0
8414        };
8415        i = plugin._overwriteProps.length;
8416        while (--i > -1) {
8417          propLookup[plugin._overwriteProps[i]] = this._firstPT;
8418        }
8419        if (plugin._priority || plugin._onInitAllProps) {
8420          initPlugins = true;
8421        }
8422        if (plugin._onDisable || plugin._onEnable) {
8423          this._notifyPluginsOfEnabled = true;
8424        }
8425        if (pt._next) {
8426          pt._next._prev = pt;
8427        }
8428      } else {
8429        propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter, index);
8430      }
8431    }
8432    if (overwrittenProps) if (this._kill(overwrittenProps, target)) {
8433      //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)
8434      return this._initProps(target, propLookup, siblings, overwrittenProps, index);
8435    }
8436    if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) {
8437      this._kill(propLookup, target);
8438      return this._initProps(target, propLookup, siblings, overwrittenProps, index);
8439    }
8440    if (this._firstPT) if (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration) {
8441      //zero duration tweens don't lazy render by default; everything else does.
8442      _lazyLookup[target._gsTweenID] = true;
8443    }
8444    return initPlugins;
8445  };
8446  p.render = function (time, suppressEvents, force) {
8447    var prevTime = this._time,
8448      duration = this._duration,
8449      prevRawPrevTime = this._rawPrevTime,
8450      isComplete,
8451      callback,
8452      pt,
8453      rawPrevTime;
8454    if (time >= duration - 0.0000001 && time >= 0) {
8455      //to work around occasional floating point math artifacts.
8456      this._totalTime = this._time = duration;
8457      this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
8458      if (!this._reversed) {
8459        isComplete = true;
8460        callback = "onComplete";
8461        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.
8462      }
8463      if (duration === 0) if (this._initted || !this.vars.lazy || force) {
8464        //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.
8465        if (this._startTime === this._timeline._duration) {
8466          //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
8466ding 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.
8467          time = 0;
8468        }
8469        if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) {
8470          //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.
8471          force = true;
8472          if (prevRawPrevTime > _tinyNum) {
8473            callback = "onReverseComplete";
8474          }
8475        }
8476        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.
8477      }
8478    } else if (time < 0.0000001) {
8479      //to work around occasional floating point math artifacts, round super small values to 0.
8480      this._totalTime = this._time = 0;
8481      this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
8482      if (prevTime !== 0 || duration === 0 && prevRawPrevTime > 0) {
8483        callback = "onReverseComplete";
8484        isComplete = this._reversed;
8485      }
8486      if (time < 0) {
8487        this._active = false;
8488        if (duration === 0) if (this._initted || !this.vars.lazy || force) {
8489          //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.
8490          if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) {
8491            force = true;
8492          }
8493          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.
8494        }
8495      }
8496      if (!this._initted || this._startAt && this._startAt.progress()) {
8497        //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.
8498        force = true;
8499      }
8500    } else {
8501      this._totalTime = this._time = time;
8502      if (this._easeType) {
8503        var r = time / duration,
8504          type = this._easeType,
8505          pow = this._easePower;
8506        if (type === 1 || type === 3 && r >= 0.5) {
8507          r = 1 - r;
8508        }
8509        if (type === 3) {
8510          r *= 2;
8511        }
8512        if (pow === 1) {
8513          r *= r;
8514        } else if (pow === 2) {
8515          r *= r * r;
8516        } else if (pow === 3) {
8517          r *= r * r * r;
8518        } else if (pow === 4) {
8519          r *= r * r * r * r;
8520        }
8521        if (type === 1) {
8522          this.ratio = 1 - r;
8523        } else if (type === 2) {
8524          this.ratio = r;
8525        } else if (time / duration < 0.5) {
8526          this.ratio = r / 2;
8527        } else {
8528          this.ratio = 1 - r / 2;
8529        }
8530      } else {
8531        this.ratio = this._ease.getRatio(time / duration);
8532      }
8533    }
8534    if (this._time === prevTime && !force) {
8535      return;
8536    } else if (!this._initted) {
8537      this._init();
8538      if (!this._initted || this._gc) {
8539        //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that over
8539writing 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.
8540        return;
8541      } else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) {
8542        this._time = this._totalTime = prevTime;
8543        this._rawPrevTime = prevRawPrevTime;
8544        _lazyTweens.push(this);
8545        this._lazy = [time, suppressEvents];
8546        return;
8547      }
8548      //_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.
8549      if (this._time && !isComplete) {
8550        this.ratio = this._ease.getRatio(this._time / duration);
8551      } else if (isComplete && this._ease._calcEnd) {
8552        this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1);
8553      }
8554    }
8555    if (this._lazy !== false) {
8556      //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.
8557      this._lazy = false;
8558    }
8559    if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
8560      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.
8561    }
8562    if (prevTime === 0) {
8563      if (this._startAt) {
8564        if (time >= 0) {
8565          this._startAt.render(time, true, force);
8566        } else if (!callback) {
8567          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.
8568        }
8569      }
8570      if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) {
8571        this._callback("onStart");
8572      }
8573    }
8574    pt = this._firstPT;
8575    while (pt) {
8576      if (pt.f) {
8577        pt.t[pt.p](pt.c * this.ratio + pt.s);
8578      } else {
8579        pt.t[pt.p] = pt.c * this.ratio + pt.s;
8580      }
8581      pt = pt._next;
8582    }
8583    if (this._onUpdate) {
8584      if (time < 0) if (this._startAt && time !== -0.0001) {
8585        //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.
8586        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.
8587      }
8588      if (!suppressEvents) if (this._time !== prevTime || isComplete || force) {
8589        this._callback("onUpdate");
8590      }
8591    }
8592    if (callback) if (!this._gc || force) {
8593      //check _gc because there's a chance that kill() could be called in an onUpdate
8594      if (time < 0 && this._startAt && !this._onUpdate && time !== -0.0001) {
8595        //-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.
8596        this._startAt.render(time, true, force);
8597      }
8598      if (isComplete) {
8599        if (this._timeline.autoRemoveChildren) {
8600          this._enabled(false, false);
8601        }
8602        this._active = false;
8603      }
8604      if (!suppressEvents && this.vars[callback]) {
8605        this._callback(callback);
8606      }
8607      if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) {
8608        //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 scenario, but possible nonetheless.
8609        this._rawPrevTime = 0;
8610      }
8611    }
8612  };
8613  p._kill = function (vars, target, overwritingTween) {
8614    if (vars === "all") {
8615      vars = null;
8616    }
8617    if (vars == null) if (target == null || target === this.target) {
8618      this._lazy = false;
8619      return this._enabled(false, false);
8620    }
8621    target = typeof target !== "string" ? target || this._targets || this.target : TweenLite.selector(target) || target;
8622    var simultaneousOverwrite = overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline,
8623      i,
8624      overwrittenProps,
8625      p,
8626      pt,
8627      propLookup,
8628      changed,
8629      killProps,
8630      record,
8631      killed;
8632    if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") {
8633      i = target.length;
8634      while (--i > -1) {
8635        if (this._kill(vars, target[i], overwritingTween)) {
8636          changed = true;
8637        }
8638      }
8639    } else {
8640      if (this._targets) {
8641        i = this._targets.length;
8642        while (--i > -1) {
8643          if (target === this._targets[i]) {
8644            propLookup = this._propLookup[i] || {};
8645            this._overwrittenProps = this._overwrittenProps || [];
8646            overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all";
8647            break;
8648          }
8649        }
8650      } else if (target !== this.target) {
8651        return false;
8652      } else {
8653        propLookup = this._propLookup;
8654        overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all";
8655      }
8656      if (propLookup) {
8657        killProps = vars || propLookup;
8658        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)
8659        if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) {
8660          for (p in killProps) {
8661            if (propLookup[p]) {
8662              if (!killed) {
8663                killed = [];
8664              }
8665              killed.push(p);
8666            }
8667          }
8668          if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) {
8669            //if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it).
8670            return false;
8671          }
8672        }
8673        for (p in killProps) {
8674          if (pt = propLookup[p]) {
8675            if (simultaneousOverwrite) {
8676              //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.
8677              if (pt.f) {
8678                pt.t[pt.p](pt.s);
8679              } else {
8680                pt.t[pt.p] = pt.s;
8681              }
8682              changed = true;
8683            }
8684            if (pt.pg && pt.t._kill(killProps)) {
8685              changed = true; //some plugins need to be notified so they can perform cleanup tasks first
8686            }
8687            if (!pt.pg || pt.t._overwriteProps.length === 0) {
8688              if (pt._prev) {
8689                pt._prev._next = pt._next;
8690              } else if (pt === this._firstPT) {
8691                this._firstPT = pt._next;
8692              }
8693              if (pt._next) {
8694                pt._next._prev = pt._prev;
8695              }
8696              pt._next = pt._prev = null;
8697            }
8698            delete propLookup[p];
8699          }
8700          if (record) {
8701            overwrittenProps[p] = 1;
8702          }
8703        }
8704        if (!this._firstPT && this._initted) {
8705          //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.
8706          this._enabled(false, false);
8707        }
8708      }
8709    }
8710    return changed;
8711  };
8712  p.invalidate = function () {
8713    if (this._notifyPluginsOfEnabled) {
8714      TweenLite._onPluginEvent("_onDisable", this);
8715    }
8716    this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null;
8717    this._notifyPluginsOfEnabled = this._active = this._lazy = false;
8718    this._propLookup = this._targets ? {} : [];
8719    Animation.prototype.invalidate.call(this);
8720    if (this.vars.immediateRender) {
8721      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)
8722      this.render(Math.min(0, -this._delay)); //in case delay is negative.
8723    }
8724    return this;
8725  };
8726  p._enabled = function (enabled, ignoreTimeline) {
8727    if (!_tickerActive) {
8728      _ticker.wake();
8729    }
8730    if (enabled && this._gc) {
8731      var targets = this._targets,
8732        i;
8733      if (targets) {
8734        i = targets.length;
8735        while (--i > -1) {
8736          this._siblings[i] = _register(targets[i], this, true);
8737        }
8738      } else {
8739        this._siblings = _register(this.target, this, true);
8740      }
8741    }
8742    Animation.prototype._enabled.call(this, enabled, ignoreTimeline);
8743    if (this._notifyPluginsOfEnabled) if (this._firstPT) {
8744      return TweenLite._onPluginEvent(enabled ? "_onEnable" : "_onDisable", this);
8745    }
8746    return false;
8747  };
8748
8749  //----TweenLite static methods -----------------------------------------------------
8750
8751  TweenLite.to = function (target, duration, vars) {
8752    return new TweenLite(target, duration, vars);
8753  };
8754  TweenLite.from = function (target, duration, vars) {
8755    vars.runBackwards = true;
8756    vars.immediateRender = vars.immediateRender != false;
8757    return new TweenLite(target, duration, vars);
8758  };
8759  TweenLite.fromTo = function (target, duration, fromVars, toVars) {
8760    toVars.startAt = fromVars;
8761    toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
8762    return new TweenLite(target, duration, toVars);
8763  };
8764  TweenLite.delayedCall = function (delay, callback, params, scope, useFrames) {
8765    return new TweenLite(callback, 0, {
8766      delay: delay,
8767      onComplete: callback,
8768      onCompleteParams: params,
8769      callbackScope: scope,
8770      onReverseComplete: callback,
8771      onReverseCompleteParams: params,
8772      immediateRender: false,
8773      lazy: false,
8774      useFrames: useFrames,
8775      overwrite: 0
8776    });
8777  };
8778  TweenLite.set = function (target, vars) {
8779    return new TweenLite(target, 0, vars);
8780  };
8781  TweenLite.getTweensOf = function (target, onlyActive) {
8782    if (target == null) {
8783      return [];
8784    }
8785    target = typeof target !== "string" ? target : TweenLite.selector(target) || target;
8786    var i, a, j, t;
8787    if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") {
8788      i = target.length;
8789      a = [];
8790      while (--i > -1) {
8791        a = a.concat(TweenLite.getTweensOf(target[i], onlyActive));
8792      }
8793      i = a.length;
8794      //now get rid of any duplicates (tweens of arrays of objects could cause duplicates)
8795      while (--i > -1) {
8796        t = a[i];
8797        j = i;
8798        while (--j > -1) {
8799          if (t === a[j]) {
8800            a.splice(i, 1);
8801          }
8802        }
8803      }
8804    } else if (target._gsTweenID) {
8805      a = _register(target).concat();
8806      i = a.length;
8807      while (--i > -1) {
8808        if (a[i]._gc || onlyActive && !a[i].isActive()) {
8809          a.splice(i, 1);
8810        }
8811      }
8812    }
8813    return a || [];
8814  };
8815  TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function (target, onlyActive, vars) {
8816    if (_typeof(onlyActive) === "object") {
8817      vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted)
8818      onlyActive = false;
8819    }
8820    var a = TweenLite.getTweensOf(target, onlyActive),
8821      i = a.length;
8822    while (--i > -1) {
8823      a[i]._kill(vars, target);
8824    }
8825  };
8826
8827  /*
8828   * ----------------------------------------------------------------
8829   * 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)
8830   * ----------------------------------------------------------------
8831   */
8832  var TweenPlugin = _class("plugins.TweenPlugin", function (props, priority) {
8833    this._overwriteProps = (props || "").split(",");
8834    this._propName = this._overwriteProps[0];
8835    this._priority = priority || 0;
8836    this._super = TweenPlugin.prototype;
8837  }, true);
8838  p = TweenPlugin.prototype;
8839  TweenPlugin.version = "1.19.0";
8840  TweenPlugin.API = 2;
8841  p._firstPT = null;
8842  p._addTween = _addPropTween;
8843  p.setRatio = _setRatio;
8844  p._kill = function (lookup) {
8845    var a = this._overwriteProps,
8846      pt = this._firstPT,
8847      i;
8848    if (lookup[this._propName] != null) {
8849      this._overwriteProps = [];
8850    } else {
8851      i = a.length;
8852      while (--i > -1) {
8853        if (lookup[a[i]] != null) {
8854          a.splice(i, 1);
8855        }
8856      }
8857    }
8858    while (pt) {
8859      if (lookup[pt.n] != null) {
8860        if (pt._next) {
8861          pt._next._prev = pt._prev;
8862        }
8863        if (pt._prev) {
8864          pt._prev._next = pt._next;
8865          pt._prev = null;
8866        } else if (this._firstPT === pt) {
8867          this._firstPT = pt._next;
8868        }
8869      }
8870      pt = pt._next;
8871    }
8872    return false;
8873  };
8874  p._mod = p._roundProps = function (lookup) {
8875    var pt = this._firstPT,
8876      val;
8877    while (pt) {
8878      val = lookup[this._propName] || pt.n != null && lookup[pt.n.split(this._propName + "_").join("")];
8879      if (val && typeof val === "function") {
8880        //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.
8881        if (pt.f === 2) {
8882          pt.t._applyPT.m = val;
8883        } else {
8884          pt.m = val;
8885        }
8886      }
8887      pt = pt._next;
8888    }
8889  };
8890  TweenLite._onPluginEvent = function (type, tween) {
8891    var pt = tween._firstPT,
8892      changed,
8893      pt2,
8894      first,
8895      last,
8896      next;
8897    if (type === "_onInitAllProps") {
8898      //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.
8899      while (pt) {
8900        next = pt._next;
8901        pt2 = first;
8902        while (pt2 && pt2.pr > pt.pr) {
8903          pt2 = pt2._next;
8904        }
8905        if (pt._prev = pt2 ? pt2._prev : last) {
8906          pt._prev._next = pt;
8907        } else {
8908          first = pt;
8909        }
8910        if (pt._next = pt2) {
8911          pt2._prev = pt;
8912        } else {
8913          last = pt;
8914        }
8915        pt = next;
8916      }
8917      pt = tween._firstPT = first;
8918    }
8919    while (pt) {
8920      if (pt.pg) if (typeof pt.t[type] === "function") if (pt.t[type]()) {
8921        changed = true;
8922      }
8923      pt = pt._next;
8924    }
8925    return changed;
8926  };
8927  TweenPlugin.activate = function (plugins) {
8928    var i = plugins.length;
8929    while (--i > -1) {
8930      if (plugins[i].API === TweenPlugin.API) {
8931        _plugins[new plugins[i]()._propName] = plugins[i];
8932      }
8933    }
8934    return true;
8935  };
8936
8937  //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.
8938  _gsDefine.plugin = function (config) {
8939    if (!config || !config.propName || !config.init || !config.API) {
8940      throw "illegal plugin definition.";
8941    }
8942    var propName = config.propName,
8943      priority = config.priority || 0,
8944      overwriteProps = config.overwriteProps,
8945      map = {
8946        init: "_onInitTween",
8947        set: "setRatio",
8948        kill: "_kill",
8949        round: "_mod",
8950        mod: "_mod",
8951        initAll: "_onInitAllProps"
8952      },
8953      Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin", function () {
8954        TweenPlugin.call(this, propName, priority);
8955        this._overwriteProps = overwriteProps || [];
8956      }, config.global === true),
8957      p = Plugin.prototype = new TweenPlugin(propName),
8958      prop;
8959    p.constructor = Plugin;
8960    Plugin.API = config.API;
8961    for (prop in map) {
8962      if (typeof config[prop] === "function") {
8963        p[map[prop]] = config[prop];
8964      }
8965    }
8966    Plugin.version = config.version;
8967    TweenPlugin.activate([Plugin]);
8968    return Plugin;
8969  };
8970
8971  //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.
8972  a = window._gsQueue;
8973  if (a) {
8974    for (i = 0; i < a.length; i++) {
8975      a[i]();
8976    }
8977    for (p in _defLookup) {
8978      if (!_defLookup[p].func) {
8979        window.console.log("GSAP encountered missing dependency: " + p);
8980      }
8981    }
8982  }
8983  _tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated
8984})(typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : void 0 || window, "TweenLite");
8985
8986}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
8987},{}],5:[function(require,module,exports){
8988(function (global){(function (){
8989"use strict";
8990
8991function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
8992/*!
8993 * VERSION: 1.20.4
8994 * DATE: 2018-02-15
8995 * UPDATES AND DOCS AT: http://greensock.com
8996 * 
8997 * Includes all of the following: TweenLite, TweenMax, TimelineLite, TimelineMax, EasePack, CSSPlugin, RoundPropsPlugin, BezierPlugin, AttrPlugin, DirectionalRotationPlugin
8998 *
8999 * @license Copyright (c) 2008-2018, GreenSock. All rights reserved.
9000 * This work is subject to the terms at http://greensock.com/standard-license or for
9001 * Club GreenSock members, the software agreement that was issued with your membership.
9002 * 
9003 * @author: Jack Doyle, [email protected]
9004 **/
9005var _gsScope = typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : void 0 || window; //helps ensure compatibility with AMD/RequireJS and CommonJS/Node
9006(_gsScope._gsQueue || (_gsScope._gsQueue = [])).push(function () {
9007  "use strict";
9008
9009  _gsScope._gsDefine("TweenMax", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) {
9010    var _slice = function _slice(a) {
9011        //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
9012        var b = [],
9013          l = a.length,
9014          i;
9015        for (i = 0; i !== l; b.push(a[i++]));
9016        return b;
9017      },
9018      _applyCycle = function _applyCycle(vars, targets, i) {
9019        var alt = vars.cycle,
9020          p,
9021          val;
9022        for (p in alt) {
9023          val = alt[p];
9024          vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length];
9025        }
9026        delete vars.cycle;
9027      },
9028      _TweenMax = function TweenMax(target, duration, vars) {
9029        TweenLite.call(this, target, duration, vars);
9030        this._cycle = 0;
9031        this._yoyo = this.vars.yoyo === true || !!this.vars.yoyoEase;
9032        this._repeat = this.vars.repeat || 0;
9033        this._repeatDelay = this.vars.repeatDelay || 0;
9034        if (this._repeat) {
9035          this._uncache(true); //ensures that if there is any repeat, the totalDuration will get recalculated to accurately report it.
9036        }
9037        this.render = _TweenMax.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
9038      },
9039      _tinyNum = 0.0000000001,
9040      TweenLiteInternals = TweenLite._internals,
9041      _isSelector = TweenLiteInternals.isSelector,
9042      _isArray = TweenLiteInternals.isArray,
9043      p = _TweenMax.prototype = TweenLite.to({}, 0.1, {}),
9044      _blankArray = [];
9045    _TweenMax.version = "1.20.4";
9046    p.constructor = _TweenMax;
9047    p.kill()._gc = false;
9048    _TweenMax.killTweensOf = _TweenMax.killDelayedCallsTo = TweenLite.killTweensOf;
9049    _TweenMax.getTweensOf = TweenLite.getTweensOf;
9050    _TweenMax.lagSmoothing = TweenLite.lagSmoothing;
9051    _TweenMax.ticker = TweenLite.ticker;
9052    _TweenMax.render = TweenLite.render;
9053    p.invalidate = function () {
9054      this._yoyo = this.vars.yoyo === true || !!this.vars.yoyoEase;
9055      this._repeat = this.vars.repeat || 0;
9056      this._repeatDelay = this.vars.repeatDelay || 0;
9057      this._yoyoEase = null;
9058      this._uncache(true);
9059      return TweenLite.prototype.invalidate.call(this);
9060    };
9061    p.updateTo = function (vars, resetDuration) {
9062      var curRatio = this.ratio,
9063        immediate = this.vars.immediateRender || vars.immediateRender,
9064        p;
9065      if (resetDuration && this._startTime < this._timeline._time) {
9066        this._startTime = this._timeline._time;
9067        this._uncache(false);
9068        if (this._gc) {
9069          this._enabled(true, false);
9070        } else {
9071          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.
9072        }
9073      }
9074      for (p in vars) {
9075        this.vars[p] = vars[p];
9076      }
9077      if (this._initted || immediate) {
9078        if (resetDuration) {
9079          this._initted = false;
9080          if (immediate) {
9081            this.render(0, true, true);
9082          }
9083        } else {
9084          if (this._gc) {
9085            this._enabled(true, false);
9086          }
9087          if (this._notifyPluginsOfEnabled && this._firstPT) {
9088            TweenLite._onPluginEvent("_onDisable", this); //in case a plugin like MotionBlur must perform some cleanup tasks
9089          }
9090          if (this._time / this._duration > 0.998) {
9091            //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. 
9092            var prevTime = this._totalTime;
9093            this.render(0, true, false);
9094            this._initted = false;
9095            this.render(prevTime, true, false);
9096          } else {
9097            this._initted = false;
9098            this._init();
9099            if (this._time > 0 || immediate) {
9100              var inv = 1 / (1 - curRatio),
9101                pt = this._firstPT,
9102                endValue;
9103              while (pt) {
9104                endValue = pt.s + pt.c;
9105                pt.c *= inv;
9106                pt.s = endValue - pt.c;
9107                pt = pt._next;
9108              }
9109            }
9110          }
9111        }
9112      }
9113      return this;
9114    };
9115    p.render = function (time, suppressEvents, force) {
9116      if (!this._initted) if (this._duration === 0 && this.vars.repeat) {
9117        //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.
9118        this.invalidate();
9119      }
9120      var totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
9121        prevTime = this._time,
9122        prevTotalTime = this._totalTime,
9123        prevCycle = this._cycle,
9124        duration = this._duration,
9125        prevRawPrevTime = this._rawPrevTime,
9126        isComplete,
9127        callback,
9128        pt,
9129        cycleDuration,
9130        r,
9131        type,
9132        pow,
9133        rawPrevTime,
9134        yoyoEase;
9135      if (time >= totalDur - 0.0000001 && time >= 0) {
9136        //to work around occasional floating point math artifacts.
9137        this._totalTime = totalDur;
9138        this._cycle = this._repeat;
9139        if (this._yoyo && (this._cycle & 1) !== 0) {
9140          this._time = 0;
9141          this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
9142        } else {
9143          this._time = duration;
9144          this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
9145        }
9146        if (!this._reversed) {
9147          isComplete = true;
9148          callback = "onComplete";
9149          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.
9150        }
9151        if (duration === 0) if (this._initted || !this.vars.lazy || force) {
9152          //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.
9153          if (this._startTime === this._timeline._duration) {
9154            //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 rounding 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.
9155            time = 0;
9156          }
9157          if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) {
9158            //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.
9159            force = true;
9160            if (prevRawPrevTime > _tinyNum) {
9161              callback = "onReverseComplete";
9162            }
9163          }
9164          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.
9165        }
9166      } else if (time < 0.0000001) {
9167        //to work around occasional floating point math artifacts, round super small values to 0.
9168        this._totalTime = this._time = this._cycle = 0;
9169        this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
9170        if (prevTotalTime !== 0 || duration === 0 && prevRawPrevTime > 0) {
9171          callback = "onReverseComplete";
9172          isComplete = this._reversed;
9173        }
9174        if (time < 0) {
9175          this._active = false;
9176          if (duration === 0) if (this._initted || !this.vars.lazy || force) {
9177            //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.
9178            if (prevRawPrevTime >= 0) {
9179              force = true;
9180            }
9181            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.
9182          }
9183        }
9184        if (!this._initted) {
9185          //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.
9186          force = true;
9187        }
9188      } else {
9189        this._totalTime = this._time = time;
9190        if (this._repeat !== 0) {
9191          cycleDuration = duration + this._repeatDelay;
9192          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!)
9193          if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
9194            this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
9195          }
9196          this._time = this._totalTime - this._cycle * cycleDuration;
9197          if (this._yoyo) if ((this._cycle & 1) !== 0) {
9198            this._time = duration - this._time;
9199            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.
9200            if (yoyoEase) {
9201              if (!this._yoyoEase) {
9202                if (yoyoEase === true && !this._initted) {
9203                  //if it's not initted and yoyoEase is true, this._ease won't have been populated yet so we must discern it here.
9204                  yoyoEase = this.vars.ease;
9205                  this._yoyoEase = yoyoEase = !yoyoEase ? TweenLite.defaultEase : yoyoEase instanceof Ease ? yoyoEase : typeof yoyoEase === "function" ? new Ease(yoyoEase, this.vars.easeParams) : Ease.map[yoyoEase] || TweenLite.defaultEase;
9206                } else {
9207                  this._yoyoEase = yoyoEase = yoyoEase === true ? this._ease : yoyoEase instanceof Ease ? yoyoEase : Ease.map[yoyoEase];
9208                }
9209              }
9210              this.ratio = yoyoEase ? 1 - yoyoEase.getRatio((duration - this._time) / duration) : 0;
9211            }
9212          }
9213          if (this._time > duration) {
9214            this._time = duration;
9215          } else if (this._time < 0) {
9216            this._time = 0;
9217          }
9218        }
9219        if (this._easeType && !yoyoEase) {
9220          r = this._time / duration;
9221          type = this._easeType;
9222          pow = this._easePower;
9223          if (type === 1 || type === 3 && r >= 0.5) {
9224            r = 1 - r;
9225          }
9226          if (type === 3) {
9227            r *= 2;
9228          }
9229          if (pow === 1) {
9230            r *= r;
9231          } else if (pow === 2) {
9232            r *= r * r;
9233          } else if (pow === 3) {
9234            r *= r * r * r;
9235          } else if (pow === 4) {
9236            r *= r * r * r * r;
9237          }
9238          if (type === 1) {
9239            this.ratio = 1 - r;
9240          } else if (type === 2) {
9241            this.ratio = r;
9242          } else if (this._time / duration < 0.5) {
9243            this.ratio = r / 2;
9244          } else {
9245            this.ratio = 1 - r / 2;
9246          }
9247        } else if (!yoyoEase) {
9248          this.ratio = this._ease.getRatio(this._time / duration);
9249        }
9250      }
9251      if (prevTime === this._time && !force && prevCycle === this._cycle) {
9252        if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) {
9253          //so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
9254          this._callback("onUpdate");
9255        }
9256        return;
9257      } else if (!this._initted) {
9258        this._init();
9259        if (!this._initted || this._gc) {
9260          //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.
9261          return;
9262        } else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) {
9263          //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.
9264          this._time = prevTime;
9265          this._totalTime = prevTotalTime;
9266          this._rawPrevTime = prevRawPrevTime;
9267          this._cycle = prevCycle;
9268          TweenLiteInternals.lazyTweens.push(this);
9269          this._lazy = [time, suppressEvents];
9270          return;
9271        }
9272        //_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.
9273        if (this._time && !isComplete && !yoyoEase) {
9274          this.ratio = this._ease.getRatio(this._time / duration);
9275        } else if (isComplete && this._ease._calcEnd && !yoyoEase) {
9276          this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1);
9277        }
9278      }
9279      if (this._lazy !== false) {
9280        this._lazy = false;
9281      }
9282      if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
9283        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.
9284      }
9285      if (prevTotalTime === 0) {
9286        if (this._initted === 2 && time > 0) {
9287          //this.invalidate();
9288          this._init(); //will just apply overwriting since _initted of (2) means it was a from() tween that had immediateRender:true
9289        }
9290        if (this._startAt) {
9291          if (time >= 0) {
9292            this._startAt.render(time, true, force);
9293          } else if (!callback) {
9294            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.
9295          }
9296        }
9297        if (this.vars.onStart) if (this._totalTime !== 0 || duration === 0) if (!suppressEvents) {
9298          this._callback("onStart");
9299        }
9300      }
9301      pt = this._firstPT;
9302      while (pt) {
9303        if (pt.f) {
9304          pt.t[pt.p](pt.c * this.ratio + pt.s);
9305        } else {
9306          pt.t[pt.p] = pt.c * this.ratio + pt.s;
9307        }
9308        pt = pt._next;
9309      }
9310      if (this._onUpdate) {
9311        if (time < 0) if (this._startAt && this._startTime) {
9312          //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.
9313          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.
9314        }
9315        if (!suppressEvents) if (this._totalTime !== prevTotalTime || callback) {
9316          this._callback("onUpdate");
9317        }
9318      }
9319      if (this._cycle !== prevCycle) if (!suppressEvents) if (!this._gc) if (this.vars.onRepeat) {
9320        this._callback("onRepeat");
9321      }
9322      if (callback) if (!this._gc || force) {
9323        //check gc because there's a chance that kill() could be called in an onUpdate
9324        if (time < 0 && this._startAt && !this._onUpdate && this._startTime) {
9325          //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.
9326          this._startAt.render(time, true, force);
9327        }
9328        if (isComplete) {
9329          if (this._timeline.autoRemoveChildren) {
9330            this._enabled(false, false);
9331          }
9332          this._active = false;
9333        }
9334        if (!suppressEvents && this.vars[callback]) {
9335          this._callback(callback);
9336        }
9337        if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) {
9338          //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
9338nario, but possible nonetheless.
9339          this._rawPrevTime = 0;
9340        }
9341      }
9342    };
9343
9344    //---- STATIC FUNCTIONS -----------------------------------------------------------------------------------------------------------
9345
9346    _TweenMax.to = function (target, duration, vars) {
9347      return new _TweenMax(target, duration, vars);
9348    };
9349    _TweenMax.from = function (target, duration, vars) {
9350      vars.runBackwards = true;
9351      vars.immediateRender = vars.immediateRender != false;
9352      return new _TweenMax(target, duration, vars);
9353    };
9354    _TweenMax.fromTo = function (target, duration, fromVars, toVars) {
9355      toVars.startAt = fromVars;
9356      toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
9357      return new _TweenMax(target, duration, toVars);
9358    };
9359    _TweenMax.staggerTo = _TweenMax.allTo = function (targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
9360      stagger = stagger || 0;
9361      var delay = 0,
9362        a = [],
9363        finalComplete = function finalComplete() {
9364          if (vars.onComplete) {
9365            vars.onComplete.apply(vars.onCompleteScope || this, arguments);
9366          }
9367          onCompleteAll.apply(onCompleteAllScope || vars.callbackScope || this, onCompleteAllParams || _blankArray);
9368        },
9369        cycle = vars.cycle,
9370        fromCycle = vars.startAt && vars.startAt.cycle,
9371        l,
9372        copy,
9373        i,
9374        p;
9375      if (!_isArray(targets)) {
9376        if (typeof targets === "string") {
9377          targets = TweenLite.selector(targets) || targets;
9378        }
9379        if (_isSelector(targets)) {
9380          targets = _slice(targets);
9381        }
9382      }
9383      targets = targets || [];
9384      if (stagger < 0) {
9385        targets = _slice(targets);
9386        targets.reverse();
9387        stagger *= -1;
9388      }
9389      l = targets.length - 1;
9390      for (i = 0; i <= l; i++) {
9391        copy = {};
9392        for (p in vars) {
9393          copy[p] = vars[p];
9394        }
9395        if (cycle) {
9396          _applyCycle(copy, targets, i);
9397          if (copy.duration != null) {
9398            duration = copy.duration;
9399            delete copy.duration;
9400          }
9401        }
9402        if (fromCycle) {
9403          fromCycle = copy.startAt = {};
9404          for (p in vars.startAt) {
9405            fromCycle[p] = vars.startAt[p];
9406          }
9407          _applyCycle(copy.startAt, targets, i);
9408        }
9409        copy.delay = delay + (copy.delay || 0);
9410        if (i === l && onCompleteAll) {
9411          copy.onComplete = finalComplete;
9412        }
9413        a[i] = new _TweenMax(targets[i], duration, copy);
9414        delay += stagger;
9415      }
9416      return a;
9417    };
9418    _TweenMax.staggerFrom = _TweenMax.allFrom = function (targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
9419      vars.runBackwards = true;
9420      vars.immediateRender = vars.immediateRender != false;
9421      return _TweenMax.staggerTo(targets, duration, vars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
9422    };
9423    _TweenMax.staggerFromTo = _TweenMax.allFromTo = function (targets, duration, fromVars, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
9424      toVars.startAt = fromVars;
9425      toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
9426      return _TweenMax.staggerTo(targets, duration, toVars, stagger, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
9427    };
9428    _TweenMax.delayedCall = function (delay, callback, params, scope, useFrames) {
9429      return new _TweenMax(callback, 0, {
9430        delay: delay,
9431        onComplete: callback,
9432        onCompleteParams: params,
9433        callbackScope: scope,
9434        onReverseComplete: callback,
9435        onReverseCompleteParams: params,
9436        immediateRender: false,
9437        useFrames: useFrames,
9438        overwrite: 0
9439      });
9440    };
9441    _TweenMax.set = function (target, vars) {
9442      return new _TweenMax(target, 0, vars);
9443    };
9444    _TweenMax.isTweening = function (target) {
9445      return TweenLite.getTweensOf(target, true).length > 0;
9446    };
9447    var _getChildrenOf2 = function _getChildrenOf(timeline, includeTimelines) {
9448        var a = [],
9449          cnt = 0,
9450          tween = timeline._first;
9451        while (tween) {
9452          if (tween instanceof TweenLite) {
9453            a[cnt++] = tween;
9454          } else {
9455            if (includeTimelines) {
9456              a[cnt++] = tween;
9457            }
9458            a = a.concat(_getChildrenOf2(tween, includeTimelines));
9459            cnt = a.length;
9460          }
9461          tween = tween._next;
9462        }
9463        return a;
9464      },
9465      getAllTweens = _TweenMax.getAllTweens = function (includeTimelines) {
9466        return _getChildrenOf2(Animation._rootTimeline, includeTimelines).concat(_getChildrenOf2(Animation._rootFramesTimeline, includeTimelines));
9467      };
9468    _TweenMax.killAll = function (complete, tweens, delayedCalls, timelines) {
9469      if (tweens == null) {
9470        tweens = true;
9471      }
9472      if (delayedCalls == null) {
9473        delayedCalls = true;
9474      }
9475      var a = getAllTweens(timelines != false),
9476        l = a.length,
9477        allTrue = tweens && delayedCalls && timelines,
9478        isDC,
9479        tween,
9480        i;
9481      for (i = 0; i < l; i++) {
9482        tween = a[i];
9483        if (allTrue || tween instanceof SimpleTimeline || (isDC = tween.target === tween.vars.onComplete) && delayedCalls || tweens && !isDC) {
9484          if (complete) {
9485            tween.totalTime(tween._reversed ? 0 : tween.totalDuration());
9486          } else {
9487            tween._enabled(false, false);
9488          }
9489        }
9490      }
9491    };
9492    _TweenMax.killChildTweensOf = function (parent, complete) {
9493      if (parent == null) {
9494        return;
9495      }
9496      var tl = TweenLiteInternals.tweenLookup,
9497        a,
9498        curParent,
9499        p,
9500        i,
9501        l;
9502      if (typeof parent === "string") {
9503        parent = TweenLite.selector(parent) || parent;
9504      }
9505      if (_isSelector(parent)) {
9506        parent = _slice(parent);
9507      }
9508      if (_isArray(parent)) {
9509        i = parent.length;
9510        while (--i > -1) {
9511          _TweenMax.killChildTweensOf(parent[i], complete);
9512        }
9513        return;
9514      }
9515      a = [];
9516      for (p in tl) {
9517        curParent = tl[p].target.parentNode;
9518        while (curParent) {
9519          if (curParent === parent) {
9520            a = a.concat(tl[p].tweens);
9521          }
9522          curParent = curParent.parentNode;
9523        }
9524      }
9525      l = a.length;
9526      for (i = 0; i < l; i++) {
9527        if (complete) {
9528          a[i].totalTime(a[i].totalDuration());
9529        }
9530        a[i]._enabled(false, false);
9531      }
9532    };
9533    var _changePause = function _changePause(pause, tweens, delayedCalls, timelines) {
9534      tweens = tweens !== false;
9535      delayedCalls = delayedCalls !== false;
9536      timelines = timelines !== false;
9537      var a = getAllTweens(timelines),
9538        allTrue = tweens && delayedCalls && timelines,
9539        i = a.length,
9540        isDC,
9541        tween;
9542      while (--i > -1) {
9543        tween = a[i];
9544        if (allTrue || tween instanceof SimpleTimeline || (isDC = tween.target === tween.vars.onComplete) && delayedCalls || tweens && !isDC) {
9545          tween.paused(pause);
9546        }
9547      }
9548    };
9549    _TweenMax.pauseAll = function (tweens, delayedCalls, timelines) {
9550      _changePause(true, tweens, delayedCalls, timelines);
9551    };
9552    _TweenMax.resumeAll = function (tweens, delayedCalls, timelines) {
9553      _changePause(false, tweens, delayedCalls, timelines);
9554    };
9555    _TweenMax.globalTimeScale = function (value) {
9556      var tl = Animation._rootTimeline,
9557        t = TweenLite.ticker.time;
9558      if (!arguments.length) {
9559        return tl._timeScale;
9560      }
9561      value = value || _tinyNum; //can't allow zero because it'll throw the math off
9562      tl._startTime = t - (t - tl._startTime) * tl._timeScale / value;
9563      tl = Animation._rootFramesTimeline;
9564      t = TweenLite.ticker.frame;
9565      tl._startTime = t - (t - tl._startTime) * tl._timeScale / value;
9566      tl._timeScale = Animation._rootTimeline._timeScale = value;
9567      return value;
9568    };
9569
9570    //---- GETTERS / SETTERS ----------------------------------------------------------------------------------------------------------
9571
9572    p.progress = function (value, suppressEvents) {
9573      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);
9574    };
9575    p.totalProgress = function (value, suppressEvents) {
9576      return !arguments.length ? this._totalTime / this.totalDuration() : this.totalTime(this.totalDuration() * value, suppressEvents);
9577    };
9578    p.time = function (value, suppressEvents) {
9579      if (!arguments.length) {
9580        return this._time;
9581      }
9582      if (this._dirty) {
9583        this.totalDuration();
9584      }
9585      if (value > this._duration) {
9586        value = this._duration;
9587      }
9588      if (this._yoyo && (this._cycle & 1) !== 0) {
9589        value = this._duration - value + this._cycle * (this._duration + this._repeatDelay);
9590      } else if (this._repeat !== 0) {
9591        value += this._cycle * (this._duration + this._repeatDelay);
9592      }
9593      return this.totalTime(value, suppressEvents);
9594    };
9595    p.duration = function (value) {
9596      if (!arguments.length) {
9597        return this._duration; //don't set _dirty = false because there could be repeats that haven't been factored 
9597into 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.
9598      }
9599      return Animation.prototype.duration.call(this, value);
9600    };
9601    p.totalDuration = function (value) {
9602      if (!arguments.length) {
9603        if (this._dirty) {
9604          //instead of Infinity, we use 999999999999 so that we can accommodate reverses
9605          this._totalDuration = this._repeat === -1 ? 999999999999 : this._duration * (this._repeat + 1) + this._repeatDelay * this._repeat;
9606          this._dirty = false;
9607        }
9608        return this._totalDuration;
9609      }
9610      return this._repeat === -1 ? this : this.duration((value - this._repeat * this._repeatDelay) / (this._repeat + 1));
9611    };
9612    p.repeat = function (value) {
9613      if (!arguments.length) {
9614        return this._repeat;
9615      }
9616      this._repeat = value;
9617      return this._uncache(true);
9618    };
9619    p.repeatDelay = function (value) {
9620      if (!arguments.length) {
9621        return this._repeatDelay;
9622      }
9623      this._repeatDelay = value;
9624      return this._uncache(true);
9625    };
9626    p.yoyo = function (value) {
9627      if (!arguments.length) {
9628        return this._yoyo;
9629      }
9630      this._yoyo = value;
9631      return this;
9632    };
9633    return _TweenMax;
9634  }, true);
9635
9636  /*
9637   * ----------------------------------------------------------------
9638   * TimelineLite
9639   * ----------------------------------------------------------------
9640   */
9641  _gsScope._gsDefine("TimelineLite", ["core.Animation", "core.SimpleTimeline", "TweenLite"], function (Animation, SimpleTimeline, TweenLite) {
9642    var TimelineLite = function TimelineLite(vars) {
9643        SimpleTimeline.call(this, vars);
9644        this._labels = {};
9645        this.autoRemoveChildren = this.vars.autoRemoveChildren === true;
9646        this.smoothChildTiming = this.vars.smoothChildTiming === true;
9647        this._sortChildren = true;
9648        this._onUpdate = this.vars.onUpdate;
9649        var v = this.vars,
9650          val,
9651          p;
9652        for (p in v) {
9653          val = v[p];
9654          if (_isArray(val)) if (val.join("").indexOf("{self}") !== -1) {
9655            v[p] = this._swapSelfInParams(val);
9656          }
9657        }
9658        if (_isArray(v.tweens)) {
9659          this.add(v.tweens, 0, v.align, v.stagger);
9660        }
9661      },
9662      _tinyNum = 0.0000000001,
9663      TweenLiteInternals = TweenLite._internals,
9664      _internals = TimelineLite._internals = {},
9665      _isSelector = TweenLiteInternals.isSelector,
9666      _isArray = TweenLiteInternals.isArray,
9667      _lazyTweens = TweenLiteInternals.lazyTweens,
9668      _lazyRender = TweenLiteInternals.lazyRender,
9669      _globals = _gsScope._gsDefine.globals,
9670      _copy = function _copy(vars) {
9671        var copy = {},
9672          p;
9673        for (p in vars) {
9674          copy[p] = vars[p];
9675        }
9676        return copy;
9677      },
9678      _applyCycle = function _applyCycle(vars, targets, i) {
9679        var alt = vars.cycle,
9680          p,
9681          val;
9682        for (p in alt) {
9683          val = alt[p];
9684          vars[p] = typeof val === "function" ? val(i, targets[i]) : val[i % val.length];
9685        }
9686        delete vars.cycle;
9687      },
9688      _pauseCallback = _internals.pauseCallback = function () {},
9689      _slice = function _slice(a) {
9690        //don't use [].slice because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
9691        var b = [],
9692          l = a.length,
9693          i;
9694        for (i = 0; i !== l; b.push(a[i++]));
9695        return b;
9696      },
9697      p = TimelineLite.prototype = new SimpleTimeline();
9698    TimelineLite.version = "1.20.4";
9699    p.constructor = TimelineLite;
9700    p.kill()._gc = p._forcingPlayhead = p._hasPause = false;
9701
9702    /* might use later...
9703    //translates a local time inside an animation to the corresponding time on the root/global timeline, factoring in all nesting and timeScales.
9704    function localToGlobal(time, animation) {
9705    	while (animation) {
9706    		time = (time / animation._timeScale) + animation._startTime;
9707    		animation = animation.timeline;
9708    	}
9709    	return time;
9710    }
9711    	//translates the supplied time on the root/global timeline into the corresponding local time inside a particular animation, factoring in all nesting and timeScales
9712    function globalToLocal(time, animation) {
9713    	var scale = 1;
9714    	time -= localToGlobal(0, animation);
9715    	while (animation) {
9716    		scale *= animation._timeScale;
9717    		animation = animation.timeline;
9718    	}
9719    	return time * scale;
9720    }
9721    */
9722
9723    p.to = function (target, duration, vars, position) {
9724      var Engine = vars.repeat && _globals.TweenMax || TweenLite;
9725      return duration ? this.add(new Engine(target, duration, vars), position) : this.set(target, vars, position);
9726    };
9727    p.from = function (target, duration, vars, position) {
9728      return this.add((vars.repeat && _globals.TweenMax || TweenLite).from(target, duration, vars), position);
9729    };
9730    p.fromTo = function (target, duration, fromVars, toVars, position) {
9731      var Engine = toVars.repeat && _globals.TweenMax || TweenLite;
9732      return duration ? this.add(Engine.fromTo(target, duration, fromVars, toVars), position) : this.set(target, toVars, position);
9733    };
9734    p.staggerTo = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
9735      var tl = new TimelineLite({
9736          onComplete: onCompleteAll,
9737          onCompleteParams: onCompleteAllParams,
9738          callbackScope: onCompleteAllScope,
9739          smoothChildTiming: this.smoothChildTiming
9740        }),
9741        cycle = vars.cycle,
9742        copy,
9743        i;
9744      if (typeof targets === "string") {
9745        targets = TweenLite.selector(targets) || targets;
9746      }
9747      targets = targets || [];
9748      if (_isSelector(targets)) {
9749        //senses if the targets object is a selector. If it is, we should translate it into an array.
9750        targets = _slice(targets);
9751      }
9752      stagger = stagger || 0;
9753      if (stagger < 0) {
9754        targets = _slice(targets);
9755        targets.reverse();
9756        stagger *= -1;
9757      }
9758      for (i = 0; i < targets.length; i++) {
9759        copy = _copy(vars);
9760        if (copy.startAt) {
9761          copy.startAt = _copy(copy.startAt);
9762          if (copy.startAt.cycle) {
9763            _applyCycle(copy.startAt, targets, i);
9764          }
9765        }
9766        if (cycle) {
9767          _applyCycle(copy, targets, i);
9768          if (copy.duration != null) {
9769            duration = copy.duration;
9770            delete copy.duration;
9771          }
9772        }
9773        tl.to(targets[i], duration, copy, i * stagger);
9774      }
9775      return this.add(tl, position);
9776    };
9777    p.staggerFrom = function (targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
9778      vars.immediateRender = vars.immediateRender != false;
9779      vars.runBackwards = true;
9780      return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
9781    };
9782    p.staggerFromTo = function (targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope) {
9783      toVars.startAt = fromVars;
9784      toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
9785      return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams, onCompleteAllScope);
9786    };
9787    p.call = function (callback, params, scope, position) {
9788      return this.add(TweenLite.delayedCall(0, callback, params, scope), position);
9789    };
9790    p.set = function (target, vars, position) {
9791      position = this._parseTimeOrLabel(position, 0, true);
9792      if (vars.immediateRender == null) {
9793        vars.immediateRender = position === this._time && !this._paused;
9794      }
9795      return this.add(new TweenLite(target, 0, vars), position);
9796    };
9797    TimelineLite.exportRoot = function (vars, ignoreDelayedCalls) {
9798      vars = vars || {};
9799      if (vars.smoothChildTiming == null) {
9800        vars.smoothChildTiming = true;
9801      }
9802      var tl = new TimelineLite(vars),
9803        root = tl._timeline,
9804        hasNegativeStart,
9805        time,
9806        tween,
9807        next;
9808      if (ignoreDelayedCalls == null) {
9809        ignoreDelayedCalls = true;
9810      }
9811      root._remove(tl, true);
9812      tl._startTime = 0;
9813      tl._rawPrevTime = tl._time = tl._totalTime = root._time;
9814      tween = root._first;
9815      while (tween) {
9816        next = tween._next;
9817        if (!ignoreDelayedCalls || !(tween instanceof TweenLite && tween.target === tween.vars.onComplete)) {
9818          time = tween._startTime - tween._delay;
9819          if (time < 0) {
9820            hasNegativeStart = 1;
9821          }
9822          tl.add(tween, time);
9823        }
9824        tween = next;
9825      }
9826      root.add(tl, 0);
9827      if (hasNegativeStart) {
9828        //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.
9829        tl.totalDuration();
9830      }
9831      return tl;
9832    };
9833    p.add = function (value, position, align, stagger) {
9834      var curTime, l, i, child, tl, beforeRawTime;
9835      if (typeof position !== "number") {
9836        position = this._parseTimeOrLabel(position, 0, true, value);
9837      }
9838      if (!(value instanceof Animation)) {
9839        if (value instanceof Array || value && value.push && _isArray(value)) {
9840          align = align || "normal";
9841          stagger = stagger || 0;
9842          curTime = position;
9843          l = value.length;
9844          for (i = 0; i < l; i++) {
9845            if (_isArray(child = value[i])) {
9846              child = new TimelineLite({
9847                tweens: child
9848              });
9849            }
9850            this.add(child, curTime);
9851            if (typeof child !== "string" && typeof child !== "function") {
9852              if (align === "sequence") {
9853                curTime = child._startTime + child.totalDuration() / child._timeScale;
9854              } else if (align === "start") {
9855                child._startTime -= child.delay();
9856              }
9857            }
9858            curTime += stagger;
9859          }
9860          return this._uncache(true);
9861        } else if (typeof value === "string") {
9862          return this.addLabel(value, position);
9863        } else if (typeof value === "function") {
9864          value = TweenLite.delayedCall(0, value);
9865        } else {
9866          throw "Cannot add " + value + " into the timeline; it is not a tween, timeline, function, or string.";
9867        }
9868      }
9869      SimpleTimeline.prototype.add.call(this, value, position);
9870      if (value._time) {
9871        //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.
9872        value.render((this.rawTime() - value._startTime) * value._timeScale, false, false);
9873      }
9874
9875      //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.
9876      if (this._gc || this._time === this._duration) if (!this._paused) if (this._duration < this.duration()) {
9877        //in case any of the ancestors had completed but should now be enabled...
9878        tl = this;
9879        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.
9880        while (tl._timeline) {
9881          if (beforeRawTime && tl._timeline.smoothChildTiming) {
9882            tl.totalTime(tl._totalTime, true); //moves the timeline (shifts its startTime) if necessary, and also enables it.
9883          } else if (tl._gc) {
9884            tl._enabled(true, false);
9885          }
9886          tl = tl._timeline;
9887        }
9888      }
9889      return this;
9890    };
9891    p.remove = function (value) {
9892      if (value instanceof Animation) {
9893        this._remove(value, false);
9894        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.
9895        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.
9896        return this;
9897      } else if (value instanceof Array || value && value.push && _isArray(value)) {
9898        var i = value.length;
9899        while (--i > -1) {
9900          this.remove(value[i]);
9901        }
9902        return this;
9903      } else if (typeof value === "string") {
9904        return this.removeLabel(value);
9905      }
9906      return this.kill(null, value);
9907    };
9908    p._remove = function (tween, skipDisable) {
9909      SimpleTimeline.prototype._remove.call(this, tween, skipDisable);
9910      var last = this._last;
9911      if (!last) {
9912        this._time = this._totalTime = this._duration = this._totalDuration = 0;
9913      } else if (this._time > this.duration()) {
9914        this._time = this._duration;
9915        this._totalTime = this._totalDuration;
9916      }
9917      return this;
9918    };
9919    p.append = function (value, offsetOrLabel) {
9920      return this.add(value, this._parseTimeOrLabel(null, offsetOrLabel, true, value));
9921    };
9922    p.insert = p.insertMultiple = function (value, position, align, stagger) {
9923      return this.add(value, position || 0, align, stagger);
9924    };
9925    p.appendMultiple = function (tweens, offsetOrLabel, align, stagger) {
9926      return this.add(tweens, this._parseTimeOrLabel(null, offsetOrLabel, true, tweens), align, stagger);
9927    };
9928    p.addLabel = function (label, position) {
9929      this._labels[label] = this._parseTimeOrLabel(position);
9930      return this;
9931    };
9932    p.addPause = function (position, callback, params, scope) {
9933      var t = TweenLite.delayedCall(0, _pauseCallback, params, scope || this);
9934      t.vars.onComplete = t.vars.onReverseComplete = callback;
9935      t.data = "isPause";
9936      this._hasPause = true;
9937      return this.add(t, position);
9938    };
9939    p.removeLabel = function (label) {
9940      delete this._labels[label];
9941      return this;
9942    };
9943    p.getLabelTime = function (label) {
9944      return this._labels[label] != null ? this._labels[label] : -1;
9945    };
9946    p._parseTimeOrLabel = function (timeOrLabel, offsetOrLabel, appendIfAbsent, ignore) {
9947      var clippedDuration, i;
9948      //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().
9949      if (ignore instanceof Animation && ignore.timeline === this) {
9950        this.remove(ignore);
9951      } else if (ignore && (ignore instanceof Array || ignore.push && _isArray(ignore))) {
9952        i = ignore.length;
9953        while (--i > -1) {
9954          if (ignore[i] instanceof Animation && ignore[i].timeline === this) {
9955            this.remove(ignore[i]);
9956          }
9957        }
9958      }
9959      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.
9960      if (typeof offsetOrLabel === "string") {
9961        return this._parseTimeOrLabel(offsetOrLabel, appendIfAbsent && typeof timeOrLabel === "number" && this._labels[offsetOrLabel] == null ? timeOrLabel - clippedDuration : 0, appendIfAbsent);
9962      }
9963      offsetOrLabel = offsetOrLabel || 0;
9964      if (typeof timeOrLabel === "string" && (isNaN(timeOrLabel) || this._labels[timeOrLabel] != null)) {
9965        //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).
9966        i = timeOrLabel.indexOf("=");
9967        if (i === -1) {
9968          if (this._labels[timeOrLabel] == null) {
9969            return appendIfAbsent ? this._labels[timeOrLabel] = clippedDuration + offsetOrLabel : offsetOrLabel;
9970          }
9971          return this._labels[timeOrLabel] + offsetOrLabel;
9972        }
9973        offsetOrLabel = parseInt(timeOrLabel.charAt(i - 1) + "1", 10) * Number(timeOrLabel.substr(i + 1));
9974        timeOrLabel = i > 1 ? this._parseTimeOrLabel(timeOrLabel.substr(0, i - 1), 0, appendIfAbsent) : clippedDuration;
9975      } else if (timeOrLabel == null) {
9976        timeOrLabel = clippedDuration;
9977      }
9978      return Number(timeOrLabel) + offsetOrLabel;
9979    };
9980    p.seek = function (position, suppressEvents) {
9981      return this.totalTime(typeof position === "number" ? position : this._parseTimeOrLabel(position), suppressEvents !== false);
9982    };
9983    p.stop = function () {
9984      return this.paused(true);
9985    };
9986    p.gotoAndPlay = function (position, suppressEvents) {
9987      return this.play(position, suppressEvents);
9988    };
9989    p.gotoAndStop = function (position, suppressEvents) {
9990      return this.pause(position, suppressEvents);
9991    };
9992    p.render = function (time, suppressEvents, force) {
9993      if (this._gc) {
9994        this._enabled(true, false);
9995      }
9996      var prevTime = this._time,
9997        totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
9998        prevStart = this._startTime,
9999        prevTimeScale = this._timeScale,
10000        prevPaused = this._paused,
10001        tween,
10002        isComplete,
10003        next,
10004        callback,
10005        internalForce,
10006        pauseTween,
10007        curTime;
10008      if (prevTime !== this._time) {
10009        //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).
10010        time += this._time - prevTime;
10011      }
10012      if (time >= totalDur - 0.0000001 && time >= 0) {
10013        //to work around occasional floating point math artifacts.
10014        this._totalTime = this._time = totalDur;
10015        if (!this._reversed) if (!this._hasPausedChild()) {
10016          isComplete = true;
10017          callback = "onComplete";
10018          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.
10019          if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || this._rawPrevTime < 0 || this._rawPrevTime === _tinyNum) if (this._rawPrevTime !== time && this._first) {
10020            internalForce = true;
10021            if (this._rawPrevTime > _tinyNum) {
10022              callback = "onReverseComplete";
10023            }
10024          }
10025        }
10026        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.
10027        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.
10028      } else if (time < 0.0000001) {
10029        //to work around occasional floating point math artifacts, round super small values to 0.
10030        this._totalTime = this._time = 0;
10031        if (prevTime !== 0 || this._duration === 0 && this._rawPrevTime !== _tinyNum && (this._rawPrevTime > 0 || time < 0 && this._rawPrevTime >= 0)) {
10032          callback = "onReverseComplete";
10033          isComplete = this._reversed;
10034        }
10035        if (time < 0) {
10036          this._active = false;
10037          if (this._timeline.autoRemoveChildren && this._reversed) {
10038            //ensures proper GC if a timeline is resumed after it's finished reversing.
10039            internalForce = isComplete = true;
10040            callback = "onReverseComplete";
10041          } else if (this._rawPrevTime >= 0 && this._first) {
10042            //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.
10043            internalForce = true;
10044          }
10045          this._rawPrevTime = time;
10046        } else {
10047          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.
10048          if (time === 0 && isComplete) {
10049            //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).
10050            tween = this._first;
10051            while (tween && tween._startTime === 0) {
10052              if (!tween._duration) {
10053                isComplete = false;
10054              }
10055              tween = tween._next;
10056            }
10057          }
10058          time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
10059          if (!this._initted) {
10060            internalForce = true;
10061          }
10062        }
10063      } else {
10064        if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
10065          if (time >= prevTime) {
10066            tween = this._first;
10067            while (tween && tween._startTime <= time && !pauseTween) {
10068              if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
10069                pauseTween = tween;
10070              }
10071              tween = tween._next;
10072            }
10073          } else {
10074            tween = this._last;
10075            while (tween && tween._startTime >= time && !pauseTween) {
10076              if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
10077                pauseTween = tween;
10078              }
10079              tween = tween._prev;
10080            }
10081          }
10082          if (pauseTween) {
10083            this._time = time = pauseTween._startTime;
10084            this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay);
10085          }
10086        }
10087        this._totalTime = this._time = this._rawPrevTime = time;
10088      }
10089      if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
10090        return;
10091      } else if (!this._initted) {
10092        this._initted = true;
10093      }
10094      if (!this._active) if (!this._paused && this._time !== prevTime && time > 0) {
10095        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.
10096      }
10097      if (prevTime === 0) if (this.vars.onStart) if (this._time !== 0 || !this._duration) if (!suppressEvents) {
10098        this._callback("onStart");
10099      }
10100      curTime = this._time;
10101      if (curTime >= prevTime) {
10102        tween = this._first;
10103        while (tween) {
10104          next = tween._next; //record it here because the value could change after rendering...
10105          if (curTime !== this._time || this._paused && !prevPaused) {
10106            //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
10107            break;
10108          } else if (tween._active || tween._startTime <= curTime && !tween._paused && !tween._gc) {
10109            if (pauseTween === tween) {
10110              this.pause();
10111            }
10112            if (!tween._reversed) {
10113              tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
10114            } else {
10115              tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
10116            }
10117          }
10118          tween = next;
10119        }
10120      } else {
10121        tween = this._last;
10122        while (tween) {
10123          next = tween._prev; //record it here because the value could change after rendering...
10124          if (curTime !== this._time || this._paused && !prevPaused) {
10125            //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
10126            break;
10127          } else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) {
10128            if (pauseTween === tween) {
10129              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.
10130              while (pauseTween && pauseTween.endTime() > this._time) {
10131                pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force);
10132                pauseTween = pauseTween._prev;
10133              }
10134              pauseTween = null;
10135              this.pause();
10136            }
10137            if (!tween._reversed) {
10138              tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
10139            } else {
10140              tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
10141            }
10142          }
10143          tween = next;
10144        }
10145      }
10146      if (this._onUpdate) if (!suppressEvents) {
10147        if (_lazyTweens.length) {
10148          //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.
10149          _lazyRender();
10150        }
10151        this._callback("onUpdate");
10152      }
10153      if (callback) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) {
10154        //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
10155        if (isComplete) {
10156          if (_lazyTweens.length) {
10157            //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.
10158            _lazyRender();
10159          }
10160          if (this._timeline.autoRemoveChildren) {
10161            this._enabled(false, false);
10162          }
10163          this._active = false;
10164        }
10165        if (!suppressEvents && this.vars[callback]) {
10166          this._callback(callback);
10167        }
10168      }
10169    };
10170    p._hasPausedChild = function () {
10171      var tween = this._first;
10172      while (tween) {
10173        if (tween._paused || tween instanceof TimelineLite && tween._hasPausedChild()) {
10174          return true;
10175        }
10176        tween = tween._next;
10177      }
10178      return false;
10179    };
10180    p.getChildren = function (nested, tweens, timelines, ignoreBeforeTime) {
10181      ignoreBeforeTime = ignoreBeforeTime || -9999999999;
10182      var a = [],
10183        tween = this._first,
10184        cnt = 0;
10185      while (tween) {
10186        if (tween._startTime < ignoreBeforeTime) {
10187          //do nothing
10188        } else if (tween instanceof TweenLite) {
10189          if (tweens !== false) {
10190            a[cnt++] = tween;
10191          }
10192        } else {
10193          if (timelines !== false) {
10194            a[cnt++] = tween;
10195          }
10196          if (nested !== false) {
10197            a = a.concat(tween.getChildren(true, tweens, timelines));
10198            cnt = a.length;
10199          }
10200        }
10201        tween = tween._next;
10202      }
10203      return a;
10204    };
10205    p.getTweensOf = function (target, nested) {
10206      var disabled = this._gc,
10207        a = [],
10208        cnt = 0,
10209        tweens,
10210        i;
10211      if (disabled) {
10212        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.
10213      }
10214      tweens = TweenLite.getTweensOf(target);
10215      i = tweens.length;
10216      while (--i > -1) {
10217        if (tweens[i].timeline === this || nested && this._contains(tweens[i])) {
10218          a[cnt++] = tweens[i];
10219        }
10220      }
10221      if (disabled) {
10222        this._enabled(false, true);
10223      }
10224      return a;
10225    };
10226    p.recent = function () {
10227      return this._recent;
10228    };
10229    p._contains = function (tween) {
10230      var tl = tween.timeline;
10231      while (tl) {
10232        if (tl === this) {
10233          return true;
10234        }
10235        tl = tl.timeline;
10236      }
10237      return false;
10238    };
10239    p.shiftChildren = function (amount, adjustLabels, ignoreBeforeTime) {
10240      ignoreBeforeTime = ignoreBeforeTime || 0;
10241      var tween = this._first,
10242        labels = this._labels,
10243        p;
10244      while (tween) {
10245        if (tween._startTime >= ignoreBeforeTime) {
10246          tween._startTime += amount;
10247        }
10248        tween = tween._next;
10249      }
10250      if (adjustLabels) {
10251        for (p in labels) {
10252          if (labels[p] >= ignoreBeforeTime) {
10253            labels[p] += amount;
10254          }
10255        }
10256      }
10257      return this._uncache(true);
10258    };
10259    p._kill = function (vars, target) {
10260      if (!vars && !target) {
10261        return this._enabled(false, false);
10262      }
10263      var tweens = !target ? this.getChildren(true, true, false) : this.getTweensOf(target),
10264        i = tweens.length,
10265        changed = false;
10266      while (--i > -1) {
10267        if (tweens[i]._kill(vars, target)) {
10268          changed = true;
10269        }
10270      }
10271      return changed;
10272    };
10273    p.clear = function (labels) {
10274      var tweens = this.getChildren(false, true, true),
10275        i = tweens.length;
10276      this._time = this._totalTime = 0;
10277      while (--i > -1) {
10278        tweens[i]._enabled(false, false);
10279      }
10280      if (labels !== false) {
10281        this._labels = {};
10282      }
10283      return this._uncache(true);
10284    };
10285    p.invalidate = function () {
10286      var tween = this._first;
10287      while (tween) {
10288        tween.invalidate();
10289        tween = tween._next;
10290      }
10291      return Animation.prototype.invalidate.call(this);
10292      ;
10293    };
10294    p._enabled = function (enabled, ignoreTimeline) {
10295      if (enabled === this._gc) {
10296        var tween = this._first;
10297        while (tween) {
10298          tween._enabled(enabled, true);
10299          tween = tween._next;
10300        }
10301      }
10302      return SimpleTimeline.prototype._enabled.call(this, enabled, ignoreTimeline);
10303    };
10304    p.totalTime = function (time, suppressEvents, uncapped) {
10305      this._forcingPlayhead = true;
10306      var val = Animation.prototype.totalTime.apply(this, arguments);
10307      this._forcingPlayhead = false;
10308      return val;
10309    };
10310    p.duration = function (value) {
10311      if (!arguments.length) {
10312        if (this._dirty) {
10313          this.totalDuration(); //just triggers recalculation
10314        }
10315        return this._duration;
10316      }
10317      if (this.duration() !== 0 && value !== 0) {
10318        this.timeScale(this._duration / value);
10319      }
10320      return this;
10321    };
10322    p.totalDuration = function (value) {
10323      if (!arguments.length) {
10324        if (this._dirty) {
10325          var max = 0,
10326            tween = this._last,
10327            prevStart = 999999999999,
10328            prev,
10329            end;
10330          while (tween) {
10331            prev = tween._prev; //record it here in case the tween changes position in the sequence...
10332            if (tween._dirty) {
10333              tween.totalDuration(); //could change the tween._startTime, so make sure the tween's cache is clean before analyzing it.
10334            }
10335            if (tween._startTime > prevStart && this._sortChildren && !tween._paused && !this._calculatingDuration) {
10336              //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence
10337              this._calculatingDuration = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(), like _parseTimeOrLabel().
10338              this.add(tween, tween._startTime - tween._delay);
10339              this._calculatingDuration = 0;
10340            } else {
10341              prevStart = tween._startTime;
10342            }
10343            if (tween._startTime < 0 && !tween._paused) {
10344              //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.
10345              max -= tween._startTime;
10346              if (this._timeline.smoothChildTiming) {
10347                this._startTime += tween._startTime / this._timeScale;
10348                this._time -= tween._startTime;
10349                this._totalTime -= tween._startTime;
10350                this._rawPrevTime -= tween._startTime;
10351              }
10352              this.shiftChildren(-tween._startTime, false, -9999999999);
10353              prevStart = 0;
10354            }
10355            end = tween._startTime + tween._totalDuration / tween._timeScale;
10356            if (end > max) {
10357              max = end;
10358            }
10359            tween = prev;
10360          }
10361          this._duration = this._totalDuration = max;
10362          this._dirty = false;
10363        }
10364        return this._totalDuration;
10365      }
10366      return value && this.totalDuration() ? this.timeScale(this._totalDuration / value) : this;
10367    };
10368    p.paused = function (value) {
10369      if (!value) {
10370        //if there's a pause directly at the spot from where we're unpausing, skip it.
10371        var tween = this._first,
10372          time = this._time;
10373        while (tween) {
10374          if (tween._startTime === time && tween.data === "isPause") {
10375            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.
10376          }
10377          tween = tween._next;
10378        }
10379      }
10380      return Animation.prototype.paused.apply(this, arguments);
10381    };
10382    p.usesFrames = function () {
10383      var tl = this._timeline;
10384      while (tl._timeline) {
10385        tl = tl._timeline;
10386      }
10387      return tl === Animation._rootFramesTimeline;
10388    };
10389    p.rawTime = function (wrapRepeats) {
10390      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;
10391    };
10392    return TimelineLite;
10393  }, true);
10394
10395  /*
10396   * ----------------------------------------------------------------
10397   * TimelineMax
10398   * ----------------------------------------------------------------
10399   */
10400  _gsScope._gsDefine("TimelineMax", ["TimelineLite", "TweenLite", "easing.Ease"], function (TimelineLite, TweenLite, Ease) {
10401    var TimelineMax = function TimelineMax(vars) {
10402        TimelineLite.call(this, vars);
10403        this._repeat = this.vars.repeat || 0;
10404        this._repeatDelay = this.vars.repeatDelay || 0;
10405        this._cycle = 0;
10406        this._yoyo = this.vars.yoyo === true;
10407        this._dirty = true;
10408      },
10409      _tinyNum = 0.0000000001,
10410      TweenLiteInternals = TweenLite._internals,
10411      _lazyTweens = TweenLiteInternals.lazyTweens,
10412      _lazyRender = TweenLiteInternals.lazyRender,
10413      _globals = _gsScope._gsDefine.globals,
10414      _easeNone = new Ease(null, null, 1, 0),
10415      p = TimelineMax.prototype = new TimelineLite();
10416    p.constructor = TimelineMax;
10417    p.kill()._gc = false;
10418    TimelineMax.version = "1.20.4";
10419    p.invalidate = function () {
10420      this._yoyo = this.vars.yoyo === true;
10421      this._repeat = this.vars.repeat || 0;
10422      this._repeatDelay = this.vars.repeatDelay || 0;
10423      this._uncache(true);
10424      return TimelineLite.prototype.invalidate.call(this);
10425    };
10426    p.addCallback = function (callback, position, params, scope) {
10427      return this.add(TweenLite.delayedCall(0, callback, params, scope), position);
10428    };
10429    p.removeCallback = function (callback, position) {
10430      if (callback) {
10431        if (position == null) {
10432          this._kill(null, callback);
10433        } else {
10434          var a = this.getTweensOf(callback, false),
10435            i = a.length,
10436            time = this._parseTimeOrLabel(position);
10437          while (--i > -1) {
10438            if (a[i]._startTime === time) {
10439              a[i]._enabled(false, false);
10440            }
10441          }
10442        }
10443      }
10444      return this;
10445    };
10446    p.removePause = function (position) {
10447      return this.removeCallback(TimelineLite._internals.pauseCallback, position);
10448    };
10449    p.tweenTo = function (position, vars) {
10450      vars = vars || {};
10451      var copy = {
10452          ease: _easeNone,
10453          useFrames: this.usesFrames(),
10454          immediateRender: false,
10455          lazy: false
10456        },
10457        Engine = vars.repeat && _globals.TweenMax || TweenLite,
10458        duration,
10459        p,
10460        t;
10461      for (p in vars) {
10462        copy[p] = vars[p];
10463      }
10464      copy.time = this._parseTimeOrLabel(position);
10465      duration = Math.abs(Number(copy.time) - this._time) / this._timeScale || 0.001;
10466      t = new Engine(this, duration, copy);
10467      copy.onStart = function () {
10468        t.target.paused(true);
10469        if (t.vars.time !== t.target.time() && duration === t.duration() && !t.isFromTo) {
10470          //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.
10471          t.duration(Math.abs(t.vars.time - t.target.time()) / t.target._timeScale).render(t.time(), true, true); //render() right away to ensure that things look right, especially in the case of .tweenTo(0).
10472        }
10473        if (vars.onStart) {
10474          //in case the user had an onStart in the vars - we don't want to overwrite it.
10475          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.
10476        }
10477      };
10478      return t;
10479    };
10480    p.tweenFromTo = function (fromPosition, toPosition, vars) {
10481      vars = vars || {};
10482      fromPosition = this._parseTimeOrLabel(fromPosition);
10483      vars.startAt = {
10484        onComplete: this.seek,
10485        onCompleteParams: [fromPosition],
10486        callbackScope: this
10487      };
10488      vars.immediateRender = vars.immediateRender !== false;
10489      var t = this.tweenTo(toPosition, vars);
10490      t.isFromTo = 1; //to ensure we don't mess with the duration in the onStart (we've got the start and end values here, so lock it in)
10491      return t.duration(Math.abs(t.vars.time - fromPosition) / this._timeScale || 0.001);
10492    };
10493    p.render = function (time, suppressEvents, force) {
10494      if (this._gc) {
10495        this._enabled(true, false);
10496      }
10497      var prevTime = this._time,
10498        totalDur = !this._dirty ? this._totalDuration : this.totalDuration(),
10499        dur = this._duration,
10500        prevTotalTime = this._totalTime,
10501        prevStart = this._startTime,
10502        prevTimeScale = this._timeScale,
10503        prevRawPrevTime = this._rawPrevTime,
10504        prevPaused = this._paused,
10505        prevCycle = this._cycle,
10506        tween,
10507        isComplete,
10508        next,
10509        callback,
10510        internalForce,
10511        cycleDuration,
10512        pauseTween,
10513        curTime;
10514      if (prevTime !== this._time) {
10515        //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).
10516        time += this._time - prevTime;
10517      }
10518      if (time >= totalDur - 0.0000001 && time >= 0) {
10519        //to work around occasional floating point math artifacts.
10520        if (!this._locked) {
10521          this._totalTime = totalDur;
10522          this._cycle = this._repeat;
10523        }
10524        if (!this._reversed) if (!this._hasPausedChild()) {
10525          isComplete = true;
10526          callback = "onComplete";
10527          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.
10528          if (this._duration === 0) if (time <= 0 && time >= -0.0000001 || prevRawPrevTime < 0 || prevRawPrevTime === _tinyNum) if (prevRawPrevTime !== time && this._first) {
10529            internalForce = true;
10530            if (prevRawPrevTime > _tinyNum) {
10531              callback = "onReverseComplete";
10532            }
10533          }
10534        }
10535        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.
10536        if (this._yoyo && (this._cycle & 1) !== 0) {
10537          this._time = time = 0;
10538        } else {
10539          this._time = dur;
10540          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 
10540which case adding 0.00000001, for example, causes it to act like nothing was added.
10541        }
10542      } else if (time < 0.0000001) {
10543        //to work around occasional floating point math artifacts, round super small values to 0.
10544        if (!this._locked) {
10545          this._totalTime = this._cycle = 0;
10546        }
10547        this._time = 0;
10548        if (prevTime !== 0 || dur === 0 && prevRawPrevTime !== _tinyNum && (prevRawPrevTime > 0 || time < 0 && prevRawPrevTime >= 0) && !this._locked) {
10549          //edge case for checking time < 0 && prevRawPrevTime >= 0: a zero-duration fromTo() tween inside a zero-duration timeline (yeah, very rare)
10550          callback = "onReverseComplete";
10551          isComplete = this._reversed;
10552        }
10553        if (time < 0) {
10554          this._active = false;
10555          if (this._timeline.autoRemoveChildren && this._reversed) {
10556            internalForce = isComplete = true;
10557            callback = "onReverseComplete";
10558          } else if (prevRawPrevTime >= 0 && this._first) {
10559            //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.
10560            internalForce = true;
10561          }
10562          this._rawPrevTime = time;
10563        } else {
10564          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.
10565          if (time === 0 && isComplete) {
10566            //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).
10567            tween = this._first;
10568            while (tween && tween._startTime === 0) {
10569              if (!tween._duration) {
10570                isComplete = false;
10571              }
10572              tween = tween._next;
10573            }
10574          }
10575          time = 0; //to avoid occasional floating point rounding errors (could cause problems especially with zero-duration tweens at the very beginning of the timeline)
10576          if (!this._initted) {
10577            internalForce = true;
10578          }
10579        }
10580      } else {
10581        if (dur === 0 && prevRawPrevTime < 0) {
10582          //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.
10583          internalForce = true;
10584        }
10585        this._time = this._rawPrevTime = time;
10586        if (!this._locked) {
10587          this._totalTime = time;
10588          if (this._repeat !== 0) {
10589            cycleDuration = dur + this._repeatDelay;
10590            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!)
10591            if (this._cycle !== 0) if (this._cycle === this._totalTime / cycleDuration && prevTotalTime <= time) {
10592              this._cycle--; //otherwise when rendered exactly at the end time, it will act as though it is repeating (at the beginning)
10593            }
10594            this._time = this._totalTime - this._cycle * cycleDuration;
10595            if (this._yoyo) if ((this._cycle & 1) !== 0) {
10596              this._time = dur - this._time;
10597            }
10598            if (this._time > dur) {
10599              this._time = dur;
10600              time = dur + 0.0001; //to avoid occasional floating point rounding error
10601            } else if (this._time < 0) {
10602              this._time = time = 0;
10603            } else {
10604              time = this._time;
10605            }
10606          }
10607        }
10608        if (this._hasPause && !this._forcingPlayhead && !suppressEvents) {
10609          time = this._time;
10610          if (time >= prevTime || this._repeat && prevCycle !== this._cycle) {
10611            tween = this._first;
10612            while (tween && tween._startTime <= time && !pauseTween) {
10613              if (!tween._duration) if (tween.data === "isPause" && !tween.ratio && !(tween._startTime === 0 && this._rawPrevTime === 0)) {
10614                pauseTween = tween;
10615              }
10616              tween = tween._next;
10617            }
10618          } else {
10619            tween = this._last;
10620            while (tween && tween._startTime >= time && !pauseTween) {
10621              if (!tween._duration) if (tween.data === "isPause" && tween._rawPrevTime > 0) {
10622                pauseTween = tween;
10623              }
10624              tween = tween._prev;
10625            }
10626          }
10627          if (pauseTween && pauseTween._startTime < dur) {
10628            this._time = time = pauseTween._startTime;
10629            this._totalTime = time + this._cycle * (this._totalDuration + this._repeatDelay);
10630          }
10631        }
10632      }
10633      if (this._cycle !== prevCycle) if (!this._locked) {
10634        /*
10635        make sure children at the end/beginning of the timeline are rendered properly. If, for example,
10636        a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which
10637        would get transated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there
10638        could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So
10639        we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must
10640        ensure that zero-duration tweens at the very beginning or end of the TimelineMax work.
10641        */
10642        var backwards = this._yoyo && (prevCycle & 1) !== 0,
10643          wrap = backwards === (this._yoyo && (this._cycle & 1) !== 0),
10644          recTotalTime = this._totalTime,
10645          recCycle = this._cycle,
10646          recRawPrevTime = this._rawPrevTime,
10647          recTime = this._time;
10648        this._totalTime = prevCycle * dur;
10649        if (this._cycle < prevCycle) {
10650          backwards = !backwards;
10651        } else {
10652          this._totalTime += dur;
10653        }
10654        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.
10655
10656        this._rawPrevTime = dur === 0 ? prevRawPrevTime - 0.0001 : prevRawPrevTime;
10657        this._cycle = prevCycle;
10658        this._locked = true; //prevents changes to totalTime and skips repeat/yoyo behavior when we recursively call render()
10659        prevTime = backwards ? 0 : dur;
10660        this.render(prevTime, suppressEvents, dur === 0);
10661        if (!suppressEvents) if (!this._gc) {
10662          if (this.vars.onRepeat) {
10663            this._cycle = recCycle; //in case the onRepeat alters the playhead or invalidates(), we shouldn't stay locked or use the previous cycle.
10664            this._locked = false;
10665            this._callback("onRepeat");
10666          }
10667        }
10668        if (prevTime !== this._time) {
10669          //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.
10670          return;
10671        }
10672        if (wrap) {
10673          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.
10674          this._locked = true;
10675          prevTime = backwards ? dur + 0.0001 : -0.0001;
10676          this.render(prevTime, true, false);
10677        }
10678        this._locked = false;
10679        if (this._paused && !prevPaused) {
10680          //if the render() triggered callback that paused this timeline, we should abort (very rare, but possible)
10681          return;
10682        }
10683        this._time = recTime;
10684        this._totalTime = recTotalTime;
10685        this._cycle = recCycle;
10686        this._rawPrevTime = recRawPrevTime;
10687      }
10688      if ((this._time === prevTime || !this._first) && !force && !internalForce && !pauseTween) {
10689        if (prevTotalTime !== this._totalTime) if (this._onUpdate) if (!suppressEvents) {
10690          //so that onUpdate fires even during the repeatDelay - as long as the totalTime changed, we should trigger onUpdate.
10691          this._callback("onUpdate");
10692        }
10693        return;
10694      } else if (!this._initted) {
10695        this._initted = true;
10696      }
10697      if (!this._active) if (!this._paused && this._totalTime !== prevTotalTime && time > 0) {
10698        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.
10699      }
10700      if (prevTotalTime === 0) if (this.vars.onStart) if (this._totalTime !== 0 || !this._totalDuration) if (!suppressEvents) {
10701        this._callback("onStart");
10702      }
10703      curTime = this._time;
10704      if (curTime >= prevTime) {
10705        tween = this._first;
10706        while (tween) {
10707          next = tween._next; //record it here because the value could change after rendering...
10708          if (curTime !== this._time || this._paused && !prevPaused) {
10709            //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
10710            break;
10711          } else if (tween._active || tween._startTime <= this._time && !tween._paused && !tween._gc) {
10712            if (pauseTween === tween) {
10713              this.pause();
10714            }
10715            if (!tween._reversed) {
10716              tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
10717            } else {
10718              tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
10719            }
10720          }
10721          tween = next;
10722        }
10723      } else {
10724        tween = this._last;
10725        while (tween) {
10726          next = tween._prev; //record it here because the value could change after rendering...
10727          if (curTime !== this._time || this._paused && !prevPaused) {
10728            //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete
10729            break;
10730          } else if (tween._active || tween._startTime <= prevTime && !tween._paused && !tween._gc) {
10731            if (pauseTween === tween) {
10732              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.
10733              while (pauseTween && pauseTween.endTime() > this._time) {
10734                pauseTween.render(pauseTween._reversed ? pauseTween.totalDuration() - (time - pauseTween._startTime) * pauseTween._timeScale : (time - pauseTween._startTime) * pauseTween._timeScale, suppressEvents, force);
10735                pauseTween = pauseTween._prev;
10736              }
10737              pauseTween = null;
10738              this.pause();
10739            }
10740            if (!tween._reversed) {
10741              tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
10742            } else {
10743              tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
10744            }
10745          }
10746          tween = next;
10747        }
10748      }
10749      if (this._onUpdate) if (!suppressEvents) {
10750        if (_lazyTweens.length) {
10751          //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.
10752          _lazyRender();
10753        }
10754        this._callback("onUpdate");
10755      }
10756      if (callback) if (!this._locked) if (!this._gc) if (prevStart === this._startTime || prevTimeScale !== this._timeScale) if (this._time === 0 || totalDur >= this.totalDuration()) {
10757        //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
10758        if (isComplete) {
10759          if (_lazyTweens.length) {
10760            //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.
10761            _lazyRender();
10762          }
10763          if (this._timeline.autoRemoveChildren) {
10764            this._enabled(false, false);
10765          }
10766          this._active = false;
10767        }
10768        if (!suppressEvents && this.vars[callback]) {
10769          this._callback(callback);
10770        }
10771      }
10772    };
10773    p.getActive = function (nested, tweens, timelines) {
10774      if (nested == null) {
10775        nested = true;
10776      }
10777      if (tweens == null) {
10778        tweens = true;
10779      }
10780      if (timelines == null) {
10781        timelines = false;
10782      }
10783      var a = [],
10784        all = this.getChildren(nested, tweens, timelines),
10785        cnt = 0,
10786        l = all.length,
10787        i,
10788        tween;
10789      for (i = 0; i < l; i++) {
10790        tween = all[i];
10791        if (tween.isActive()) {
10792          a[cnt++] = tween;
10793        }
10794      }
10795      return a;
10796    };
10797    p.getLabelAfter = function (time) {
10798      if (!time) if (time !== 0) {
10799        //faster than isNan()
10800        time = this._time;
10801      }
10802      var labels = this.getLabelsArray(),
10803        l = labels.length,
10804        i;
10805      for (i = 0; i < l; i++) {
10806        if (labels[i].time > time) {
10807          return labels[i].name;
10808        }
10809      }
10810      return null;
10811    };
10812    p.getLabelBefore = function (time) {
10813      if (time == null) {
10814        time = this._time;
10815      }
10816      var labels = this.getLabelsArray(),
10817        i = labels.length;
10818      while (--i > -1) {
10819        if (labels[i].time < time) {
10820          return labels[i].name;
10821        }
10822      }
10823      return null;
10824    };
10825    p.getLabelsArray = function () {
10826      var a = [],
10827        cnt = 0,
10828        p;
10829      for (p in this._labels) {
10830        a[cnt++] = {
10831          time: this._labels[p],
10832          name: p
10833        };
10834      }
10835      a.sort(function (a, b) {
10836        return a.time - b.time;
10837      });
10838      return a;
10839    };
10840    p.invalidate = function () {
10841      this._locked = false; //unlock and set cycle in case invalidate() is called from inside an onRepeat
10842      return TimelineLite.prototype.invalidate.call(this);
10843    };
10844
10845    //---- GETTERS / SETTERS -------------------------------------------------------------------------------------------------------
10846
10847    p.progress = function (value, suppressEvents) {
10848      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);
10849    };
10850    p.totalProgress = function (value, suppressEvents) {
10851      return !arguments.length ? this._totalTime / this.totalDuration() || 0 : this.totalTime(this.totalDuration() * value, suppressEvents);
10852    };
10853    p.totalDuration = function (value) {
10854      if (!arguments.length) {
10855        if (this._dirty) {
10856          TimelineLite.prototype.totalDuration.call(this); //just forces refresh
10857          //Instead of Infinity, we use 999999999999 so that we can accommodate reverses.
10858          this._totalDuration = this._repeat === -1 ? 999999999999 : this._duration * (this._repeat + 1) + this._repeatDelay * this._repeat;
10859        }
10860        return this._totalDuration;
10861      }
10862      return this._repeat === -1 || !value ? this : this.timeScale(this.totalDuration() / value);
10863    };
10864    p.time = function (value, suppressEvents) {
10865      if (!arguments.length) {
10866        return this._time;
10867      }
10868      if (this._dirty) {
10869        this.totalDuration();
10870      }
10871      if (value > this._duration) {
10872        value = this._duration;
10873      }
10874      if (this._yoyo && (this._cycle & 1) !== 0) {
10875        value = this._duration - value + this._cycle * (this._duration + this._repeatDelay);
10876      } else if (this._repeat !== 0) {
10877        value += this._cycle * (this._duration + this._repeatDelay);
10878      }
10879      return this.totalTime(value, suppressEvents);
10880    };
10881    p.repeat = function (value) {
10882      if (!arguments.length) {
10883        return this._repeat;
10884      }
10885      this._repeat = value;
10886      return this._uncache(true);
10887    };
10888    p.repeatDelay = function (value) {
10889      if (!arguments.length) {
10890        return this._repeatDelay;
10891      }
10892      this._repeatDelay = value;
10893      return this._uncache(true);
10894    };
10895    p.yoyo = function (value) {
10896      if (!arguments.length) {
10897        return this._yoyo;
10898      }
10899      this._yoyo = value;
10900      return this;
10901    };
10902    p.currentLabel = function (value) {
10903      if (!arguments.length) {
10904        return this.getLabelBefore(this._time + 0.00000001);
10905      }
10906      return this.seek(value, true);
10907    };
10908    return TimelineMax;
10909  }, true);
10910
10911  /*
10912   * ----------------------------------------------------------------
10913   * BezierPlugin
10914   * ----------------------------------------------------------------
10915   */
10916  (function () {
10917    var _RAD2DEG = 180 / Math.PI,
10918      _r1 = [],
10919      _r2 = [],
10920      _r3 = [],
10921      _corProps = {},
10922      _globals = _gsScope._gsDefine.globals,
10923      Segment = function Segment(a, b, c, d) {
10924        if (c === d) {
10925          //if c and d match, the final autoRotate value could lock at -90 degrees, so differentiate them slightly.
10926          c = d - (d - b) / 1000000;
10927        }
10928        if (a === b) {
10929          //if a and b match, the starting autoRotate value could lock at -90 degrees, so differentiate them slightly.
10930          b = a + (c - a) / 1000000;
10931        }
10932        this.a = a;
10933        this.b = b;
10934        this.c = c;
10935        this.d = d;
10936        this.da = d - a;
10937        this.ca = c - a;
10938        this.ba = b - a;
10939      },
10940      _correlate = ",x,y,z,left,top,right,bottom,marginTop,marginLeft,marginRight,marginBottom,paddingLeft,paddingTop,paddingRight,paddingBottom,backgroundPosition,backgroundPosition_y,",
10941      cubicToQuadratic = function cubicToQuadratic(a, b, c, d) {
10942        var q1 = {
10943            a: a
10944          },
10945          q2 = {},
10946          q3 = {},
10947          q4 = {
10948            c: d
10949          },
10950          mab = (a + b) / 2,
10951          mbc = (b + c) / 2,
10952          mcd = (c + d) / 2,
10953          mabc = (mab + mbc) / 2,
10954          mbcd = (mbc + mcd) / 2,
10955          m8 = (mbcd - mabc) / 8;
10956        q1.b = mab + (a - mab) / 4;
10957        q2.b = mabc + m8;
10958        q1.c = q2.a = (q1.b + q2.b) / 2;
10959        q2.c = q3.a = (mabc + mbcd) / 2;
10960        q3.b = mbcd - m8;
10961        q4.b = mcd + (d - mcd) / 4;
10962        q3.c = q4.a = (q3.b + q4.b) / 2;
10963        return [q1, q2, q3, q4];
10964      },
10965      _calculateControlPoints = function _calculateControlPoints(a, curviness, quad, basic, correlate) {
10966        var l = a.length - 1,
10967          ii = 0,
10968          cp1 = a[0].a,
10969          i,
10970          p1,
10971          p2,
10972          p3,
10973          seg,
10974          m1,
10975          m2,
10976          mm,
10977          cp2,
10978          qb,
10979          r1,
10980          r2,
10981          tl;
10982        for (i = 0; i < l; i++) {
10983          seg = a[ii];
10984          p1 = seg.a;
10985          p2 = seg.d;
10986          p3 = a[ii + 1].d;
10987          if (correlate) {
10988            r1 = _r1[i];
10989            r2 = _r2[i];
10990            tl = (r2 + r1) * curviness * 0.25 / (basic ? 0.5 : _r3[i] || 0.5);
10991            m1 = p2 - (p2 - p1) * (basic ? curviness * 0.5 : r1 !== 0 ? tl / r1 : 0);
10992            m2 = p2 + (p3 - p2) * (basic ? curviness * 0.5 : r2 !== 0 ? tl / r2 : 0);
10993            mm = p2 - (m1 + ((m2 - m1) * (r1 * 3 / (r1 + r2) + 0.5) / 4 || 0));
10994          } else {
10995            m1 = p2 - (p2 - p1) * curviness * 0.5;
10996            m2 = p2 + (p3 - p2) * curviness * 0.5;
10997            mm = p2 - (m1 + m2) / 2;
10998          }
10999          m1 += mm;
11000          m2 += mm;
11001          seg.c = cp2 = m1;
11002          if (i !== 0) {
11003            seg.b = cp1;
11004          } else {
11005            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.
11006          }
11007          seg.da = p2 - p1;
11008          seg.ca = cp2 - p1;
11009          seg.ba = cp1 - p1;
11010          if (quad) {
11011            qb = cubicToQuadratic(p1, cp1, cp2, p2);
11012            a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]);
11013            ii += 4;
11014          } else {
11015            ii++;
11016          }
11017          cp1 = m2;
11018        }
11019        seg = a[ii];
11020        seg.b = cp1;
11021        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.
11022        seg.da = seg.d - seg.a;
11023        seg.ca = seg.c - seg.a;
11024        seg.ba = cp1 - seg.a;
11025        if (quad) {
11026          qb = cubicToQuadratic(seg.a, cp1, seg.c, seg.d);
11027          a.splice(ii, 1, qb[0], qb[1], qb[2], qb[3]);
11028        }
11029      },
11030      _parseAnchors = function _parseAnchors(values, p, correlate, prepend) {
11031        var a = [],
11032          l,
11033          i,
11034          p1,
11035          p2,
11036          p3,
11037          tmp;
11038        if (prepend) {
11039          values = [prepend].concat(values);
11040          i = values.length;
11041          while (--i > -1) {
11042            if (typeof (tmp = values[i][p]) === "string") if (tmp.charAt(1) === "=") {
11043              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
11044            }
11045          }
11046        }
11047        l = values.length - 2;
11048        if (l < 0) {
11049          a[0] = new Segment(values[0][p], 0, 0, values[0][p]);
11050          return a;
11051        }
11052        for (i = 0; i < l; i++) {
11053          p1 = values[i][p];
11054          p2 = values[i + 1][p];
11055          a[i] = new Segment(p1, 0, 0, p2);
11056          if (correlate) {
11057            p3 = values[i + 2][p];
11058            _r1[i] = (_r1[i] || 0) + (p2 - p1) * (p2 - p1);
11059            _r2[i] = (_r2[i] || 0) + (p3 - p2) * (p3 - p2);
11060          }
11061        }
11062        a[i] = new Segment(values[i][p], 0, 0, values[i + 1][p]);
11063        return a;
11064      },
11065      bezierThrough = function bezierThrough(values, curviness, quadratic, basic, correlate, prepend) {
11066        var obj = {},
11067          props = [],
11068          first = prepend || values[0],
11069          i,
11070          p,
11071          a,
11072          j,
11073          r,
11074          l,
11075          seamless,
11076          last;
11077        correlate = typeof correlate === "string" ? "," + correlate + "," : _correlate;
11078        if (curviness == null) {
11079          curviness = 1;
11080        }
11081        for (p in values[0]) {
11082          props.push(p);
11083        }
11084        //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)
11085        if (values.length > 1) {
11086          last = values[values.length - 1];
11087          seamless = true;
11088          i = props.length;
11089          while (--i > -1) {
11090            p = props[i];
11091            if (Math.abs(first[p] - last[p]) > 0.05) {
11092              //build in a tolerance of +/-0.05 to accommodate rounding errors.
11093              seamless = false;
11094              break;
11095            }
11096          }
11097          if (seamless) {
11098            values = values.concat(); //duplicate the array to avoid contaminating the original which the user may be reusing for other tweens
11099            if (prepend) {
11100              values.unshift(prepend);
11101            }
11102            values.push(values[1]);
11103            prepend = values[values.length - 3];
11104          }
11105        }
11106        _r1.length = _r2.length = _r3.length = 0;
11107        i = props.length;
11108        while (--i > -1) {
11109          p = props[i];
11110          _corProps[p] = correlate.indexOf("," + p + ",") !== -1;
11111          obj[p] = _parseAnchors(values, p, _corProps[p], prepend);
11112        }
11113        i = _r1.length;
11114        while (--i > -1) {
11115          _r1[i] = Math.sqrt(_r1[i]);
11116          _r2[i] = Math.sqrt(_r2[i]);
11117        }
11118        if (!basic) {
11119          i = props.length;
11120          while (--i > -1) {
11121            if (_corProps[p]) {
11122              a = obj[props[i]];
11123              l = a.length - 1;
11124              for (j = 0; j < l; j++) {
11125                r = a[j + 1].da / _r2[j] + a[j].da / _r1[j] || 0;
11126                _r3[j] = (_r3[j] || 0) + r * r;
11127              }
11128            }
11129          }
11130          i = _r3.length;
11131          while (--i > -1) {
11132            _r3[i] = Math.sqrt(_r3[i]);
11133          }
11134        }
11135        i = props.length;
11136        j = quadratic ? 4 : 1;
11137        while (--i > -1) {
11138          p = props[i];
11139          a = obj[p];
11140          _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
11141          if (seamless) {
11142            a.splice(0, j);
11143            a.splice(a.length - j, j);
11144          }
11145        }
11146        return obj;
11147      },
11148      _parseBezierData = function _parseBezierData(values, type, prepend) {
11149        type = type || "soft";
11150        var obj = {},
11151          inc = type === "cubic" ? 3 : 2,
11152          soft = type === "soft",
11153          props = [],
11154          a,
11155          b,
11156          c,
11157          d,
11158          cur,
11159          i,
11160          j,
11161          l,
11162          p,
11163          cnt,
11164          tmp;
11165        if (soft && prepend) {
11166          values = [prepend].concat(values);
11167        }
11168        if (values == null || values.length < inc + 1) {
11169          throw "invalid Bezier data";
11170        }
11171        for (p in values[0]) {
11172          props.push(p);
11173        }
11174        i = props.length;
11175        while (--i > -1) {
11176          p = props[i];
11177          obj[p] = cur = [];
11178          cnt = 0;
11179          l = values.length;
11180          for (j = 0; j < l; j++) {
11181            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);
11182            if (soft) if (j > 1) if (j < l - 1) {
11183              cur[cnt++] = (a + cur[cnt - 2]) / 2;
11184            }
11185            cur[cnt++] = a;
11186          }
11187          l = cnt - inc + 1;
11188          cnt = 0;
11189          for (j = 0; j < l; j += inc) {
11190            a = cur[j];
11191            b = cur[j + 1];
11192            c = cur[j + 2];
11193            d = inc === 2 ? 0 : cur[j + 3];
11194            cur[cnt++] = tmp = inc === 3 ? new Segment(a, b, c, d) : new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
11195          }
11196          cur.length = cnt;
11197        }
11198        return obj;
11199      },
11200      _addCubicLengths = function _addCubicLengths(a, steps, resolution) {
11201        var inc = 1 / resolution,
11202          j = a.length,
11203          d,
11204          d1,
11205          s,
11206          da,
11207          ca,
11208          ba,
11209          p,
11210          i,
11211          inv,
11212          bez,
11213          index;
11214        while (--j > -1) {
11215          bez = a[j];
11216          s = bez.a;
11217          da = bez.d - s;
11218          ca = bez.c - s;
11219          ba = bez.b - s;
11220          d = d1 = 0;
11221          for (i = 1; i <= resolution; i++) {
11222            p = inc * i;
11223            inv = 1 - p;
11224            d = d1 - (d1 = (p * p * da + 3 * inv * (p * ca + inv * ba)) * p);
11225            index = j * resolution + i - 1;
11226            steps[index] = (steps[index] || 0) + d * d;
11227          }
11228        }
11229      },
11230      _parseLengthData = function _parseLengthData(obj, resolution) {
11231        resolution = resolution >> 0 || 6;
11232        var a = [],
11233          lengths = [],
11234          d = 0,
11235          total = 0,
11236          threshold = resolution - 1,
11237          segments = [],
11238          curLS = [],
11239          //current length segments array
11240          p,
11241          i,
11242          l,
11243          index;
11244        for (p in obj) {
11245          _addCubicLengths(obj[p], a, resolution);
11246        }
11247        l = a.length;
11248        for (i = 0; i < l; i++) {
11249          d += Math.sqrt(a[i]);
11250          index = i % resolution;
11251          curLS[index] = d;
11252          if (index === threshold) {
11253            total += d;
11254            index = i / resolution >> 0;
11255            segments[index] = curLS;
11256            lengths[index] = total;
11257            d = 0;
11258            curLS = [];
11259          }
11260        }
11261        return {
11262          length: total,
11263          lengths: lengths,
11264          segments: segments
11265        };
11266      },
11267      BezierPlugin = _gsScope._gsDefine.plugin({
11268        propName: "bezier",
11269        priority: -1,
11270        version: "1.3.8",
11271        API: 2,
11272        global: true,
11273        //gets called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
11274        init: function init(target, vars, tween) {
11275          this._target = target;
11276          if (vars instanceof Array) {
11277            vars = {
11278              values: vars
11279            };
11280          }
11281          this._func = {};
11282          this._mod = {};
11283          this._props = [];
11284          this._timeRes = vars.timeResolution == null ? 6 : parseInt(vars.timeResolution, 10);
11285          var values = vars.values || [],
11286            first = {},
11287            second = values[0],
11288            autoRotate = vars.autoRotate || tween.vars.orientToBezier,
11289            p,
11290            isFunc,
11291            i,
11292            j,
11293            prepend;
11294          this._autoRotate = autoRotate ? autoRotate instanceof Array ? autoRotate : [["x", "y", "rotation", autoRotate === true ? 0 : Number(autoRotate) || 0]] : null;
11295          for (p in second) {
11296            this._props.push(p);
11297          }
11298          i = this._props.length;
11299          while (--i > -1) {
11300            p = this._props[i];
11301            this._overwriteProps.push(p);
11302            isFunc = this._func[p] = typeof target[p] === "function";
11303            first[p] = !isFunc ? parseFloat(target[p]) : target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)]();
11304            if (!prepend) if (first[p] !== values[0][p]) {
11305              prepend = first;
11306            }
11307          }
11308          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
11308orrelate, prepend) : _parseBezierData(values, vars.type, first);
11309          this._segCount = this._beziers[p].length;
11310          if (this._timeRes) {
11311            var ld = _parseLengthData(this._beziers, this._timeRes);
11312            this._length = ld.length;
11313            this._lengths = ld.lengths;
11314            this._segments = ld.segments;
11315            this._l1 = this._li = this._s1 = this._si = 0;
11316            this._l2 = this._lengths[0];
11317            this._curSeg = this._segments[0];
11318            this._s2 = this._curSeg[0];
11319            this._prec = 1 / this._curSeg.length;
11320          }
11321          if (autoRotate = this._autoRotate) {
11322            this._initialRotations = [];
11323            if (!(autoRotate[0] instanceof Array)) {
11324              this._autoRotate = autoRotate = [autoRotate];
11325            }
11326            i = autoRotate.length;
11327            while (--i > -1) {
11328              for (j = 0; j < 3; j++) {
11329                p = autoRotate[i][j];
11330                this._func[p] = typeof target[p] === "function" ? target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)] : false;
11331              }
11332              p = autoRotate[i][2];
11333              this._initialRotations[i] = (this._func[p] ? this._func[p].call(this._target) : this._target[p]) || 0;
11334              this._overwriteProps.push(p);
11335            }
11336          }
11337          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.
11338          return true;
11339        },
11340        //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.)
11341        set: function set(v) {
11342          var segments = this._segCount,
11343            func = this._func,
11344            target = this._target,
11345            notStart = v !== this._startRatio,
11346            curIndex,
11347            inv,
11348            i,
11349            p,
11350            b,
11351            t,
11352            val,
11353            l,
11354            lengths,
11355            curSeg;
11356          if (!this._timeRes) {
11357            curIndex = v < 0 ? 0 : v >= 1 ? segments - 1 : segments * v >> 0;
11358            t = (v - curIndex * (1 / segments)) * segments;
11359          } else {
11360            lengths = this._lengths;
11361            curSeg = this._curSeg;
11362            v *= this._length;
11363            i = this._li;
11364            //find the appropriate segment (if the currently cached one isn't correct)
11365            if (v > this._l2 && i < segments - 1) {
11366              l = segments - 1;
11367              while (i < l && (this._l2 = lengths[++i]) <= v) {}
11368              this._l1 = lengths[i - 1];
11369              this._li = i;
11370              this._curSeg = curSeg = this._segments[i];
11371              this._s2 = curSeg[this._s1 = this._si = 0];
11372            } else if (v < this._l1 && i > 0) {
11373              while (i > 0 && (this._l1 = lengths[--i]) >= v) {}
11374              if (i === 0 && v < this._l1) {
11375                this._l1 = 0;
11376              } else {
11377                i++;
11378              }
11379              this._l2 = lengths[i];
11380              this._li = i;
11381              this._curSeg = curSeg = this._segments[i];
11382              this._s1 = curSeg[(this._si = curSeg.length - 1) - 1] || 0;
11383              this._s2 = curSeg[this._si];
11384            }
11385            curIndex = i;
11386            //now find the appropriate sub-segment (we split it into the number of pieces that was defined by "precision" and measured each one)
11387            v -= this._l1;
11388            i = this._si;
11389            if (v > this._s2 && i < curSeg.length - 1) {
11390              l = curSeg.length - 1;
11391              while (i < l && (this._s2 = curSeg[++i]) <= v) {}
11392              this._s1 = curSeg[i - 1];
11393              this._si = i;
11394            } else if (v < this._s1 && i > 0) {
11395              while (i > 0 && (this._s1 = curSeg[--i]) >= v) {}
11396              if (i === 0 && v < this._s1) {
11397                this._s1 = 0;
11398              } else {
11399                i++;
11400              }
11401              this._s2 = curSeg[i];
11402              this._si = i;
11403            }
11404            t = (i + (v - this._s1) / (this._s2 - this._s1)) * this._prec || 0;
11405          }
11406          inv = 1 - t;
11407          i = this._props.length;
11408          while (--i > -1) {
11409            p = this._props[i];
11410            b = this._beziers[p][curIndex];
11411            val = (t * t * b.da + 3 * inv * (t * b.ca + inv * b.ba)) * t + b.a;
11412            if (this._mod[p]) {
11413              val = this._mod[p](val, target);
11414            }
11415            if (func[p]) {
11416              target[p](val);
11417            } else {
11418              target[p] = val;
11419            }
11420          }
11421          if (this._autoRotate) {
11422            var ar = this._autoRotate,
11423              b2,
11424              x1,
11425              y1,
11426              x2,
11427              y2,
11428              add,
11429              conv;
11430            i = ar.length;
11431            while (--i > -1) {
11432              p = ar[i][2];
11433              add = ar[i][3] || 0;
11434              conv = ar[i][4] === true ? 1 : _RAD2DEG;
11435              b = this._beziers[ar[i][0]];
11436              b2 = this._beziers[ar[i][1]];
11437              if (b && b2) {
11438                //in case one of the properties got overwritten.
11439                b = b[curIndex];
11440                b2 = b2[curIndex];
11441                x1 = b.a + (b.b - b.a) * t;
11442                x2 = b.b + (b.c - b.b) * t;
11443                x1 += (x2 - x1) * t;
11444                x2 += (b.c + (b.d - b.c) * t - x2) * t;
11445                y1 = b2.a + (b2.b - b2.a) * t;
11446                y2 = b2.b + (b2.c - b2.b) * t;
11447                y1 += (y2 - y1) * t;
11448                y2 += (b2.c + (b2.d - b2.c) * t - y2) * t;
11449                val = notStart ? Math.atan2(y2 - y1, x2 - x1) * conv + add : this._initialRotations[i];
11450                if (this._mod[p]) {
11451                  val = this._mod[p](val, target); //for modProps
11452                }
11453                if (func[p]) {
11454                  target[p](val);
11455                } else {
11456                  target[p] = val;
11457                }
11458              }
11459            }
11460          }
11461        }
11462      }),
11463      p = BezierPlugin.prototype;
11464    BezierPlugin.bezierThrough = bezierThrough;
11465    BezierPlugin.cubicToQuadratic = cubicToQuadratic;
11466    BezierPlugin._autoCSS = true; //indicates that this plugin can be inserted into the "css" object using the autoCSS feature of TweenLite
11467    BezierPlugin.quadraticToCubic = function (a, b, c) {
11468      return new Segment(a, (2 * b + a) / 3, (2 * b + c) / 3, c);
11469    };
11470    BezierPlugin._cssRegister = function () {
11471      var CSSPlugin = _globals.CSSPlugin;
11472      if (!CSSPlugin) {
11473        return;
11474      }
11475      var _internals = CSSPlugin._internals,
11476        _parseToProxy = _internals._parseToProxy,
11477        _setPluginRatio = _internals._setPluginRatio,
11478        CSSPropTween = _internals.CSSPropTween;
11479      _internals._registerComplexSpecialProp("bezier", {
11480        parser: function parser(t, e, prop, cssp, pt, plugin) {
11481          if (e instanceof Array) {
11482            e = {
11483              values: e
11484            };
11485          }
11486          plugin = new BezierPlugin();
11487          var values = e.values,
11488            l = values.length - 1,
11489            pluginValues = [],
11490            v = {},
11491            i,
11492            p,
11493            data;
11494          if (l < 0) {
11495            return pt;
11496          }
11497          for (i = 0; i <= l; i++) {
11498            data = _parseToProxy(t, values[i], cssp, pt, plugin, l !== i);
11499            pluginValues[i] = data.end;
11500          }
11501          for (p in e) {
11502            v[p] = e[p]; //duplicate the vars object because we need to alter some things which w
11502ould cause problems if the user plans to reuse the same vars object for another tween.
11503          }
11504          v.values = pluginValues;
11505          pt = new CSSPropTween(t, "bezier", 0, 0, data.pt, 2);
11506          pt.data = data;
11507          pt.plugin = plugin;
11508          pt.setRatio = _setPluginRatio;
11509          if (v.autoRotate === 0) {
11510            v.autoRotate = true;
11511          }
11512          if (v.autoRotate && !(v.autoRotate instanceof Array)) {
11513            i = v.autoRotate === true ? 0 : Number(v.autoRotate);
11514            v.autoRotate = data.end.left != null ? [["left", "top", "rotation", i, false]] : data.end.x != null ? [["x", "y", "rotation", i, false]] : false;
11515          }
11516          if (v.autoRotate) {
11517            if (!cssp._transform) {
11518              cssp._enableTransforms(false);
11519            }
11520            data.autoRotate = cssp._target._gsTransform;
11521            data.proxy.rotation = data.autoRotate.rotation || 0;
11522            cssp._overwriteProps.push("rotation");
11523          }
11524          plugin._onInitTween(data.proxy, v, cssp._tween);
11525          return pt;
11526        }
11527      });
11528    };
11529    p._mod = function (lookup) {
11530      var op = this._overwriteProps,
11531        i = op.length,
11532        val;
11533      while (--i > -1) {
11534        val = lookup[op[i]];
11535        if (val && typeof val === "function") {
11536          this._mod[op[i]] = val;
11537        }
11538      }
11539    };
11540    p._kill = function (lookup) {
11541      var a = this._props,
11542        p,
11543        i;
11544      for (p in this._beziers) {
11545        if (p in lookup) {
11546          delete this._beziers[p];
11547          delete this._func[p];
11548          i = a.length;
11549          while (--i > -1) {
11550            if (a[i] === p) {
11551              a.splice(i, 1);
11552            }
11553          }
11554        }
11555      }
11556      a = this._autoRotate;
11557      if (a) {
11558        i = a.length;
11559        while (--i > -1) {
11560          if (lookup[a[i][2]]) {
11561            a.splice(i, 1);
11562          }
11563        }
11564      }
11565      return this._super._kill.call(this, lookup);
11566    };
11567  })();
11568
11569  /*
11570   * ----------------------------------------------------------------
11571   * CSSPlugin
11572   * ----------------------------------------------------------------
11573   */
11574  _gsScope._gsDefine("plugins.CSSPlugin", ["plugins.TweenPlugin", "TweenLite"], function (TweenPlugin, TweenLite) {
11575    /** @constructor **/
11576    var _CSSPlugin = function CSSPlugin() {
11577        TweenPlugin.call(this, "css");
11578        this._overwriteProps.length = 0;
11579        this.setRatio = _CSSPlugin.prototype.setRatio; //speed optimization (avoid prototype lookup on this "hot" method)
11580      },
11581      _globals = _gsScope._gsDefine.globals,
11582      _hasPriority,
11583      //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.
11584      _suffixMap,
11585      //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
11586      _cs,
11587      //computed style (we store this in a shared variable to conserve memory and make minification tighter
11588      _overwriteProps,
11589      //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.
11590      _specialProps = {},
11591      p = _CSSPlugin.prototype = new TweenPlugin("css");
11592    p.constructor = _CSSPlugin;
11593    _CSSPlugin.version = "1.20.4";
11594    _CSSPlugin.API = 2;
11595    _CSSPlugin.defaultTransformPerspective = 0;
11596    _CSSPlugin.defaultSkewType = "compensated";
11597    _CSSPlugin.defaultSmoothOrigin = true;
11598    p = "px"; //we'll reuse the "p" variable to keep file size down
11599    _CSSPlugin.suffixMap = {
11600      top: p,
11601      right: p,
11602      bottom: p,
11603      left: p,
11604      width: p,
11605      height: p,
11606      fontSize: p,
11607      padding: p,
11608      margin: p,
11609      perspective: p,
11610      lineHeight: ""
11611    };
11612    var _numExp = /(?:\-|\.|\b)(\d|\.|e\-)+/g,
11613      _relNumExp = /(?:\d|\-\d|\.\d|\-\.\d|\+=\d|\-=\d|\+=.\d|\-=\.\d)+/g,
11614      _valuesExp = /(?:\+=|\-=|\-|\b)[\d\-\.]+[a-zA-Z0-9]*(?:%|\b)/gi,
11615      //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)"
11616      _NaNExp = /(?![+-]?\d*\.?\d+|[+-]|e[+-]\d+)[^0-9]/g,
11617      //also allows scientific notation and doesn't kill the leading -/+ in -= and +=
11618      _suffixExp = /(?:\d|\-|\+|=|#|\.)*/g,
11619      _opacityExp = /opacity *= *([^)]*)/i,
11620      _opacityValExp = /opacity:([^;]*)/i,
11621      _alphaFilterExp = /alpha\(opacity *=.+?\)/i,
11622      _rgbhslExp = /^(rgb|hsl)/,
11623      _capsExp = /([A-Z])/g,
11624      _camelExp = /-([a-z])/gi,
11625      _urlExp = /(^(?:url\(\"|url\())|(?:(\"\))$|\)$)/gi,
11626      //for pulling out urls from url(...) or url("...") strings (some browsers wrap urls in quotes, some don't when reporting things like backgroundImage)
11627      _camelFunc = function _camelFunc(s, g) {
11628        return g.toUpperCase();
11629      },
11630      _horizExp = /(?:Left|Right|Width)/i,
11631      _ieGetMatrixExp = /(M11|M12|M21|M22)=[\d\-\.e]+/gi,
11632      _ieSetMatrixExp = /progid\:DXImageTransform\.Microsoft\.Matrix\(.+?\)/i,
11633      _commasOutsideParenExp = /,(?=[^\)]*(?:\(|$))/gi,
11634      //finds any commas that are not within parenthesis
11635      _complexExp = /[\s,\(]/i,
11636      //for testing a string to find if it has a space, comma, or open parenthesis (clues that it's a complex value)
11637      _DEG2RAD = Math.PI / 180,
11638      _RAD2DEG = 180 / Math.PI,
11639      _forcePT = {},
11640      _dummyElement = {
11641        style: {}
11642      },
11643      _doc = _gsScope.document || {
11644        createElement: function createElement() {
11645          return _dummyElement;
11646        }
11647      },
11648      _createElement = function _createElement(type, ns) {
11649        return _doc.createElementNS ? _doc.createElementNS(ns || "http://www.w3.org/1999/xhtml", type) : _doc.createElement(type);
11650      },
11651      _tempDiv = _createElement("div"),
11652      _tempImg = _createElement("img"),
11653      _internals = _CSSPlugin._internals = {
11654        _specialProps: _specialProps
11655      },
11656      //provides a hook to a few internal methods that we need to access from inside other plugins
11657      _agent = (_gsScope.navigator || {}).userAgent || "",
11658      _autoRound,
11659      _reqSafariFix,
11660      //we won't apply the Safari transform fix until we actually come across a tween that affects a transform property (to maintain best performance).
11661
11662      _isSafari,
11663      _isFirefox,
11664      //Firefox has a bug that causes 3D transformed elements to randomly disappear unless a repaint is forced after each update on each element.
11665      _isSafariLT6,
11666      //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!)
11667      _ieVers,
11668      _supportsOpacity = function () {
11669        //we set _isSafari, _ieVers, _isFirefox, and _supportsOpacity all in one function here to reduce file size slightly, especially in the minified version.
11670        var i = _agent.indexOf("Android"),
11671          a = _createElement("a");
11672        _isSafari = _agent.indexOf("Safari") !== -1 && _agent.indexOf("Chrome") === -1 && (i === -1 || parseFloat(_agent.substr(i + 8, 2)) > 3);
11673        _isSafariLT6 = _isSafari && parseFloat(_agent.substr(_agent.indexOf("Version/") + 8, 2)) < 6;
11674        _isFirefox = _agent.indexOf("Firefox") !== -1;
11675        if (/MSIE ([0-9]{1,}[\.0-9]{0,})/.exec(_agent) || /Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/.exec(_agent)) {
11676          _ieVers = parseFloat(RegExp.$1);
11677        }
11678        if (!a) {
11679          return false;
11680        }
11681        a.style.cssText = "top:1px;opacity:.55;";
11682        return /^0.55/.test(a.style.opacity);
11683      }(),
11684      _getIEOpacity = function _getIEOpacity(v) {
11685        return _opacityExp.test(typeof v === "string" ? v : (v.currentStyle ? v.currentStyle.filter : v.style.filter) || "") ? parseFloat(RegExp.$1) / 100 : 1;
11686      },
11687      _log = function _log(s) {
11688        //for logging messages, but in a way that won't throw errors in old versions of IE.
11689        if (_gsScope.console) {
11690          console.log(s);
11691        }
11692      },
11693      _target,
11694      //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
11695      _index,
11696      //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
11697
11698      _prefixCSS = "",
11699      //the non-camelCase vendor prefix like "-o-", "-moz-", "-ms-", or "-webkit-"
11700      _prefix = "",
11701      //camelCase vendor prefix like "O", "ms", "Webkit", or "Moz".
11702
11703      // @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)
11704      _checkPropPrefix = function _checkPropPrefix(p, e) {
11705        e = e || _tempDiv;
11706        var s = e.style,
11707          a,
11708          i;
11709        if (s[p] !== undefined) {
11710          return p;
11711        }
11712        p = p.charAt(0).toUpperCase() + p.substr(1);
11713        a = ["O", "Moz", "ms", "Ms", "Webkit"];
11714        i = 5;
11715        while (--i > -1 && s[a[i] + p] === undefined) {}
11716        if (i >= 0) {
11717          _prefix = i === 3 ? "ms" : a[i];
11718          _prefixCSS = "-" + _prefix.toLowerCase() + "-";
11719          return _prefix + p;
11720        }
11721        return null;
11722      },
11723      _getComputedStyle = _doc.defaultView ? _doc.defaultView.getComputedStyle : function () {},
11724      /**
11725       * @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:
11726       * var currentLeft = CSSPlugin.getStyle( document.getElementById("myElement"), "left");
11727       *
11728       * @param {!Object} t Target element whose style property you want to query
11729       * @param {!string} p Property name (like "left" or "top" or "marginTop", etc.)
11730       * @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.
11731       * @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.
11732       * @param {string=} dflt Default value that should be returned in the place of null, "none", "auto" or "auto auto".
11733       * @return {?string} The current property value
11734       */
11735      _getStyle = _CSSPlugin.getStyle = function (t, p, cs, calc, dflt) {
11736        var rv;
11737        if (!_supportsOpacity) if (p === "opacity") {
11738          //several versions of IE don't use the standard "opacity" property - they use things like filter:alpha(opacity=50), so we parse that here.
11739          return _getIEOpacity(t);
11740        }
11741        if (!calc && t.style[p]) {
11742          rv = t.style[p];
11743        } else if (cs = cs || _getComputedStyle(t)) {
11744          rv = cs[p] || cs.getPropertyValue(p) || cs.getPropertyValue(p.replace(_capsExp, "-$1").toLowerCase());
11745        } else if (t.currentStyle) {
11746          rv = t.currentStyle[p];
11747        }
11748        return dflt != null && (!rv || rv === "none" || rv === "auto" || rv === "auto auto") ? dflt : rv;
11749      },
11750      /**
11751       * @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.
11752       * @param {!Object} t Target element
11753       * @param {!string} p Property name (like "left", "top", "marginLeft", etc.)
11754       * @param {!number} v Value
11755       * @param {string=} sfx Suffix (like "px" or "%" or "em")
11756       * @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.
11757       * @return {number} value in pixels
11758       */
11759      _convertToPixels = _internals.convertToPixels = function (t, p, v, sfx, recurse) {
11760        if (sfx === "px" || !sfx && p !== "lineHeight") {
11761          return v;
11762        }
11763        if (sfx === "auto" || !v) {
11764          return 0;
11765        }
11766        var horiz = _horizExp.test(p),
11767          node = t,
11768          style = _tempDiv.style,
11769          neg = v < 0,
11770          precise = v === 1,
11771          pix,
11772          cache,
11773          time;
11774        if (neg) {
11775          v = -v;
11776        }
11777        if (precise) {
11778          v *= 100;
11779        }
11780        if (p === "lineHeight" && !sfx) {
11781          //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.
11782          cache = _getComputedStyle(t).lineHeight;
11783          t.style.lineHeight = v;
11784          pix = parseFloat(_getComputedStyle(t).lineHeight);
11785          t.style.lineHeight = cache;
11786        } else if (sfx === "%" && p.indexOf("border") !== -1) {
11787          pix = v / 100 * (horiz ? t.clientWidth : t.clientHeight);
11788        } else {
11789          style.cssText = "border:0 solid red;position:" + _getStyle(t, "position") + ";line-height:0;";
11790          if (sfx === "%" || !node.appendChild || sfx.charAt(0) === "v" || sfx === "rem") {
11791            node = t.parentNode || _doc.body;
11792            if (_getStyle(node, "display").indexOf("flex") !== -1) {
11793              //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.
11794              style.position = "absolute";
11795            }
11796            cache = node._gsCache;
11797            time = TweenLite.ticker.frame;
11798            if (cache && horiz && cache.time === time) {
11799              //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)
11800              return cache.width * v / 100;
11801            }
11802            style[horiz ? "width" : "height"] = v + sfx;
11803          } else {
11804            style[horiz ? "borderLeftWidth" : "borderTopWidth"] = v + sfx;
11805          }
11806          node.appendChild(_tempDiv);
11807          pix = parseFloat(_tempDiv[horiz ? "offsetWidth" : "offsetHeight"]);
11808          node.removeChild(_tempDiv);
11809          if (horiz && sfx === "%" && _CSSPlugin.cacheWidths !== false) {
11810            cache = node._gsCache = node._gsCache || {};
11811            cache.time = time;
11812            cache.width = pix / v * 100;
11813          }
11814          if (pix === 0 && !recurse) {
11815            pix = _convertToPixels(t, p, v, sfx, true);
11816          }
11817        }
11818        if (precise) {
11819          pix /= 100;
11820        }
11821        return neg ? -pix : pix;
11822      },
11823      _calculateOffset = _internals.calculateOffset = function (t, p, cs) {
11824        //for figuring out "top" or "left" in px when it's "auto". We need to factor in margin with the offsetLeft/offsetTop
11825        if (_getStyle(t, "position", cs) !== "absolute") {
11826          return 0;
11827        }
11828        var dim = p === "left" ? "Left" : "Top",
11829          v = _getStyle(t, "margin" + dim, cs);
11830        return t["offset" + dim] - (_convertToPixels(t, p, parseFloat(v), v.replace(_suffixExp, "")) || 0);
11831      },
11832      // @private returns at object containing ALL of the style properties in camelCase and their associated values.
11833      _getAllStyles = function _getAllStyles(t, cs) {
11834        var s = {},
11835          i,
11836          tr,
11837          p;
11838        if (cs = cs || _getComputedStyle(t, null)) {
11839          if (i = cs.length) {
11840            while (--i > -1) {
11841              p = cs[i];
11842              if (p.indexOf("-transform") === -1 || _transformPropCSS === p) {
11843                //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
11844                s[p.replace(_camelExp, _camelFunc)] = cs.getPropertyValue(p);
11845              }
11846            }
11847          } else {
11848            //some browsers behave differently - cs.length is always 0, so we must do a for...in loop.
11849            for (i in cs) {
11850              if (i.indexOf("Transform") === -1 || _transformProp === i) {
11851                //Some webkit browsers duplicate transform values, one non-prefixed and one prefixed ("transform" and "WebkitTransform"), so we must weed out the extra one here.
11852                s[i] = cs[i];
11853              }
11854            }
11855          }
11856        } else if (cs = t.currentStyle || t.style) {
11857          for (i in cs) {
11858            if (typeof i === "string" && s[i] === undefined) {
11859              s[i.replace(_camelExp, _camelFunc)] = cs[i];
11860            }
11861          }
11862        }
11863        if (!_supportsOpacity) {
11864          s.opacity = _getIEOpacity(t);
11865        }
11866        tr = _getTransform(t, cs, false);
11867        s.rotation = tr.rotation;
11868        s.skewX = tr.skewX;
11869        s.scaleX = tr.scaleX;
11870        s.scaleY = tr.scaleY;
11871        s.x = tr.x;
11872        s.y = tr.y;
11873        if (_supports3D) {
11874          s.z = tr.z;
11875          s.rotationX = tr.rotationX;
11876          s.rotationY = tr.rotationY;
11877          s.scaleZ = tr.scaleZ;
11878        }
11879        if (s.filters) {
11880          delete s.filters;
11881        }
11882        return s;
11883      },
11884      // @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
11884ontaining 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.
11885      _cssDif = function _cssDif(t, s1, s2, vars, forceLookup) {
11886        var difs = {},
11887          style = t.style,
11888          val,
11889          p,
11890          mpt;
11891        for (p in s2) {
11892          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") {
11893            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.
11894            if (style[p] !== undefined) {
11895              //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.
11896              mpt = new MiniPropTween(style, p, style[p], mpt);
11897            }
11898          }
11899        }
11900        if (vars) {
11901          for (p in vars) {
11902            //copy properties (except className)
11903            if (p !== "className") {
11904              difs[p] = vars[p];
11905            }
11906          }
11907        }
11908        return {
11909          difs: difs,
11910          firstMPT: mpt
11911        };
11912      },
11913      _dimensions = {
11914        width: ["Left", "Right"],
11915        height: ["Top", "Bottom"]
11916      },
11917      _margins = ["marginLeft", "marginRight", "marginTop", "marginBottom"],
11918      /**
11919       * @private Gets the width or height of an element
11920       * @param {!Object} t Target element
11921       * @param {!string} p Property name ("width" or "height")
11922       * @param {Object=} cs Computed style object (if one exists). Just a speed optimization.
11923       * @return {number} Dimension (in pixels)
11924       */
11925      _getDimension = function _getDimension(t, p, cs) {
11926        if ((t.nodeName + "").toLowerCase() === "svg") {
11927          //Chrome no longer supports offsetWidth/offsetHeight on SVG elements.
11928          return (cs || _getComputedStyle(t))[p] || 0;
11929        } else if (t.getCTM && _isSVG(t)) {
11930          return t.getBBox()[p] || 0;
11931        }
11932        var v = parseFloat(p === "width" ? t.offsetWidth : t.offsetHeight),
11933          a = _dimensions[p],
11934          i = a.length;
11935        cs = cs || _getComputedStyle(t, null);
11936        while (--i > -1) {
11937          v -= parseFloat(_getStyle(t, "padding" + a[i], cs, true)) || 0;
11938          v -= parseFloat(_getStyle(t, "border" + a[i] + "Width", cs, true)) || 0;
11939        }
11940        return v;
11941      },
11942      // @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)
11943      _parsePosition2 = function _parsePosition(v, recObj) {
11944        if (v === "contain" || v === "auto" || v === "auto auto") {
11945          //note: Firefox uses "auto auto" as default whereas Chrome uses "auto".
11946          return v + " ";
11947        }
11948        if (v == null || v === "") {
11949          v = "0 0";
11950        }
11951        var a = v.split(" "),
11952          x = v.indexOf("left") !== -1 ? "0%" : v.indexOf("right") !== -1 ? "100%" : a[0],
11953          y = v.indexOf("top") !== -1 ? "0%" : v.indexOf("bottom") !== -1 ? "100%" : a[1],
11954          i;
11955        if (a.length > 3 && !recObj) {
11956          //multiple positions
11957          a = v.split(", ").join(",").split(",");
11958          v = [];
11959          for (i = 0; i < a.length; i++) {
11960            v.push(_parsePosition2(a[i]));
11961          }
11962          return v.join(",");
11963        }
11964        if (y == null) {
11965          y = x === "center" ? "50%" : "0";
11966        } else if (y === "center") {
11967          y = "50%";
11968        }
11969        if (x === "center" || isNaN(parseFloat(x)) && (x + "").indexOf("=") === -1) {
11970          //remember, the user could flip-flop the values and say "bottom center" or "center bottom", etc. "center" is ambiguous because it c
11970ould be used to describe horizontal or vertical, hence the isNaN(). If there's an "=" sign in the value, it's relative.
11971          x = "50%";
11972        }
11973        v = x + " " + y + (a.length > 2 ? " " + a[2] : "");
11974        if (recObj) {
11975          recObj.oxp = x.indexOf("%") !== -1;
11976          recObj.oyp = y.indexOf("%") !== -1;
11977          recObj.oxr = x.charAt(1) === "=";
11978          recObj.oyr = y.charAt(1) === "=";
11979          recObj.ox = parseFloat(x.replace(_NaNExp, ""));
11980          recObj.oy = parseFloat(y.replace(_NaNExp, ""));
11981          recObj.v = v;
11982        }
11983        return recObj || v;
11984      },
11985      /**
11986       * @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!)
11987       * @param {(number|string)} e End value which is typically a string, but could be a number
11988       * @param {(number|string)} b Beginning value which is typically a string but could be a number
11989       * @return {number} Amount of change between the beginning and ending values (relative values that have a "+=" or "-=" are recognized)
11990       */
11991      _parseChange = function _parseChange(e, b) {
11992        if (typeof e === "function") {
11993          e = e(_index, _target);
11994        }
11995        return typeof e === "string" && e.charAt(1) === "=" ? parseInt(e.charAt(0) + "1", 10) * parseFloat(e.substr(2)) : parseFloat(e) - parseFloat(b) || 0;
11996      },
11997      /**
11998       * @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.
11999       * @param {Object} v Value to be parsed
12000       * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
12001       * @return {number} Parsed value
12002       */
12003      _parseVal = function _parseVal(v, d) {
12004        if (typeof v === "function") {
12005          v = v(_index, _target);
12006        }
12007        return v == null ? d : typeof v === "string" && v.charAt(1) === "=" ? parseInt(v.charAt(0) + "1", 10) * parseFloat(v.substr(2)) + d : parseFloat(v) || 0;
12008      },
12009      /**
12010       * @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.
12011       * @param {Object} v Value to be parsed
12012       * @param {!number} d Default value (which is also used for relative calculations if "+=" or "-=" is found in the first parameter)
12013       * @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"
12014       * @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.
12015       * @return {number} parsed angle in radians
12016       */
12017      _parseAngle = function _parseAngle(v, d, p, directionalEnd) {
12018        var min = 0.000001,
12019          cap,
12020          split,
12021          dif,
12022          result,
12023          isRelative;
12024        if (typeof v === "function") {
12025          v = v(_index, _target);
12026        }
12027        if (v == null) {
12028          result = d;
12029        } else if (typeof v === "number") {
12030          result = v;
12031        } else {
12032          cap = 360;
12033          split = v.split("_");
12034          isRelative = v.charAt(1) === "=";
12035          dif = (isRelative ? parseInt(v.charAt(0) + "1", 10) * parseFloat(split[0].substr(2)) : parseFloat(split[0])
12035) * (v.indexOf("rad") === -1 ? 1 : _RAD2DEG) - (isRelative ? 0 : d);
12036          if (split.length) {
12037            if (directionalEnd) {
12038              directionalEnd[p] = d + dif;
12039            }
12040            if (v.indexOf("short") !== -1) {
12041              dif = dif % cap;
12042              if (dif !== dif % (cap / 2)) {
12043                dif = dif < 0 ? dif + cap : dif - cap;
12044              }
12045            }
12046            if (v.indexOf("_cw") !== -1 && dif < 0) {
12047              dif = (dif + cap * 9999999999) % cap - (dif / cap | 0) * cap;
12048            } else if (v.indexOf("ccw") !== -1 && dif > 0) {
12049              dif = (dif - cap * 9999999999) % cap - (dif / cap | 0) * cap;
12050            }
12051          }
12052          result = d + dif;
12053        }
12054        if (result < min && result > -min) {
12055          result = 0;
12056        }
12057        return result;
12058      },
12059      _colorLookup = {
12060        aqua: [0, 255, 255],
12061        lime: [0, 255, 0],
12062        silver: [192, 192, 192],
12063        black: [0, 0, 0],
12064        maroon: [128, 0, 0],
12065        teal: [0, 128, 128],
12066        blue: [0, 0, 255],
12067        navy: [0, 0, 128],
12068        white: [255, 255, 255],
12069        fuchsia: [255, 0, 255],
12070        olive: [128, 128, 0],
12071        yellow: [255, 255, 0],
12072        orange: [255, 165, 0],
12073        gray: [128, 128, 128],
12074        purple: [128, 0, 128],
12075        green: [0, 128, 0],
12076        red: [255, 0, 0],
12077        pink: [255, 192, 203],
12078        cyan: [0, 255, 255],
12079        transparent: [255, 255, 255, 0]
12080      },
12081      _hue = function _hue(h, m1, m2) {
12082        h = h < 0 ? h + 1 : h > 1 ? h - 1 : h;
12083        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;
12084      },
12085      /**
12086       * @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).
12087       * @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.
12088       * @param {(boolean)} toHSL If true, an hsl() or hsla() value will be returned instead of rgb() or rgba()
12089       * @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.
12090       */
12091      _parseColor = _CSSPlugin.parseColor = function (v, toHSL) {
12092        var a, r, g, b, h, s, l, max, min, d, wasHSL;
12093        if (!v) {
12094          a = _colorLookup.black;
12095        } else if (typeof v === "number") {
12096          a = [v >> 16, v >> 8 & 255, v & 255];
12097        } else {
12098          if (v.charAt(v.length - 1) === ",") {
12099            //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.
12100            v = v.substr(0, v.length - 1);
12101          }
12102          if (_colorLookup[v]) {
12103            a = _colorLookup[v];
12104          } else if (v.charAt(0) === "#") {
12105            if (v.length === 4) {
12106              //for shorthand like #9F0
12107              r = v.charAt(1);
12108              g = v.charAt(2);
12109              b = v.charAt(3);
12110              v = "#" + r + r + g + g + b + b;
12111            }
12112            v = parseInt(v.substr(1), 16);
12113            a = [v >> 16, v >> 8 & 255, v & 255];
12114          } else if (v.substr(0, 3) === "hsl") {
12115            a = wasHSL = v.match(_numExp);
12116            if (!toHSL) {
12117              h = Number(a[0]) % 360 / 360;
12118              s = Number(a[1]) / 100;
12119              l = Number(a[2]) / 100;
12120              g = l <= 0.5 ? l * (s + 1) : l + s - l * s;
12121              r = l * 2 - g;
12122              if (a.length > 3) {
12123                a[3] = Number(a[3]);
12124              }
12125              a[0] = _hue(h + 1 / 3, r, g);
12126              a[1] = _hue(h, r, g);
12127              a[2] = _hue(h - 1 / 3, r, g);
12128            } else if (v.indexOf("=") !== -1) {
12129              //if relative values are found, just return the raw strings with the relative prefixes in place.
12130              return v.match(_relNumExp);
12131            }
12132          } else {
12133            a = v.match(_numExp) || _colorLookup.transparent;
12134          }
12135          a[0] = Number(a[0]);
12136          a[1] = Number(a[1]);
12137          a[2] = Number(a[2]);
12138          if (a.length > 3) {
12139            a[3] = Number(a[3]);
12140          }
12141        }
12142        if (toHSL && !wasHSL) {
12143          r = a[0] / 255;
12144          g = a[1] / 255;
12145          b = a[2] / 255;
12146          max = Math.max(r, g, b);
12147          min = Math.min(r, g, b);
12148          l = (max + min) / 2;
12149          if (max === min) {
12150            h = s = 0;
12151          } else {
12152            d = max - min;
12153            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
12154            h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
12155            h *= 60;
12156          }
12157          a[0] = h + 0.5 | 0;
12158          a[1] = s * 100 + 0.5 | 0;
12159          a[2] = l * 100 + 0.5 | 0;
12160        }
12161        return a;
12162      },
12163      _formatColors = function _formatColors(s, toHSL) {
12164        var colors = s.match(_colorExp) || [],
12165          charIndex = 0,
12166          parsed = "",
12167          i,
12168          color,
12169          temp;
12170        if (!colors.length) {
12171          return s;
12172        }
12173        for (i = 0; i < colors.length; i++) {
12174          color = colors[i];
12175          temp = s.substr(charIndex, s.indexOf(color, charIndex) - charIndex);
12176          charIndex += temp.length + color.length;
12177          color = _parseColor(color, toHSL);
12178          if (color.length === 3) {
12179            color.push(1);
12180          }
12181          parsed += temp + (toHSL ? "hsla(" + color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : "rgba(" + color.
12181join(",")) + ")";
12182        }
12183        return parsed + s.substr(charIndex);
12184      },
12185      _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.
12186
12187    for (p in _colorLookup) {
12188      _colorExp += "|" + p + "\\b";
12189    }
12190    _colorExp = new RegExp(_colorExp + ")", "gi");
12191    _CSSPlugin.colorStringFilter = function (a) {
12192      var combined = a[0] + " " + a[1],
12193        toHSL;
12194      if (_colorExp.test(combined)) {
12195        toHSL = combined.indexOf("hsl(") !== -1 || combined.indexOf("hsla(") !== -1;
12196        a[0] = _formatColors(a[0], toHSL);
12197        a[1] = _formatColors(a[1], toHSL);
12198      }
12199      _colorExp.lastIndex = 0;
12200    };
12201    if (!TweenLite.defaultStringFilter) {
12202      TweenLite.defaultStringFilter = _CSSPlugin.colorStringFilter;
12203    }
12204
12205    /**
12206     * @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.
12207     * @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.
12208     * @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.
12209     * @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.
12210     * @return {Function} formatter function
12211     */
12212    var _getFormatter = function _getFormatter(dflt, clr, collapsible, multi) {
12213        if (dflt == null) {
12214          return function (v) {
12215            return v;
12216          };
12217        }
12218        var dColor = clr ? (dflt.match(_colorExp) || [""])[0] : "",
12219          dVals = dflt.split(dColor).join("").match(_valuesExp) || [],
12220          pfx = dflt.substr(0, dflt.indexOf(dVals[0])),
12221          sfx = dflt.charAt(dflt.length - 1) === ")" ? ")" : "",
12222          delim = dflt.indexOf(" ") !== -1 ? " " : ",",
12223          numVals = dVals.length,
12224          dSfx = numVals > 0 ? dVals[0].replace(_numExp, "") : "",
12225          _formatter2;
12226        if (!numVals) {
12227          return function (v) {
12228            return v;
12229          };
12230        }
12231        if (clr) {
12232          _formatter2 = function formatter(v) {
12233            var color, vals, i, a;
12234            if (typeof v === "number") {
12235              v += dSfx;
12236            } else if (multi && _commasOutsideParenExp.test(v)) {
12237              a = v.replace(_commasOutsideParenExp, "|").split("|");
12238              for (i = 0; i < a.length; i++) {
12239                a[i] = _formatter2(a[i]);
12240              }
12241              return a.join(",");
12242            }
12243            color = (v.match(_colorExp) || [dColor])[0];
12244            vals = v.split(color).join("").match(_valuesExp) || [];
12245            i = vals.length;
12246            if (numVals > i--) {
12247              while (++i < numVals) {
12248                vals[i] = collapsible ? vals[(i - 1) / 2 | 0] : dVals[i];
12249              }
12250            }
12251            return pfx + vals.join(delim) + delim + color + sfx + (v.indexOf("inset") !== -1 ? " inset" : "");
12252          };
12253          return _formatter2;
12254        }
12255        _formatter2 = function _formatter(v) {
12256          var vals, a, i;
12257          if (typeof v === "number") {
12258            v += dSfx;
12259          } else if (multi && _commasOutsideParenExp.test(v)) {
12260            a = v.replace(_commasOutsideParenExp, "|").split("|");
12261            for (i = 0; i < a.length; i++) {
12262              a[i] = _formatter2(a[i]);
12263            }
12264            return a.join(",");
12265          }
12266          vals = v.match(_valuesExp) || [];
12267          i = vals.length;
12268          if (numVals > i--) {
12269            while (++i < numVals) {
12270              vals[i] = collapsible ? vals[(i - 1) / 2 | 0] : dVals[i];
12271            }
12272          }
12273          return pfx + vals.join(delim) + sfx;
12274        };
12275        return _formatter2;
12276      },
12277      /**
12278       * @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.
12279       * @param {!string} props a comma-delimited list of property names in order from top to left, like "marginTop,marginRight,marginBottom,marginLeft"
12280       * @return {Function} a formatter function
12281       */
12282      _getEdgeParser = function _getEdgeParser(props) {
12283        props = props.split(",");
12284        return function (t, e, p, cssp, pt, plugin, vars) {
12285          var a = (e + "").split(" "),
12286            i;
12287          vars = {};
12288          for (i = 0; i < 4; i++) {
12289            vars[props[i]] = a[i] = a[i] || a[(i - 1) / 2 >> 0];
12290          }
12291          return cssp.parse(t, vars, pt, plugin);
12292        };
12293      },
12294      // @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.
12295      _setPluginRatio = _internals._setPluginRatio = function (v) {
12296        this.plugin.setRatio(v);
12297        var d = this.data,
12298          proxy = d.proxy,
12299          mpt = d.firstMPT,
12300          min = 0.000001,
12301          val,
12302          pt,
12303          i,
12304          str,
12305          p;
12306        while (mpt) {
12307          val = proxy[mpt.v];
12308          if (mpt.r) {
12309            val = Math.round(val);
12310          } else if (val < min && val > -min) {
12311            val = 0;
12312          }
12313          mpt.t[mpt.p] = val;
12314          mpt = mpt._next;
12315        }
12316        if (d.autoRotate) {
12317          d.autoRotate.rotation = d.mod ? d.mod(proxy.rotation, this.t) : proxy.rotation; //special case for ModifyPlugin to hook into an auto-rotating bezier
12318        }
12319        //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.
12320        if (v === 1 || v === 0) {
12321          mpt = d.firstMPT;
12322          p = v === 1 ? "e" : "b";
12323          while (mpt) {
12324            pt = mpt.t;
12325            if (!pt.type) {
12326              pt[p] = pt.s + pt.xs0;
12327            } else if (pt.type === 1) {
12328              str = pt.xs0 + pt.s + pt.xs1;
12329              for (i = 1; i < pt.l; i++) {
12330                str += pt["xn" + i] + pt["xs" + (i + 1)];
12331              }
12332              pt[p] = str;
12333            }
12334            mpt = mpt._next;
12335          }
12336        }
12337      },
12338      /**
12339       * @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
12339ded plus the original value.
12340       * @param {!Object} t target object whose property we're tweening (often a CSSPropTween)
12341       * @param {!string} p property name
12342       * @param {(number|string|object)} v value
12343       * @param {MiniPropTween=} next next MiniPropTween in the linked list
12344       * @param {boolean=} r if true, the tweened value should be rounded to the nearest integer
12345       */
12346      MiniPropTween = function MiniPropTween(t, p, v, next, r) {
12347        this.t = t;
12348        this.p = p;
12349        this.v = v;
12350        this.r = r;
12351        if (next) {
12352          next._prev = this;
12353          this._next = next;
12354        }
12355      },
12356      /**
12357       * @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.
12358       * This method returns an object that has the following properties:
12359       *  - 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
12360       *  - 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
12361       *  - firstMPT: the first MiniPropTween in the linked list
12362       *  - 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.
12363       * @param {!Object} t target object to be tweened
12364       * @param {!(Object|string)} vars the object containing the information about the tweening values (typically the end/destination values) that should be parsed
12365       * @param {!CSSPlugin} cssp The CSSPlugin instance
12366       * @param {CSSPropTween=} pt the next CSSPropTween in the linked list
12367       * @param {TweenPlugin=} plugin the external TweenPlugin instance that will be handling tweening the numeric values
12368       * @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.
12369       * @return An object containing the following properties: proxy, end, firstMPT, and pt (see above for descriptions)
12370       */
12371      _parseToProxy = _internals._parseToProxy = function (t, vars, cssp, pt, plugin, shallow) {
12372        var bpt = pt,
12373          start = {},
12374          end = {},
12375          transform = cssp._transform,
12376          oldForce = _forcePT,
12377          i,
12378          p,
12379          xp,
12380          mpt,
12381          firstPT;
12382        cssp._transform = null;
12383        _forcePT = vars;
12384        pt = firstPT = cssp.parse(t, vars, pt, plugin);
12385        _forcePT = oldForce;
12386        //break off from the linked list so the new ones are isolated.
12387        if (shallow) {
12388          cssp._transform = transform;
12389          if (bpt) {
12390            bpt._prev = null;
12391            if (bpt._prev) {
12392              bpt._prev._next = null;
12393            }
12394          }
12395        }
12396        while (pt && pt !== bpt) {
12397          if (pt.type <= 1) {
12398            p = pt.p;
12399            end[p] = pt.s + pt.c;
12400            start[p] = pt.s;
12401            if (!shallow) {
12402              mpt = new MiniPropTween(pt, "s", p, mpt, pt.r);
12403              pt.c = 0;
12404            }
12405            if (pt.type === 1) {
12406              i = pt.l;
12407              while (--i > 0) {
12408                xp = "xn" + i;
12409                p = pt.p + "_" + xp;
12410                end[p] = pt.data[xp];
12411                start[p] = pt[xp];
12412                if (!shallow) {
12413                  mpt = new MiniPropTween(pt, xp, p, mpt, pt.rxp[xp]);
12414                }
12415              }
12416            }
12417          }
12418          pt = pt._next;
12419        }
12420        return {
12421          proxy: start,
12422          end: end,
12423          firstMPT: mpt,
12424          pt: firstPT
12425        };
12426      },
12427      /**
12428       * @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.
12429       * CSSPropTweens have the following optional properties as well (not defined through the constructor):
12430       *  - 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.
12431       *  - 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)
12432       *  - plugin: The TweenPlugin instance that will handle the tweening of any complex values. For example, sometimes we don't want to use normal subt
12432weens (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.
12433       *  - 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.
12434       *  - 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.
12435       * @param {!Object} t Target object whose property will be tweened. Often a DOM element, but not always. It could be anything.
12436       * @param {string} p Property to tween (name). For example, to tween element.width, p would be "width".
12437       * @param {number} s Starting numeric value
12438       * @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.
12439       * @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.
12440       * @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.
12441       * @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"
12442       * @param {boolean=} r If true, the value(s) should be rounded
12443       * @param {number=} pr Priority in the linked list order. Higher priority CSSPropTweens will be updated before lower priority ones. The default priority is 0.
12444       * @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.
12445       * @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.
12446       */
12447      CSSPropTween = _internals.CSSPropTween = function (t, p, s, c, next, type, n, r, pr, b, e) {
12448        this.t = t; //target
12449        this.p = p; //property
12450        this.s = s; //starting value
12451        this.c = c; //change value
12452        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)
12453        if (!(t instanceof CSSPropTween)) {
12454          _overwriteProps.push(this.n);
12455        }
12456        this.r = r; //round (boolean)
12457        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
12458        if (pr) {
12459          this.pr = pr;
12460          _hasPriority = true;
12461        }
12462        this.b = b === undefined ? s : b;
12463        this.e = e === undefined ? s + c : e;
12464        if (next) {
12465          this._next = next;
12466          next._prev = this;
12467        }
12468      },
12469      _addNonTweeningNumericPT = function _addNonTweeningNumericPT(target, prop, start, end, next, overwriteProp) {
12470        //cleans up some code redundancies and helps minification. Just a fast way to add a NUMERIC non-tweening CSSPropTween
12471        var pt = new CSSPropTween(target, prop, start, end - start, next, -1, overwriteProp);
12472        pt.b = start;
12473        pt.e = pt.xs0 = end;
12474        return pt;
12475      },
12476      /**
12477       * 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:
12478       * 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);
12479       * 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().
12480       * 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.
12481       *
12482       * @param {!Object} t Target whose property will be tweened
12483       * @param {!string} p Property that will be tweened (its name, like "left" or "backgroundColor" or "boxShadow")
12484       * @param {string} b Beginning value
12485       * @param {string} e Ending value
12486       * @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)
12487       * @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
12488       * @param {?CSSPropTween} pt CSSPropTween instance that is the current head of the linked list (we'll prepend to this).
12489       * @param {number=} pr Priority in the linked list order. Higher priority properties will be updated before lower priority ones. The default priority is 0.
12490       * @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}
12491       * @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.
12492       * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parseComplex() call.
12493       */
12494      _parseComplex = _CSSPlugin.parseComplex = function (t, p, b, e, clrs, dflt, pt, pr, plugin, setRatio) {
12495        //DEBUG: _log("parseComplex: "+p+", b: "+b+", e: "+e);
12496        b = b || dflt || "";
12497        if (typeof e === "function") {
12498          e = e(_index, _target);
12499        }
12500        pt = new CSSPropTween(t, p, 0, 0, pt, setRatio ? 2 : 1, null, false, pr, b, e);
12501        e += ""; //ensures it's a string
12502        if (clrs && _colorExp.test(e + b)) {
12503          //if colors are found, normalize the formatting to rgba() or hsla().
12504          e = [b, e];
12505          _CSSPlugin.colorStringFilter(e);
12506          b = e[0];
12507          e = e[1];
12508        }
12509        var ba = b.split(", ").join(",").split(" "),
12510          //beginning array
12511          ea = e.split(", ").join(",").split(" "),
12512          //ending array
12513          l = ba.length,
12514          autoRound = _autoRound !== false,
12515          i,
12516          xi,
12517          ni,
12518          bv,
12519          ev,
12520          bnums,
12521          enums,
12522          bn,
12523          hasAlpha,
12524          temp,
12525          cv,
12526          str,
12527          useHSL;
12528        if (e.indexOf(",") !== -1 || b.indexOf(",") !== -1) {
12529          if ((e + b).indexOf("rgb") !== -1 || (e + b).indexOf("hsl") !== -1) {
12530            //keep rgb(), rgba(), hsl(), and hsla() values together! (remember, we're splitting on spaces)
12531            ba = ba.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
12532            ea = ea.join(" ").replace(_commasOutsideParenExp, ", ").split(" ");
12533          } else {
12534            ba = ba.join(" ").split(",").join(", ").split(" ");
12535            ea = ea.join(" ").split(",").join(", ").split(" ");
12536          }
12537          l = ba.length;
12538        }
12539        if (l !== ea.length) {
12540          //DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
12541          ba = (dflt || "").split(" ");
12542          l = ba.length;
12543        }
12544        pt.plugin = plugin;
12545        pt.setRatio = setRatio;
12546        _colorExp.lastIndex = 0;
12547        for (i = 0; i < l; i++) {
12548          bv = ba[i];
12549          ev = ea[i];
12550          bn = parseFloat(bv);
12551          //if the value begins with a number (most common). It's fine if it has a suffix like px
12552          if (bn || bn === 0) {
12553            pt.appendXtra("", bn, _parseChange(ev, bn), ev.replace(_relNumExp, ""), autoRound && ev.indexOf("px") !== -1, true);
12554
12555            //if the value is a color
12556          } else if (clrs && _colorExp.test(bv)) {
12557            str = ev.indexOf(")") + 1;
12558            str = ")" + (str ? ev.substr(str) : ""); //if there's a comma or ) at the end, retain it.
12559            useHSL = ev.indexOf("hsl") !== -1 && _supportsOpacity;
12560            temp = ev; //original string value so we can look for any prefix later.
12561            bv = _parseColor(bv, useHSL);
12562            ev = _parseColor(ev, useHSL);
12563            hasAlpha = bv.length + ev.length > 6;
12564            if (hasAlpha && !_supportsOpacity && ev[3] === 0) {
12565              //older versions of IE don't support rgba(), so if the destination alpha is 0, just use "transparent" for the end color
12566              pt["xs" + pt.l] += pt.l ? " transparent" : "transparent";
12567              pt.e = pt.e.split(ea[i]).join("transparent");
12568            } else {
12569              if (!_supportsOpacity) {
12570                //old versions of IE don't support rgba().
12571                hasAlpha = false;
12572              }
12573              if (useHSL) {
12574                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);
12575              } else {
12576                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);
12577              }
12578              if (hasAlpha) {
12579                bv = bv.length < 4 ? 1 : bv[3];
12580                pt.appendXtra("", bv, (ev.length < 4 ? 1 : ev[3]) - bv, str, false);
12581              }
12582            }
12583            _colorExp.lastIndex = 0; //otherwise the test() on the RegExp could move the lastIndex and taint future results.
12584          } else {
12585            bnums = bv.match(_numExp); //gets each group of numbers in the beginning value string and drops them into an array
12586
12587            //if no number is found, treat it as a non-tweening value and just append the string to the current xs.
12588            if (!bnums) {
12589              pt["xs" + pt.l] += pt.l || pt["xs" + pt.l] ? " " + ev : ev;
12590
12591              //loop through all the numbers that are found and construct the extra values on the pt.
12592            } else {
12593              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
12594              if (!enums || enums.length !== bnums.length) {
12595                //DEBUG: _log("mismatched formatting detected on " + p + " (" + b + " vs " + e + ")");
12596                return pt;
12597              }
12598              ni = 0;
12599              for (xi = 0; xi < bnums.length; xi++) {
12600                cv = bnums[xi];
12601                temp = bv.indexOf(cv, ni);
12602                pt.appendXtra(bv.substr(ni, temp - ni), Number(cv), _parseChange(enums[xi], cv), "", autoRound && bv.substr(temp + cv.length, 2) === "px", xi === 0);
12603                ni = temp + cv.length;
12604              }
12605              pt["xs" + pt.l] += bv.substr(ni);
12606            }
12607          }
12608        }
12609        //if there are relative values ("+=" or "-=" prefix), we need to adjust the ending value to eliminate the prefixes and combine the values properly.
12610        if (e.indexOf("=") !== -1) if (pt.data) {
12611          str = pt.xs0 + pt.data.s;
12612          for (i = 1; i < pt.l; i++) {
12613            str += pt["xs" + i] + pt.data["xn" + i];
12614          }
12615          pt.e = str + pt["xs" + i];
12616        }
12617        if (!pt.l) {
12618          pt.type = -1;
12619          pt.xs0 = pt.e;
12620        }
12621        return pt.xfirst || pt;
12622      },
12623      i = 9;
12624    p = CSSPropTween.prototype;
12625    p.l = p.pr = 0; //length (number of extra properties like xn1, xn2, xn3, etc.
12626    while (--i > 0) {
12627      p["xn" + i] = 0;
12628      p["xs" + i] = "";
12629    }
12630    p.xs0 = "";
12631    p._next = p._prev = p.xfirst = p.data = p.plugin = p.setRatio = p.rxp = null;
12632
12633    /**
12634     * 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:
12635     * xs0:"rect(", s:10, xs1:"px, ", xn1:5, xs2:"px, ", xn2:0, xs3:"px, ", xn3:20, xn4:"px)"
12636     * And they'd all get joined together when the CSSPlugin renders (in the setRatio() method).
12637     * @param {string=} pfx Prefix (if any)
12638     * @param {!number} s Starting value
12639     * @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.
12640     * @param {string=} sfx Suffix (if any)
12641     * @param {boolean=} r Round (if true).
12642     * @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.
12643     * @return {CSSPropTween} returns itself so that multiple methods can be chained together.
12644     */
12645    p.appendXtra = function (pfx, s, c, sfx, r, pad) {
12646      var pt = this,
12647        l = pt.l;
12648      pt["xs" + l] += pad && (l || pt["xs" + l]) ? " " + pfx : pfx || "";
12649      if (!c) if (l !== 0 && !pt.plugin) {
12650        //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!
12651        pt["xs" + l] += s + (sfx || "");
12652        return pt;
12653      }
12654      pt.l++;
12655      pt.type = pt.setRatio ? 2 : 1;
12656      pt["xs" + pt.l] = sfx || "";
12657      if (l > 0) {
12658        pt.data["xn" + l] = s + c;
12659        pt.rxp["xn" + l] = r; //round extra property (we need to tap into this in the _parseToProxy() method)
12660        pt["xn" + l] = s;
12661        if (!pt.plugin) {
12662          pt.xfirst = new CSSPropTween(pt, "xn" + l, s, c, pt.xfirst || pt, 0, pt.n, r, pt.pr);
12663          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.
12664        }
12665        return pt;
12666      }
12667      pt.data = {
12668        s: s + c
12669      };
12670      pt.rxp = {};
12671      pt.s = s;
12672      pt.c = c;
12673      pt.r = r;
12674      return pt;
12675    };
12676
12677    /**
12678     * @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.
12679     * @param {!string} p Property name (like "boxShadow" or "throwProps")
12680     * @param {Object=}
12680 options An object containing any of the following configuration options:
12681     *                      - defaultValue: the default value
12682     *                      - 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)
12683     *                      - 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.)
12684     *                      - prefix: if true, we'll determine whether or not this property requires a vendor prefix (like Webkit or Moz or ms or O)
12685     *                      - color: set this to true if the value for this SpecialProp may contain color-related values like rgb(), rgba(), etc.
12686     *                      - priority: priority in the linked list order. Higher priority SpecialProps will be updated before lower priority ones. The default priority is 0.
12687     *                      - multi: if true, the formatter should accommodate a comma-delimited list of values, like boxShadow could have multiple boxShadows listed out.
12688     *                      - 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.
12689     *                      - 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).
12690     */
12691    var SpecialProp = function SpecialProp(p, options) {
12692        options = options || {};
12693        this.p = options.prefix ? _checkPropPrefix(p) || p : p;
12694        _specialProps[p] = _specialProps[this.p] = this;
12695        this.format = options.formatter || _getFormatter(options.defaultValue, options.color, options.collapsible, options.multi);
12696        if (options.parser) {
12697          this.parse = options.parser;
12698        }
12699        this.clrs = options.color;
12700        this.multi = options.multi;
12701        this.keyword = options.keyword;
12702        this.dflt = options.defaultValue;
12703        this.pr = options.priority || 0;
12704      },
12705      //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.
12706      _registerComplexSpecialProp = _internals._registerComplexSpecialProp = function (p, options, defaults) {
12707        if (_typeof(options) !== "object") {
12708          options = {
12709            parser: defaults
12710          }; //to make backwards compatible with older versions of BezierPlugin and ThrowPropsPlugin
12711        }
12712        var a = p.split(","),
12713          d = options.defaultValue,
12714          i,
12715          temp;
12716        defaults = defaults || [d];
12717        for (i = 0; i < a.length; i++) {
12718          options.prefix = i === 0 && options.prefix;
12719          options.defaultValue = defaults[i] || d;
12720          temp = new SpecialProp(a[i], options);
12721        }
12722      },
12723      //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.
12724      _registerPluginProp = _internals._registerPluginProp = function (p) {
12725        if (!_specialProps[p]) {
12726          var pluginName = p.charAt(0).toUpperCase() + p.substr(1) + "Plugin";
12727          _registerComplexSpecialProp(p, {
12728            parser: function parser(t, e, p, cssp, pt, plugin, vars) {
12729              var pluginClass = _globals.com.greensock.plugins[pluginName];
12730              if (!pluginClass) {
12731                _log("Error: " + pluginName + " js file not loaded.");
12732                return pt;
12733              }
12734              pluginClass._cssRegister();
12735              return _specialProps[p].parse(t, e, p, cssp, pt, plugin, vars);
12736            }
12737          });
12738        }
12739      };
12740    p = SpecialProp.prototype;
12741
12742    /**
12743     * 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
12743adow) 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)
12744     * @param {!Object} t target element
12745     * @param {(string|number|object)} b beginning value
12746     * @param {(string|number|object)} e ending (destination) value
12747     * @param {CSSPropTween=} pt next CSSPropTween in the linked list
12748     * @param {TweenPlugin=} plugin If another plugin will be tweening the complex value, that TweenPlugin instance goes here.
12749     * @param {function=} setRatio If a custom setRatio() method should be used to handle this complex value, that goes here.
12750     * @return {CSSPropTween=} First CSSPropTween in the linked list
12751     */
12752    p.parseComplex = function (t, b, e, pt, plugin, setRatio) {
12753      var kwd = this.keyword,
12754        i,
12755        ba,
12756        ea,
12757        l,
12758        bi,
12759        ei;
12760      //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)
12761      if (this.multi) if (_commasOutsideParenExp.test(e) || _commasOutsideParenExp.test(b)) {
12762        ba = b.replace(_commasOutsideParenExp, "|").split("|");
12763        ea = e.replace(_commasOutsideParenExp, "|").split("|");
12764      } else if (kwd) {
12765        ba = [b];
12766        ea = [e];
12767      }
12768      if (ea) {
12769        l = ea.length > ba.length ? ea.length : ba.length;
12770        for (i = 0; i < l; i++) {
12771          b = ba[i] = ba[i] || this.dflt;
12772          e = ea[i] = ea[i] || this.dflt;
12773          if (kwd) {
12774            bi = b.indexOf(kwd);
12775            ei = e.indexOf(kwd);
12776            if (bi !== ei) {
12777              if (ei === -1) {
12778                //if the keyword isn't in the end value, remove it from the beginning one.
12779                ba[i] = ba[i].split(kwd).join("");
12780              } else if (bi === -1) {
12781                //if the keyword isn't in the beginning, add it.
12782                ba[i] += " " + kwd;
12783              }
12784            }
12785          }
12786        }
12787        b = ba.join(", ");
12788        e = ea.join(", ");
12789      }
12790      return _parseComplex(t, this.p, b, e, this.clrs, this.dflt, pt, this.pr, plugin, setRatio);
12791    };
12792
12793    /**
12794     * 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:
12795     * this._firstPT = sp.parse(element, "5px 10px 20px rgb(2550,102,51)", "boxShadow", this);
12796     * 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).
12797     * @param {!Object} t Target object whose property is being tweened
12798     * @param {Object} e End value as provided in the vars object (typically a string, but not always - like a throwProps would be an object).
12799     * @param {!string} p Property name
12800     * @param {!CSSPlugin} cssp The CSSPlugin instance that should be associated with this tween.
12801     * @param {?CSSPropTween} pt The CSSPropTween that is the current head of the linked list (we'll prepend to it)
12802     * @param {TweenPlugin=} plugin If a plugin will be used to tween the parsed value, this is the plugin instance.
12803     * @param {Object=} vars Original vars object that contains the data for parsing.
12804     * @return {CSSPropTween} The first CSSPropTween in the linked list which includes the new one(s) added by the parse() call.
12805     */
12806    p.parse = function (t, e, p, cssp, pt, plugin, vars) {
12807      return this.parseComplex(t.style, this.format(_getStyle(t, this.p, _cs, false, this.dflt)), this.format(e), pt, plugin);
12808    };
12809
12810    /**
12811     * 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:
12812     *  1) Target object whose property should be tweened (typically a DOM element)
12813     *  2) The end/destination value (could be a string, number, object, or whatever you want)
12814     *  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)
12815     *
12816     * 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:
12817     *
12818     * CSSPlugin.registerSpecialProp("myCustomProp", function(target, value, tween) {
12819     *      var start = target.style.width;
12820     *      return function(ratio) {
12821     *              target.style.width = (start + value * ratio) + "px";
12822     *              console.log("set width to " + target.style.width);
12823     *          }
12824     * }, 0);
12825     *
12826     * Then, when I do this tween, it will trigger my special property:
12827     *
12828     * TweenLite.to(element, 1, {css:{myCustomProp:100}});
12829     *
12830     * In the example, of course, we're just changing the width, but you can do anything you want.
12831     *
12832     * @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}})
12833     * @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.
12834     * @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.
12835     */
12836    _CSSPlugin.registerSpecialProp = function (name, onInitTween, priority) {
12837      _registerComplexSpecialProp(name, {
12838        parser: function parser(t, e, p, cssp, pt, plugin, vars) {
12839          var rv = new CSSPropTween(t, p, 0, 0, pt, 2, p, false, priority);
12840          rv.plugin = plugin;
12841          rv.setRatio = onInitTween(t, e, cssp._tween, p);
12842          return rv;
12843        },
12844        priority: priority
12845      });
12846    };
12847
12848    //transform-related methods and properties
12849    _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).
12850    var _transformProps = "scaleX,scaleY,scaleZ,x,y,z,skewX,skewY,rotation,rotationX,rotationY,perspective,xPercent,yPercent".split(","),
12851      _transformProp = _checkPropPrefix("transform"),
12852      //the Javascript (camelCase) transform property, like msTransform, WebkitTransform, MozTransform, or OTransform.
12853      _transformPropCSS = _prefixCSS + "transform",
12854      _transformOriginProp = _checkPropPrefix("transformOrigin"),
12855      _supports3D = _checkPropPrefix("perspective") !== null,
12856      Transform = _internals.Transform = function () {
12857        this.perspective = parseFloat(_CSSPlugin.defaultTransformPerspective) || 0;
12858        this.force3D = _CSSPlugin.defaultForce3D === false || !_supports3D ? false : _CSSPlugin.defaultForce3D || "auto";
12859      },
12860      _SVGElement = _gsScope.SVGElement,
12861      _useSVGTransformAttr,
12862      //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.
12863
12864      _createSVG = function _createSVG(type, container, attributes) {
12865        var element = _doc.createElementNS("http://www.w3.org/2000/svg", type),
12866          reg = /([a-z])([A-Z])/g,
12867          p;
12868        for (p in attributes) {
12869          element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]);
12870        }
12871        container.appendChild(element);
12872        return element;
12873      },
12874      _docElement = _doc.documentElement || {},
12875      _forceSVGTransformAttr = function () {
12876        //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
12877        var force = _ieVers || /Android/i.test(_agent) && !_gsScope.chrome,
12878          svg,
12879          rect,
12880          width;
12881        if (_doc.createElementNS && !force) {
12882          //IE8 and earlier doesn't support SVG anyway
12883          svg = _createSVG("svg", _docElement);
12884          rect = _createSVG("rect", svg, {
12885            width: 100,
12886            height: 50,
12887            x: 100
12888          });
12889          width = rect.getBoundingClientRect().width;
12890          rect.style[_transformOriginProp] = "50% 50%";
12891          rect.style[_transformProp] = "scaleX(0.5)";
12892          force = width === rect.getBoundingClientRect().width && !(_is
12892Firefox && _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).
12893          _docElement.removeChild(svg);
12894        }
12895        return force;
12896      }(),
12897      _parseSVGOrigin = function _parseSVGOrigin(e, local, decoratee, absolute, smoothOrigin, skipRecord) {
12898        var tm = e._gsTransform,
12899          m = _getMatrix(e, true),
12900          v,
12901          x,
12902          y,
12903          xOrigin,
12904          yOrigin,
12905          a,
12906          b,
12907          c,
12908          d,
12909          tx,
12910          ty,
12911          determinant,
12912          xOriginOld,
12913          yOriginOld;
12914        if (tm) {
12915          xOriginOld = tm.xOrigin; //record the original values before we alter them.
12916          yOriginOld = tm.yOrigin;
12917        }
12918        if (!absolute || (v = absolute.split(" ")).length < 2) {
12919          b = e.getBBox();
12920          if (b.x === 0 && b.y === 0 && b.width + b.height === 0) {
12921            //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.
12922            b = {
12923              x: parseFloat(e.hasAttribute("x") ? e.getAttribute("x") : e.hasAttribute("cx") ? e.getAttribute("cx") : 0) || 0,
12924              y: parseFloat(e.hasAttribute("y") ? e.getAttribute("y") : e.hasAttribute("cy") ? e.getAttribute("cy") : 0) || 0,
12925              width: 0,
12926              height: 0
12927            };
12928          }
12929          local = _parsePosition2(local).split(" ");
12930          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];
12931        }
12932        decoratee.xOrigin = xOrigin = parseFloat(v[0]);
12933        decoratee.yOrigin = yOrigin = parseFloat(v[1]);
12934        if (absolute && m !== _identity2DMatrix) {
12935          //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.
12936          a = m[0];
12937          b = m[1];
12938          c = m[2];
12939          d = m[3];
12940          tx = m[4];
12941          ty = m[5];
12942          determinant = a * d - b * c;
12943          if (determinant) {
12944            //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.
12945            x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;
12946            y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;
12947            xOrigin = decoratee.xOrigin = v[0] = x;
12948            yOrigin = decoratee.yOrigin = v[1] = y;
12949          }
12950        }
12951        if (tm) {
12952          //avoid jump when transformOrigin is changed - adjust the x/y values accordingly
12953          if (skipRecord) {
12954            decoratee.xOffset = tm.xOffset;
12955            decoratee.yOffset = tm.yOffset;
12956            tm = decoratee;
12957          }
12958          if (smoothOrigin || smoothOrigin !== false && _CSSPlugin.defaultSmoothOrigin !== false) {
12959            x = xOrigin - xOriginOld;
12960            y = yOrigin - yOriginOld;
12961            //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.
12962            //tm.x -= x - (x * m[0] + y * m[2]);
12963            //tm.y -= y - (x * m[1] + y * m[3]);
12964            tm.xOffset += x * m[0] + y * m[2] - x;
12965            tm.yOffset += x * m[1] + y * m[3] - y;
12966          } else {
12967            tm.xOffset = tm.yOffset = 0;
12968          }
12969        }
12970        if (!skipRecord) {
12971          e.setAttribute("data-svg-origin", v.join(" "));
12972        }
12973      },
12974      _getBBoxHack2 = function _getBBoxHack(swapIfPossible) {
12975        //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).
12976        var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"),
12977          oldParent = this.parentNode,
12978          oldSibling = this.nextSibling,
12979          oldCSS = this.style.cssText,
12980          bbox;
12981        _docElement.appendChild(svg);
12982        svg.appendChild(this);
12983        this.style.display = "block";
12984        if (swapIfPossible) {
12985          try {
12986            bbox = this.getBBox();
12987            this._originalGetBBox = this.getBBox;
12988            this.getBBox = _getBBoxHack2;
12989          } catch (e) {}
12990        } else if (this._originalGetBBox) {
12991          bbox = this._originalGetBBox();
12992        }
12993        if (oldSibling) {
12994          oldParent.insertBefore(this, oldSibling);
12995        } else {
12996          oldParent.appendChild(this);
12997        }
12998        _docElement.removeChild(svg);
12999        this.style.cssText = oldCSS;
13000        return bbox;
13001      },
13002      _getBBox = function _getBBox(e) {
13003        try {
13004          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
13005        } catch (error) {
13006          return _getBBoxHack2.call(e, true);
13007        }
13008      },
13009      _isSVG = function _isSVG(e) {
13010        //reports if the element is an SVG on which getBBox() actually works
13011        return !!(_SVGElement && e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));
13012      },
13013      _identity2DMatrix = [1, 0, 0, 1, 0, 0],
13014      _getMatrix = function _getMatrix(e, force2D) {
13015        var tm = e._gsTransform || new Transform(),
13016          rnd = 100000,
13017          style = e.style,
13018          isDefault,
13019          s,
13020          m,
13021          n,
13022          dec,
13023          none;
13024        if (_transformProp) {
13025          s = _getStyle(e, _transformPropCSS, null, true);
13026        } else if (e.currentStyle) {
13027          //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.
13028          s = e.currentStyle.filter.match(_ieGetMatrixExp);
13029          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(",") : "";
13030        }
13031        isDefault = !s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)";
13032        if (_transformProp && ((none = !_getComputedStyle(e) || _getComputedStyle(e).display === "none") || !e.parentNode)) {
13033          //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
13034          if (none) {
13035            //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).
13036            n = style.display;
13037            style.display = "block";
13038          }
13039          if (!e.parentNode) {
13040            dec = 1; //flag
13041            _docElement.appendChild(e);
13042          }
13043          s = _getStyle(e, _transformPropCSS, null, true);
13044          isDefault = !s || s === "none" || s === "matrix(1, 0, 0, 1, 0, 0)";
13045          if (n) {
13046            style.display = n;
13047          } else if (none) {
13048            _removeProp(style, "display");
13049          }
13050          if (dec) {
13051            _docElement.removeChild(e);
13052          }
13053        }
13054        if (tm.svg || e.getCTM && _isSVG(e)) {
13055          if (isDefault && (style[_transformProp] + "").indexOf("matrix") !== -1) {
13056            //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
13057            s = style[_transformProp];
13058            isDefault = 0;
13059          }
13060          m = e.getAttribute("transform");
13061          if (isDefault && m) {
13062            m = e.transform.baseVal.consolidate().matrix; //ensures that even complex values like "translate(50,60) rotate(135,0,0)" are parsed because it mashes it into a matrix.
13063            s = "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + m.e + "," + m.f + ")";
13064            isDefault = 0;
13065          }
13066        }
13067        if (isDefault) {
13068          return _identity2DMatrix;
13069        }
13070        //split the matrix values out into an array (m for matrix)
13071        m = (s || "").match(_numExp) || [];
13072        i = m.length;
13073        while (--i > -1) {
13074          n = Number(m[i]);
13075          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).
13076        }
13077        return force2D && m.length > 6 ? [m[0], m[1], m[4], m[5], m[12], m[13]] : m;
13078      },
13079      /**
13080       * 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.
13081       * @param {!Object} t target element
13082       * @param {Object=} cs computed style object (optional)
13083       * @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...}
13084       * @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)
13085       * @return {object}
13085 object containing all of the transform properties/values like {x:0, y:0, z:0, scaleX:1...}
13086       */
13087      _getTransform = _internals.getTransform = function (t, cs, rec, parse) {
13088        if (t._gsTransform && rec && !parse) {
13089          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.
13090        }
13091        var tm = rec ? t._gsTransform || new Transform() : new Transform(),
13092          invX = tm.scaleX < 0,
13093          //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.
13094          min = 0.00002,
13095          rnd = 100000,
13096          zOrigin = _supports3D ? parseFloat(_getStyle(t, _transformOriginProp, cs, false, "0 0 0").split(" ")[2]) || tm.zOrigin || 0 : 0,
13097          defaultTransformPerspective = parseFloat(_CSSPlugin.defaultTransformPerspective) || 0,
13098          m,
13099          i,
13100          scaleX,
13101          scaleY,
13102          rotation,
13103          skewX;
13104        tm.svg = !!(t.getCTM && _isSVG(t));
13105        if (tm.svg) {
13106          _parseSVGOrigin(t, _getStyle(t, _transformOriginProp, cs, false, "50% 50%") + "", tm, t.getAttribute("data-svg-origin"));
13107          _useSVGTransformAttr = _CSSPlugin.useSVGTransformAttr || _forceSVGTransformAttr;
13108        }
13109        m = _getMatrix(t);
13110        if (m !== _identity2DMatrix) {
13111          if (m.length === 16) {
13112            //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)
13113            var a11 = m[0],
13114              a21 = m[1],
13115              a31 = m[2],
13116              a41 = m[3],
13117              a12 = m[4],
13118              a22 = m[5],
13119              a32 = m[6],
13120              a42 = m[7],
13121              a13 = m[8],
13122              a23 = m[9],
13123              a33 = m[10],
13124              a14 = m[12],
13125              a24 = m[13],
13126              a34 = m[14],
13127              a43 = m[11],
13128              angle = Math.atan2(a32, a33),
13129              t1,
13130              t2,
13131              t3,
13132              t4,
13133              cos,
13134              sin;
13135            //we manually compensate for non-zero z component of transformOrigin to work around bugs in Safari
13136            if (tm.zOrigin) {
13137              a34 = -tm.zOrigin;
13138              a14 = a13 * a34 - m[12];
13139              a24 = a23 * a34 - m[13];
13140              a34 = a33 * a34 + tm.zOrigin - m[14];
13141            }
13142            //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.
13143            tm.rotationX = angle * _RAD2DEG;
13144            //rotationX
13145            if (angle) {
13146              cos = Math.cos(-angle);
13147              sin = Math.sin(-angle);
13148              t1 = a12 * cos + a13 * sin;
13149              t2 = a22 * cos + a23 * sin;
13150              t3 = a32 * cos + a33 * sin;
13151              a13 = a12 * -sin + a13 * cos;
13152              a23 = a22 * -sin + a23 * cos;
13153              a33 = a32 * -sin + a33 * cos;
13154              a43 = a42 * -sin + a43 * cos;
13155              a12 = t1;
13156              a22 = t2;
13157              a32 = t3;
13158            }
13159            //rotationY
13160            angle = Math.atan2(-a31, a33);
13161            tm.rotationY = angle * _RAD2DEG;
13162            if (angle) {
13163              cos = Math.cos(-angle);
13164              sin = Math.sin(-angle);
13165              t1 = a11 * cos - a13 * sin;
13166              t2 = a21 * cos - a23 * sin;
13167              t3 = a31 * cos - a33 * sin;
13168              a23 = a21 * sin + a23 * cos;
13169              a33 = a31 * sin + a33 * cos;
13170              a43 = a41 * sin + a43 * cos;
13171              a11 = t1;
13172              a21 = t2;
13173              a31 = t3;
13174            }
13175            //rotationZ
13176            angle = Math.atan2(a21, a11);
13177            tm.rotation = angle * _RAD2DEG;
13178            if (angle) {
13179              cos = Math.cos(angle);
13180              sin = Math.sin(angle);
13181              t1 = a11 * cos + a21 * sin;
13182              t2 = a12 * cos + a22 * sin;
13183              t3 = a13 * cos + a23 * sin;
13184              a21 = a21 * cos - a11 * sin;
13185              a22 = a22 * cos - a12 * sin;
13186              a23 = a23 * cos - a13 * sin;
13187              a11 = t1;
13188              a12 = t2;
13189              a13 = t3;
13190            }
13191            if (tm.rotationX && Math.abs(tm.rotationX) + Math.abs(tm.rotation) > 359.9) {
13192              //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.
13193              tm.rotationX = tm.rotation = 0;
13194              tm.rotationY = 180 - tm.rotationY;
13195            }
13196
13197            //skewX
13198            angle = Math.atan2(a12, a22);
13199
13200            //scales
13201            tm.scaleX = (Math.sqrt(a11 * a11 + a21 * a21 + a31 * a31) * rnd + 0.5 | 0) / rnd;
13202            tm.scaleY = (Math.sqrt(a22 * a22 + a32 * a32) * rnd + 0.5 | 0) / rnd;
13203            tm.scaleZ = (Math.sqrt(a13 * a13 + a23 * a23 + a33 * a33) * rnd + 0.5 | 0) / rnd;
13204            a11 /= tm.scaleX;
13205            a12 /= tm.scaleY;
13206            a21 /= tm.scaleX;
13207            a22 /= tm.scaleY;
13208            if (Math.abs(angle) > min) {
13209              tm.skewX = angle * _RAD2DEG;
13210              a12 = 0;
13210 //unskews
13211              if (tm.skewType !== "simple") {
13212                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).
13213              }
13214            } else {
13215              tm.skewX = 0;
13216            }
13217
13218            /* //for testing purposes
13219            var transform = "matrix3d(",
13220            	comma = ",",
13221            	zero = "0";
13222            a13 /= tm.scaleZ;
13223            a23 /= tm.scaleZ;
13224            a31 /= tm.scaleX;
13225            a32 /= tm.scaleY;
13226            a33 /= tm.scaleZ;
13227            transform += ((a11 < min && a11 > -min) ? zero : a11) + comma + ((a21 < min && a21 > -min) ? zero : a21) + comma + ((a31 < min && a31 > -min) ? zero : a31);
13228            transform += comma + ((a41 < min && a41 > -min) ? zero : a41) + comma + ((a12 < min && a12 > -min) ? zero : a12) + comma + ((a22 < min && a22 > -min) ? zero : a22);
13229            transform += comma + ((a32 < min && a32 > -min) ? zero : a32) + comma + ((a42 < min && a42 > -min) ? zero : a42) + comma + ((a13 < min && a13 > -min) ? zero : a13);
13230            transform += comma + ((a23 < min && a23 > -min) ? zero : a23) + comma + ((a33 < min && a33 > -min) ? zero : a33) + comma + ((a43 < min && a43 > -min) ? zero : a43) + comma;
13231            transform += a14 + comma + a24 + comma + a34 + comma + (tm.perspective ? (1 + (-a34 / tm.perspective)) : 1) + ")";
13232            console.log(transform);
13233            document.querySelector(".test").style[_transformProp] = transform;
13234            */
13235
13236            tm.perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;
13237            tm.x = a14;
13238            tm.y = a24;
13239            tm.z = a34;
13240            if (tm.svg) {
13241              tm.x -= tm.xOrigin - (tm.xOrigin * a11 - tm.yOrigin * a12);
13242              tm.y -= tm.yOrigin - (tm.yOrigin * a21 - tm.xOrigin * a22);
13243            }
13244          } else if (!_supports3D || parse || !m.length || tm.x !== m[4] || tm.y !== m[5] || !tm.rotationX && !tm.rotationY) {
13245            //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.
13246            var k = m.length >= 6,
13247              a = k ? m[0] : 1,
13248              b = m[1] || 0,
13249              c = m[2] || 0,
13250              d = k ? m[3] : 1;
13251            tm.x = m[4] || 0;
13252            tm.y = m[5] || 0;
13253            scaleX = Math.sqrt(a * a + b * b);
13254            scaleY = Math.sqrt(d * d + c * c);
13255            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).
13256            skewX = c || d ? Math.atan2(c, d) * _RAD2DEG + rotation : tm.skewX || 0;
13257            tm.scaleX = scaleX;
13258            tm.scaleY = scaleY;
13259            tm.rotation = rotation;
13260            tm.skewX = skewX;
13261            if (_supports3D) {
13262              tm.rotationX = tm.rotationY = tm.z = 0;
13263              tm.perspective = defaultTransformPerspective;
13264              tm.scaleZ = 1;
13265            }
13266            if (tm.svg) {
13267              tm.x -= tm.xOrigin - (tm.xOrigin * a + tm.yOrigin * c);
13268              tm.y -= tm.yOrigin - (tm.xOrigin * b + tm.yOrigin * d);
13269            }
13270          }
13271          if (Math.abs(tm.skewX) > 90 && Math.abs(tm.skewX) < 270) {
13272            if (invX) {
13273              tm.scaleX *= -1;
13274              tm.skewX += tm.rotation <= 0 ? 180 : -180;
13275              tm.rotation += tm.rotation <= 0 ? 180 : -180;
13276            } else {
13277              tm.scaleY *= -1;
13278              tm.skewX += tm.skewX <= 0 ? 180 : -180;
13279            }
13280          }
13281          tm.zOrigin = zOrigin;
13282          //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.
13283          for (i in tm) {
13284            if (tm[i] < min) if (tm[i] > -min) {
13285              tm[i] = 0;
13286            }
13287          }
13288        }
13289        //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);
13290        if (rec) {
13291          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)
13292          if (tm.svg) {
13293            //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.
13294            if (_useSVGTransformAttr && t.style[_transformProp]) {
13295              TweenLite.delayedCall(0.001, function () {
13296                //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).
13297                _removeProp(t.style, _transformProp);
13298              });
13299            } else if (!_useSVGTransformAttr && t.getAttribute("transform")) {
13300              TweenLite.delayedCall(0.001, function () {
13301                t.removeAttribute("transform");
13302              });
13303            }
13304          }
13305        }
13306        return tm;
13307      },
13308      //for setting 2D transforms in IE6, IE7, and IE8 (must use a "filter" to emulate the behavior of modern day browser transforms)
13309      _setIETransformRatio = function _setIETransformRatio(v) {
13310        var t = this.data,
13311          //refers to the element's _gsTransform object
13312          ang = -t.rotation * _DEG2RAD,
13313          skew = ang + t.skewX * _DEG2RAD,
13314          rnd = 100000,
13315          a = (Math.cos(ang) * t.scaleX * rnd | 0) / rnd,
13316          b = (Math.sin(ang) * t.scaleX * rnd | 0) / rnd,
13317          c = (Math.sin(skew) * -t.scaleY * rnd | 0) / rnd,
13318          d = (Math.cos(skew) * t.scaleY * rnd | 0) / rnd,
13319          style = this.t.style,
13320          cs = this.t.currentStyle,
13321          filters,
13322          val;
13323        if (!cs) {
13324          return;
13325        }
13326        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)
13327        b = -c;
13328        c = -val;
13329        filters = cs.filter;
13330        style.filter = ""; //remove filters so that we can accurately measure offsetWidth/offsetHeight
13331        var w = this.t.offsetWidth,
13332          h = this.t.offsetHeight,
13333          clip = cs.position !== "absolute",
13334          m = "progid:DXImageTransform.Microsoft.Matrix(M11=" + a + ", M12=" + b + ", M21=" + c + ", M22=" + d,
13335          ox = t.x + w * t.xPercent / 100,
13336          oy = t.y + h * t.yPercent / 100,
13337          dx,
13338          dy;
13339
13340        //if transformOrigin is being used, adjust the offset x and y
13341        if (t.ox != null) {
13342          dx = (t.oxp ? w * t.ox * 0.01 : t.ox) - w / 2;
13343          dy = (t.oyp ? h * t.oy * 0.01 : t.oy) - h / 2;
13344          ox += dx - (dx * a + dy * b);
13345          oy += dy - (dx * c + dy * d);
13346        }
13347        if (!clip) {
13348          m += ", sizingMethod='auto expand')";
13349        } else {
13350          dx = w / 2;
13351          dy = h / 2;
13352          //translate to ensure that transformations occur around the correct origin (default is center).
13353          m += ", Dx=" + (dx - (dx * a + dy * b) + ox) + ", Dy=" + (dy - (dx * c + dy * d) + oy) + ")";
13354        }
13355        if (filters.indexOf("DXImageTransform.Microsoft.Matrix(") !== -1) {
13356          style.filter = filters.replace(_ieSetMatrixExp, m);
13357        } else {
13358          style.filter = m + " " + filters; //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.
13359        }
13360
13361        //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.
13362        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) {
13363          style.removeAttribute("filter");
13364        }
13365
13366        //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).
13367        if (!clip) {
13368          var mult = _ieVers < 8 ? 1 : -1,
13369            //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
13370            marg,
13371            prop,
13372            dif;
13373          dx = t.ieOffsetX || 0;
13374          dy = t.ieOffsetY || 0;
13375          t.ieOffsetX = Math.round((w - ((a < 0 ? -a : a) * w + (b < 0 ? -b : b) * h)) / 2 + ox);
13376          t.ieOffsetY = Math.round((h - ((d < 0 ? -d : d) * h + (c < 0 ? -c : c) * w)) / 2 + oy);
13377          for (i = 0; i < 4; i++) {
13378            prop = _margins[i];
13379            marg = cs[prop];
13380            //we need to get the current margin in case it is being tweened separately (we want to respect that tween's changes)
13381            val = marg.indexOf("px") !== -1 ? parseFloat(marg) : _convertToPixels(this.t, prop, parseFloat(marg), marg.replace(_suffixExp, "")) || 0;
13382            if (val !== t[prop]) {
13383              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.
13384            } else {
13385              dif = i < 2 ? dx - t.ieOffsetX : dy - t.ieOffsetY;
13386            }
13387            style[prop] = (t[prop] = Math.round(val - dif * (i === 0 || i === 2 ? 1 : mult))) + "px";
13388          }
13389        }
13390      },
13391      /* translates a super small decimal to a string WITHOUT scientific notation
13392      _safeDecimal = function(n) {
13393      	var s = (n < 0 ? -n : n) + "",
13394      		a = s.split("e-");
13395      	return (n < 0 ? "-0." : "0.") + new Array(parseInt(a[1], 10) || 0).join("0") + a[0].split(".").join("");
13396      },
13397      */
13398
13399      _setTransformRatio = _internals.set3DTransformRatio = _internals.setTransformRatio = function (v) {
13400        var t = this.data,
13401          //refers to the element's _gsTransform object
13402          style = this.t.style,
13403          angle = t.rotation,
13404          rotationX = t.rotationX,
13405          rotationY = t.rotationY,
13406          sx = t.scaleX,
13407          sy = t.scaleY,
13408          sz = t.scaleZ,
13409          x = t.x,
13410          y = t.y,
13411          z = t.z,
13412          isSVG = t.svg,
13413          perspective = t.perspective,
13414          force3D = t.force3D,
13415          skewY = t.skewY,
13416          skewX = t.skewX,
13417          t1,
13418          a11,
13419          a12,
13420          a13,
13421          a21,
13422          a22,
13423          a23,
13424          a31,
13425          a32,
13426          a33,
13427          a41,
13428          a42,
13429          a43,
13430          zOrigin,
13431          min,
13432          cos,
13433          sin,
13434          t2,
13435          transform,
13436          comma,
13437          zero,
13438          skew,
13439          rnd;
13440        if (skewY) {
13441          //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.
13442          skewX += skewY;
13443          angle += skewY;
13444        }
13445
13446        //check to see if we should render as 2D (and SVGs must use 2D when _useSVGTransformAttr is true)
13447        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) {
13448          //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.
13449
13450          //2D
13451          if (angle || skewX || isSVG) {
13452            angle *= _DEG2RAD;
13453            skew = skewX * _DEG2RAD;
13454            rnd = 100000;
13455            a11 = Math.cos(angle) * sx;
13456            a21 = Math.sin(angle) * sx;
13457            a12 = Math.sin(angle - skew) * -sy;
13458            a22 = Math.cos(angle - skew) * sy;
13459            if (skew && t.skewType === "simple") {
13460              //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
13461              t1 = Math.tan(skew - skewY * _DEG2RAD);
13462              t1 = Math.sqrt(1 + t1 * t1);
13463              a12 *= t1;
13464              a22 *= t1;
13465              if (skewY) {
13466                t1 = Math.tan(skewY * _DEG2RAD);
13467                t1 = Math.sqrt(1 + t1 * t1);
13468                a11 *= t1;
13469                a21 *= t1;
13470              }
13471            }
13472            if (isSVG) {
13473              x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
13474              y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
13475              if (_useSVGTransformAttr && (t.xPercent || t.yPercent)) {
13476                //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the matrix to simulate it.
13477                min = this.t.getBBox();
13478                x += t.xPercent * 0.01 * min.width;
13479                y += t.yPercent * 0.01 * min.height;
13480              }
13481              min = 0.000001;
13482              if (x < min) if (x > -min) {
13483                x = 0;
13484              }
13485              if (y < min) if (y > -min) {
13486                y = 0;
13487              }
13488            }
13489            transform = (a11 * rnd | 0) / rnd + "," + (a21 * rnd | 0) / rnd + "," + (a12 * rnd | 0) / rnd + "," + (a22 * rnd | 0) / rnd + "," + x + "," + y + ")";
13490            if (isSVG && _useSVGTransformAttr) {
13491              this.t.setAttribute("transform", "matrix(" + transform);
13492            } else {
13493              //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.
13494              style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + transform;
13495            }
13496          } else {
13497            style[_transformProp] = (t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix(" : "matrix(") + sx + ",0,0," + sy + "," + x + "," + y + ")";
13498          }
13499          return;
13500        }
13501        if (_isFirefox) {
13502          //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.
13503          min = 0.0001;
13504          if (sx < min && sx > -min) {
13505            sx = sz = 0.00002;
13506          }
13507          if (sy < min && sy > -min) {
13508            sy = sz = 0.00002;
13509          }
13510          if (perspective && !t.z && !t.rotationX && !t.rotationY) {
13511            //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).
13512            perspective = 0;
13513          }
13514        }
13515        if (angle || skewX) {
13516          angle *= _DEG2RAD;
13517          cos = a11 = Math.cos(angle);
13518          sin = a21 = Math.sin(angle);
13519          if (skewX) {
13520            angle -= skewX * _DEG2RAD;
13521            cos = Math.cos(angle);
13522            sin = Math.sin(angle);
13523            if (t.skewType === "simple") {
13524              //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
13525              t1 = Math.tan((skewX - skewY) * _DEG2RAD);
13526              t1 = Math.sqrt(1 + t1 * t1);
13527              cos *= t1;
13528              sin *= t1;
13529              if (t.skewY) {
13530                t1 = Math.tan(skewY * _DEG2RAD);
13531                t1 = Math.sqrt(1 + t1 * t1);
13532                a11 *= t1;
13533                a21 *= t1;
13534              }
13535            }
13536          }
13537          a12 = -sin;
13538          a22 = cos;
13539        } else if (!rotationY && !rotationX && sz === 1 && !perspective && !isSVG) {
13540          //if we're only translating and/or 2D scaling, this is faster...
13541          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 + ")" : "");
13542          return;
13543        } else {
13544          a11 = a22 = 1;
13545          a12 = a21 = 0;
13546        }
13547        // KEY  INDEX   AFFECTS a[row][column]
13548        // a11  0       rotation, rotationY, scaleX
13549        // a21  1       rotation, rotationY, scaleX
13550        // a31  2       rotationY, scaleX
13551        // a41  3       rotationY, scaleX
13552        // a12  4       rotation, skewX, rotationX, scaleY
13553        // a22  5       rotation, skewX, rotationX, scaleY
13554        // a32  6       rotationX, scaleY
13555        // a42  7       rotationX, scaleY
13556        // a13  8       rotationY, rotationX, scaleZ
13557        // a23  9       rotationY, rotationX, scaleZ
13558        // a33  10      rotationY, rotationX, scaleZ
13559        // a43  11      rotationY, rotationX, perspective, scaleZ
13560        // a14  12      x, zOrigin, svgOrigin
13561        // a24  13      y, zOrigin, svgOrigin
13562        // a34  14      z, zOrigin
13563        // a44  15
13564        // rotation: Math.atan2(a21, a11)
13565        // rotationY: Math.atan2(a13, a33) (or Math.atan2(a13, a11))
13566        // rotationX: Math.atan2(a32, a33)
13567        a33 = 1;
13568        a13 = a23 = a31 = a32 = a41 = a42 = 0;
13569        a43 = perspective ? -1 / perspective : 0;
13570        zOrigin = t.zOrigin;
13571        min = 0.000001; //threshold below which browsers use scientific notation which w
13571on't work.
13572        comma = ",";
13573        zero = "0";
13574        angle = rotationY * _DEG2RAD;
13575        if (angle) {
13576          cos = Math.cos(angle);
13577          sin = Math.sin(angle);
13578          a31 = -sin;
13579          a41 = a43 * -sin;
13580          a13 = a11 * sin;
13581          a23 = a21 * sin;
13582          a33 = cos;
13583          a43 *= cos;
13584          a11 *= cos;
13585          a21 *= cos;
13586        }
13587        angle = rotationX * _DEG2RAD;
13588        if (angle) {
13589          cos = Math.cos(angle);
13590          sin = Math.sin(angle);
13591          t1 = a12 * cos + a13 * sin;
13592          t2 = a22 * cos + a23 * sin;
13593          a32 = a33 * sin;
13594          a42 = a43 * sin;
13595          a13 = a12 * -sin + a13 * cos;
13596          a23 = a22 * -sin + a23 * cos;
13597          a33 = a33 * cos;
13598          a43 = a43 * cos;
13599          a12 = t1;
13600          a22 = t2;
13601        }
13602        if (sz !== 1) {
13603          a13 *= sz;
13604          a23 *= sz;
13605          a33 *= sz;
13606          a43 *= sz;
13607        }
13608        if (sy !== 1) {
13609          a12 *= sy;
13610          a22 *= sy;
13611          a32 *= sy;
13612          a42 *= sy;
13613        }
13614        if (sx !== 1) {
13615          a11 *= sx;
13616          a21 *= sx;
13617          a31 *= sx;
13618          a41 *= sx;
13619        }
13620        if (zOrigin || isSVG) {
13621          if (zOrigin) {
13622            x += a13 * -zOrigin;
13623            y += a23 * -zOrigin;
13624            z += a33 * -zOrigin + zOrigin;
13625          }
13626          if (isSVG) {
13627            //due to bugs in some browsers, we need to manage the transform-origin of SVG manually
13628            x += t.xOrigin - (t.xOrigin * a11 + t.yOrigin * a12) + t.xOffset;
13629            y += t.yOrigin - (t.xOrigin * a21 + t.yOrigin * a22) + t.yOffset;
13630          }
13631          if (x < min && x > -min) {
13632            x = zero;
13633          }
13634          if (y < min && y > -min) {
13635            y = zero;
13636          }
13637          if (z < min && z > -min) {
13638            z = 0; //don't use string because we calculate perspective later and need the number.
13639          }
13640        }
13641
13642        //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:
13643        transform = t.xPercent || t.yPercent ? "translate(" + t.xPercent + "%," + t.yPercent + "%) matrix3d(" : "matrix3d(";
13644        transform += (a11 < min && a11 > -min ? zero : a11) + comma + (a21 < min && a21 > -min ? zero : a21) + comma + (a31 < min && a31 > -min ? zero : a31);
13645        transform += comma + (a41 < min && a41 > -min ? zero : a41) + comma + (a12 < min && a12 > -min ? zero : a12) + comma + (a22 < min && a22 > -min ? zero : a22);
13646        if (rotationX || rotationY || sz !== 1) {
13647          //performance optimization (often there's no rotationX or rotationY, so we can skip these calculations)
13648          transform += comma + (a32 < min && a32 > -min ? zero : a32) + comma + (a42 < min && a42 > -min ? zero : a42) + comma + (a13 < min && a13 > -min ? zero : a13);
13649          transform += comma + (a23 < min && a23 > -min ? zero : a23) + comma + (a33 < min && a33 > -min ? zero : a33) + comma + (a43 < min && a43 > -min ? zero : a43) + comma;
13650        } else {
13651          transform += ",0,0,0,0,1,0,";
13652        }
13653        transform += x + comma + y + comma + z + comma + (perspective ? 1 + -z / perspective : 1) + ")";
13654        style[_transformProp] = transform;
13655      };
13656    p = Transform.prototype;
13657    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;
13658    p.scaleX = p.scaleY = p.scaleZ = 1;
13659    _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", {
13660      parser: function parser(t, e, parsingProp, cssp, pt, plugin, vars) {
13661        if (cssp._lastParsedTransform === vars) {
13662          return pt;
13663        } //only need to parse the transform once, and only if the browser supports it.
13664        cssp._lastParsedTransform = vars;
13665        var scaleFunc = vars.scale && typeof vars.scale === "function" ? vars.scale : 0,
13666          //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()).
13667          swapFunc;
13668        if (typeof vars[parsingProp] === "function") {
13669          //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.
13670          swapFunc = vars[parsingProp];
13671          vars[parsingProp] = e;
13672        }
13673        if (scaleFunc) {
13674          vars.scale = scaleFunc(_index, t);
13675        }
13676        var originalGSTransform = t._gsTransform,
13677          style = t.style,
13678          min = 0.000001,
13679          i = _transformProps.length,
13680          v = vars,
13681          endRotations = {},
13682          transformOriginString = "transformOrigin",
13683          m1 = _getTransform(t, _cs, true, v.parseTransform),
13684          orig = v.transform && (typeof v.transform === "function" ? v.transform(_index, _target) : v.transform),
13685          m2,
13686          copy,
13687          has3D,
13688          hasChange,
13689          dr,
13690          x,
13691          y,
13692          matrix,
13693          p;
13694        m1.skewType = v.skewType || m1.skewType || _CSSPlugin.defaultSkewType;
13695        cssp._transform = m1;
13696        if (orig && typeof orig === "string" && _transformProp) {
13697          //for values like transform:"rotate(60deg) scale(0.5, 0.8)"
13698          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.
13699          copy[_transformProp] = orig;
13700          copy.display = "block"; //if display is "none", the browser often refuses to report the transform properties correctly.
13701          copy.position = "absolute";
13702          _doc.body.appendChild(_tempDiv);
13703          m2 = _getTransform(_tempDiv, null, false);
13704          if (m1.skewType === "simple") {
13705            //the default _getTransform() reports the skewX/scaleY as if skewType is "compensated", thus we need to adjust that here if skewType is "simple".
13706            m2.scaleY *= Math.cos(m2.skewX * _DEG2RAD);
13707          }
13708          if (m1.svg) {
13709            //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...
13710            x = m1.xOrigin;
13711            y = m1.yOrigin;
13712            m2.x -= m1.xOffset;
13713            m2.y -= m1.yOffset;
13714            if (v.transformOrigin || v.svgOrigin) {
13715              //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.
13716              orig = {};
13717              _parseSVGOrigin(t, _parsePosition2(v.transformOrigin), orig, v.svgOrigin, v.smoothOrigin, true);
13718              x = orig.xOrigin;
13719              y = orig.yOrigin;
13720              m2.x -= orig.xOffset - m1.xOffset;
13721              m2.y -= orig.yOffset - m1.yOffset;
13722            }
13723            if (x || y) {
13724              matrix = _getMatrix(_tempDiv, true);
13725              m2.x -= x - (x * matrix[0] + y * matrix[2]);
13726              m2.y -= y - (x * matrix[1] + y * matrix[3]);
13727            }
13728          }
13729          _doc.body.removeChild(_tempDiv);
13730          if (!m2.perspective) {
13731            m2.perspective = m1.perspective; //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.
13732          }
13733          if (v.xPercent != null) {
13734            m2.xPercent = _parseVal(v.xPercent, m1.xPercent);
13735          }
13736          if (v.yPercent != null) {
13737            m2.yPercent = _parseVal(v.yPercent, m1.yPercent);
13738          }
13739        } else if (_typeof(v) === "object") {
13740          //for values like scaleX, scaleY, rotation, x, y, skewX, and skewY or transform:{...} (object)
13741          m2 = {
13742            scaleX: _parseVal(v.scaleX != null ? v.scaleX : v.scale, m1.scaleX),
13743            scaleY: _parseVal(v.scaleY != null ? v.scaleY : v.scale, m1.scaleY),
13744            scaleZ: _parseVal(v.scaleZ, m1.scaleZ),
13745            x: _parseVal(v.x, m1.x),
13746            y: _parseVal(v.y, m1.y),
13747            z: _parseVal(v.z, m1.z),
13748            xPercent: _parseVal(v.xPercent, m1.xPercent),
13749            yPercent: _parseVal(v.yPercent, m1.yPercent),
13750            perspective: _parseVal(v.transformPerspective, m1.perspective)
13751          };
13752          dr = v.directionalRotation;
13753          if (dr != null) {
13754            if (_typeof(dr) === "object") {
13755              for (copy in dr) {
13756                v[copy] = dr[copy];
13757              }
13758            } else {
13759              v.rotation = dr;
13760            }
13761          }
13762          if (typeof v.x === "string" && v.x.indexOf("%") !== -1) {
13763            m2.x = 0;
13764            m2.xPercent = _parseVal(v.x, m1.xPercent);
13765          }
13766          if (typeof v.y === "string" && v.y.indexOf("%") !== -1) {
13767            m2.y = 0;
13768            m2.yPercent = _parseVal(v.y, m1.yPercent);
13769          }
13770          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);
13771          if (_supports3D) {
13772            m2.rotationX = _parseAngle("rotationX" in v ? v.rotationX : "shortRotationX" in v ? v.shortRotationX + "_short" : m1.rotationX || 0, m1.rotationX, "rotationX", endRotations);
13773            m2.rotationY = _parseAngle("rotationY" in v ? v.rotationY : "shortRotationY" in v ? v.shortRotationY + "_short" : m1.rotationY || 0, m1.rotationY, "rotationY", endRotations);
13774          }
13775          m2.skewX = _parseAngle(v.skewX, m1.skewX);
13776          m2.skewY = _parseAngle(v.skewY, m1.skewY);
13777        }
13778        if (_supports3D && v.force3D != null) {
13779          m1.force3D = v.force3D;
13780          hasChange = true;
13781        }
13782        has3D = m1.force3D || m1.z || m1.rotationX || m1.rotationY || m2.z || m2.rotationX || m2.rotationY || m2.perspective;
13783        if (!has3D && v.scale != null) {
13784          m2.scaleZ = 1; //no need to tween scaleZ.
13785        }
13786        while (--i > -1) {
13787          p = _transformProps[i];
13788          orig = m2[p] - m1[p];
13789          if (orig > min || orig < -min || v[p] != null || _forcePT[p] != null) {
13790            hasChange = true;
13791            pt = new CSSPropTween(m1, p, m1[p], orig, pt);
13792            if (p in endRotations) {
13793              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
13794            }
13795            pt.xs0 = 0; //ensures the value stays numeric in setRatio()
13796            pt.plugin = plugin;
13797            cssp._overwriteProps.push(pt.n);
13798          }
13799        }
13800        orig = v.transformOrigin;
13801        if (m1.svg && (orig || v.svgOrigin)) {
13802          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
13803          y = m1.yOffset;
13804          _parseSVGOrigin(t, _parsePosition2(orig), m2, v.svgOrigin, v.smoothOrigin);
13805          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.
13806          pt = _addNonTweeningNumericPT(m1, "yOrigin", (originalGSTransform ? m1 : m2).yOrigin, m2.yOrigin, pt, transformOriginString);
13807          if (x !== m1.xOffset || y !== m1.yOffset) {
13808            pt = _addNonTweeningNumericPT(m1, "xOffset", originalGSTransform ? x : m1.xOffset, m1.xOffset, pt, transformOriginString);
13809            pt = _addNonTweeningNumericPT(m1, "yOffset", originalGSTransform ? y : m1.yOffset, m1.yOffset, pt, transformOriginString);
13810          }
13811          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
13812        }
13813        if (orig || _supports3D && has3D && m1.zOrigin) {
13814          //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).
13815          if (_transformProp) {
13816            hasChange = true;
13817            p = _transformOriginProp;
13818            orig = (orig || _getStyle(t, p, _cs, false, "50% 50%")) + ""; //cast as string to avoid errors
13819            pt = new CSSPropTween(style, p, 0, 0, pt, -1, transformOriginString);
13820            pt.b = style[p];
13821            pt.plugin = plugin;
13822            if (_supports3D) {
13823              copy = m1.zOrigin;
13824              orig = orig.split(" ");
13825              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.
13826              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)!
13827              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)
13828              pt.b = copy;
13829              pt.xs0 = pt.e = m1.zOrigin;
13830            } else {
13831              pt.xs0 = pt.e = orig;
13832            }
13833
13834            //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).
13835          } else {
13836            _parsePosition2(orig + "", m1);
13837          }
13838        }
13839        if (hasChange) {
13840          cssp._transformType = !(m1.svg && _useSVGTransformAttr) && (has3D || this._transformType === 3) ? 3 : 2; //quicker than calling cssp._enableTransforms();
13841        }
13842        if (swapFunc) {
13843          vars[parsingProp] = swapFunc;
13844        }
13845        if (scaleFunc) {
13846          vars.scale = scaleFunc;
13847        }
13848        return pt;
13849      },
13850      prefix: true
13851    });
13852    _registerComplexSpecialProp("boxShadow", {
13853      defaultValue: "0px 0px 0px 0px #999",
13854      prefix: true,
13855      color: true,
13856      multi: true,
13857      keyword: "inset"
13858    });
13859    _registerComplexSpecialProp("borderRadius", {
13860      defaultValue: "0px",
13861      parser: function parser(t, e, p, cssp, pt, plugin) {
13862        e = this.format(e);
13863        var props = ["borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius"],
13864          style = t.style,
13865          ea1,
13866          i,
13867          es2,
13868          bs2,
13869          bs,
13870          es,
13871          bn,
13872          en,
13873          w,
13874          h,
13875          esfx,
13876          bsfx,
13877          rel,
13878          hn,
13879          vn,
13880          em;
13881        w = parseFloat(t.offsetWidth);
13882        h = parseFloat(t.offsetHeight);
13883        ea1 = e.split(" ");
13884        for (i = 0; i < props.length; i++) {
13885          //if we're dealing with percentages, we must convert things separately for the horizontal and vertical axis!
13886          if (this.p.indexOf("border")) {
13887            //older browsers used a prefix
13888            props[i] = _checkPropPrefix(props[i]);
13889          }
13890          bs = bs2 = _getStyle(t, props[i], _cs, false, "0px");
13891          if (bs.indexOf(" ") !== -1) {
13892            bs2 = bs.split(" ");
13893            bs = bs2[0];
13894            bs2 = bs2[1];
13895          }
13896          es = es2 = ea1[i];
13897          bn = parseFloat(bs);
13898          bsfx = bs.substr((bn + "").length);
13899          rel = es.charAt(1) === "=";
13900          if (rel) {
13901            en = parseInt(es.charAt(0) + "1", 10);
13902            es = es.substr(2);
13903            en *= parseFloat(es);
13904            esfx = es.substr((en + "").length - (en < 0 ? 1 : 0)) || "";
13905          } else {
13906            en = parseFloat(es);
13907            esfx = es.substr((en + "").length);
13908          }
13909          if (esfx === "") {
13910            esfx = _suffixMap[p] || bsfx;
13911          }
13912          if (esfx !== bsfx) {
13913            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.
13914            vn = _convertToPixels(t, "borderTop", bn, bsfx); //vertical number
13915            if (esfx === "%") {
13916              bs = hn / w * 100 + "%";
13917              bs2 = vn / h * 100 + "%";
13918            } else if (esfx === "em") {
13919              em = _convertToPixels(t, "borderLeft", 1, "em");
13920              bs = hn / em + "em";
13921              bs2 = vn / em + "em";
13922            } else {
13923              bs = hn + "px";
13924              bs2 = vn + "px";
13925            }
13926            if (rel) {
13927              es = parseFloat(bs) + en + esfx;
13928              es2 = parseFloat(bs2) + en + esfx;
13929            }
13930          }
13931          pt = _parseComplex(style, props[i], bs + " " + bs2, es + " " + es2, false, "0px", pt);
13932        }
13933        return pt;
13934      },
13935      prefix: true,
13936      formatter: _getFormatter("0px 0px 0px 0px", false, true)
13937    });
13938    _registerComplexSpecialProp("borderBottomLeftRadius,borderBottomRightRadius,borderTopLeftRadius,borderTopRightRadius", {
13939      defaultValue: "0px",
13940      parser: function parser(t, e, p, cssp, pt, plugin) {
13941        return _parseComplex(t.style, p, this.format(_getStyle(t, p, _cs, false, "0px 0px")), this.format(e), false, "0px", pt);
13942      },
13943      prefix: true,
13944      formatter: _getFormatter("0px 0px", false, true)
13945    });
13946    _registerComplexSpecialProp("backgroundPosition", {
13947      defaultValue: "0 0",
13948      parser: function parser(t, e, p, cssp, pt, plugin) {
13949        var bp = "background-position",
13950          cs = _cs || _getComputedStyle(t, null),
13951          bs = this.format((cs ? _ieVers ? cs.getPropertyValue(bp + "-x") + " " + cs.getPropertyValue(bp + "-y") : cs.getPropertyValue(bp) : t.currentStyle.backgroundPositionX + " " + t.currentStyle.backgroundPositionY) || "0 0"),
13952          //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
13953          es = this.format(e),
13954          ba,
13955          ea,
13956          i,
13957          pct,
13958          overlap,
13959          src;
13960        if (bs.indexOf("%") !== -1 !== (es.indexOf("%") !== -1) && es.split(",").length < 2) {
13961          src = _getStyle(t, "backgroundImage").replace(_urlExp, "");
13962          if (src && src !== "none") {
13963            ba = bs.split(" ");
13964            ea = es.split(" ");
13965            _tempImg.setAttribute("src", src); //set the temp IMG's src to the background-image so that we can measure its width/height
13966            i = 2;
13967            while (--i > -1) {
13968              bs = ba[i];
13969              pct = bs.indexOf("%") !== -1;
13970              if (pct !== (ea[i].indexOf("%") !== -1)) {
13971                overlap = i === 0 ? t.offsetWidth - _tempImg.width : t.offsetHeight - _tempImg.height;
13972                ba[i] = pct ? parseFloat(bs) / 100 * overlap + "px" : parseFloat(bs) / overlap * 100 + "%";
13973              }
13974            }
13975            bs = ba.join(" ");
13976          }
13977        }
13978        return this.parseComplex(t.style, bs, es, pt, plugin);
13979      },
13980      formatter: _parsePosition2
13981    });
13982    _registerComplexSpecialProp("backgroundSize", {
13983      defaultValue: "0 0",
13984      formatter: function formatter(v) {
13985        v += ""; //ensure it's a string
13986        return _parsePosition2(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).
13987      }
13988    });
13989    _registerComplexSpecialProp("perspective", {
13990      defaultValue: "0px",
13991      prefix: true
13992    });
13993    _registerComplexSpecialProp("perspectiveOrigin", {
13994      defaultValue: "50% 50%",
13995      prefix: true
13996    });
13997    _registerComplexSpecialProp("transformStyle", {
13998      prefix: true
13999    });
14000    _registerComplexSpecialProp("backfaceVisibility", {
14001      prefix: true
14002    });
14003    _registerComplexSpecialProp("userSelect", {
14004      prefix: true
14005    });
14006    _registerComplexSpecialProp("margin", {
14007      parser: _getEdgeParser("marginTop,marginRight,marginBottom,marginLeft")
14008    });
14009    _registerComplexSpecialProp("padding", {
14010      parser: _getEdgeParser("paddingTop,paddingRight,paddingBottom,paddingLeft")
14011    });
14012    _registerComplexSpecialProp("clip", {
14013      defaultValue: "rect(0px,0px,0px,0px)",
14014      parser: function parser(t, e, p, cssp, pt, plugin) {
14015        var b, cs, delim;
14016        if (_ieVers < 9) {
14017          //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.
14018          cs = t.currentStyle;
14019          delim = _ieVers < 8 ? " " : ",";
14020          b = "rect(" + cs.clipTop + delim + cs.clipRight + delim + cs.clipBottom + delim + cs.clipLeft + ")";
14021          e = this.format(e).split(",").join(delim);
14022        } else {
14023          b = this.format(_getStyle(t, this.p, _cs, false, this.dflt));
14024          e = this.format(e);
14025        }
14026        return this.parseComplex(t.style, b, e, pt, plugin);
14027      }
14028    });
14029    _registerComplexSpecialProp("textShadow", {
14030      defaultValue: "0px 0px 0px #999",
14031      color: true,
14032      multi: true
14033    });
14034    _registerComplexSpecialProp("autoRound,strictUnits", {
14035      parser: function parser(t, e, p, cssp, pt) {
14036        return pt;
14037      }
14038    }); //just so that we can ignore these properties (not tween them)
14039    _registerComplexSpecialProp("border", {
14040      defaultValue: "0px solid #000",
14041      parser: function parser(t, e, p, cssp, pt, plugin) {
14042        var bw = _getStyle(t, "borderTopWidth", _cs, false, "0px"),
14043          end = this.format(e).split(" "),
14044          esfx = end[0].replace(_suffixExp, "");
14045        if (esfx !== "px") {
14046          //if we're animating to a non-px value, we need to convert the beginning width to that unit.
14047          bw = parseFloat(bw) / _convertToPixels(t, "borderTopWidth", 1, esfx) + esfx;
14048        }
14049        return this.parseComplex(t.style, this.format(bw + " " + _getStyle(t, "borderTopStyle", _cs, false, "solid") + " " + _getStyle(t, "borderTopColor", _cs, false, "#000")), end.join(" "), pt, plugin);
14050      },
14051      color: true,
14052      formatter: function formatter(v) {
14053        var a = v.split(" ");
14054        return a[0] + " " + (a[1] || "solid") + " " + (v.match(_colorExp) || ["#000"])[0];
14055      }
14056    });
14057    _registerComplexSpecialProp("borderWidth", {
14058      parser: _getEdgeParser("borderTopWidth,borderRightWidth,borderBottomWidth,borderLeftWidth")
14059    }); //Firefox doesn't pick up on borderWidth set in style sheets (only inline).
14060    _registerComplexSpecialProp("float,cssFloat,styleFloat", {
14061      parser: function parser(t, e, p, cssp, pt, plugin) {
14062        var s = t.style,
14063          prop = "cssFloat" in s ? "cssFloat" : "styleFloat";
14064        return new CSSPropTween(s, prop, 0, 0, pt, -1, p, false, 0, s[prop], e);
14065      }
14066    });
14067
14068    //opacity-related
14069    var _setIEOpacityRatio = function _setIEOpacityRatio(v) {
14070      var t = this.t,
14071        //refers to the element's style property
14072        filters = t.filter || _getStyle(this.data, "filter") || "",
14073        val = this.s + this.c * v | 0,
14074        skip;
14075      if (val === 100) {
14076        //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.
14077        if (filters.indexOf("atrix(") === -1 && filters.indexOf("radient(") === -1 && filters.indexOf("oader(") === -1) {
14078          t.removeAttribute("filter");
14079          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.
14080        } else {
14081          t.filter = filters.replace(_alphaFilterExp, "");
14082          skip = true;
14083        }
14084      }
14085      if (!skip) {
14086        if (this.xn1) {
14087          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.
14088        }
14089        if (filters.indexOf("pacity") === -1) {
14090          //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
14091          if (val !== 0 || !this.xn1) {
14092            //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)
14093            t.filter = filters + " alpha(opacity=" + val + ")"; //we round the value because otherwise, bugs in IE7/8 can prevent "visibility" changes from being applied properly.
14094          }
14095        } else {
14096          t.filter = filters.replace(_opacityExp, "opacity=" + val);
14097        }
14098      }
14099    };
14100    _registerComplexSpecialProp("opacity,alpha,autoAlpha", {
14101      defaultValue: "1",
14102      parser: function parser(t, e, p, cssp, pt, plugin) {
14103        var b = parseFloat(_getStyle(t, "opacity", _cs, false, "1")),
14104          style = t.style,
14105          isAutoAlpha = p === "autoAlpha";
14106        if (typeof e === "string" && e.charAt(1) === "=") {
14107          e = (e.charAt(0) === "-" ? -1 : 1) * parseFloat(e.substr(2)) + b;
14108        }
14109        if (isAutoAlpha && b === 1 && _getStyle(t, "visibility", _cs) === "hidden" && e !== 0) {
14110          //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience)
14111          b = 0;
14112        }
14113        if (_supportsOpacity) {
14114          pt = new CSSPropTween(style, "opacity", b, e - b, pt);
14115        } else {
14116          pt = new CSSPropTween(style, "opacity", b * 100, (e - b) * 100, pt);
14117          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.
14118          style.zoom = 1; //helps correct an IE issue.
14119          pt.type = 2;
14120          pt.b = "alpha(opacity=" + pt.s + ")";
14121          pt.e = "alpha(opacity=" + (pt.s + pt.c) + ")";
14122          pt.data = t;
14123          pt.plugin = plugin;
14124          pt.setRatio = _setIEOpacityRatio;
14125        }
14126        if (isAutoAlpha) {
14127          //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
14128          pt = new CSSPropTween(style, "visibility", 0, 0, pt, -1, null, false, 0, b !== 0 ? "inherit" : "hidden", e === 0 ? "hidden" : "inherit");
14129          pt.xs0 = "inherit";
14130          cssp._overwriteProps.push(pt.n);
14131          cssp._overwriteProps.push(p);
14132        }
14133        return pt;
14134      }
14135    });
14136    var _removeProp = function _removeProp(s, p) {
14137        if (p) {
14138          if (s.removeProperty) {
14139            if (p.substr(0, 2) === "ms" || p.substr(0, 6) === "webkit") {
14140              //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)
14141              p = "-" + p;
14142            }
14143            s.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());
14144          } else {
14145            //note: old versions of IE use "removeAttribute()" instead of "removeProperty()"
14146            s.removeAttribute(p);
14147          }
14148        }
14149      },
14150      _setClassNameRatio = function _setClassNameRatio(v) {
14151        this.t._gsClassPT = this;
14152        if (v === 1 || v === 0) {
14153          this.t.setAttribute("class", v === 0 ? this.b : this.e);
14154          var mpt = this.data,
14155            //first MiniPropTween
14156            s = this.t.style;
14157          while (mpt) {
14158            if (!mpt.v) {
14159              _removeProp(s, mpt.p);
14160            } else {
14161              s[mpt.p] = mpt.v;
14162            }
14163            mpt = mpt._next;
14164          }
14165          if (v === 1 && this.t._gsClassPT === this) {
14166            this.t._gsClassPT = null;
14167          }
14168        } else if (this.t.getAttribute("class") !== this.e) {
14169          this.t.setAttribute("class", this.e);
14170        }
14171      };
14172    _registerComplexSpecialProp("className", {
14173      parser: function parser(t, e, p, cssp, pt, plugin, vars) {
14174        var b = t.getAttribute("class") || "",
14175          //don't use t.className because it doesn't work consistently on SVG elements; getAttribute("class") and setAttribute("class", value") is more reliable.
14176          cssText = t.style.cssText,
14177          difData,
14178          bs,
14179          cnpt,
14180          cnptLookup,
14181          mpt;
14182        pt = cssp._classNamePT = new CSSPropTween(t, p, 0, 0, pt, 2);
14183        pt.setRatio = _setClassNameRatio;
14184        pt.pr = -11;
14185        _hasPriority = true;
14186        pt.b = b;
14187        bs = _getAllStyles(t, _cs);
14188        //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
14188ing that were there just for class-specific values)
14189        cnpt = t._gsClassPT;
14190        if (cnpt) {
14191          cnptLookup = {};
14192          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.
14193          while (mpt) {
14194            cnptLookup[mpt.p] = 1;
14195            mpt = mpt._next;
14196          }
14197          cnpt.setRatio(1);
14198        }
14199        t._gsClassPT = pt;
14200        pt.e = e.charAt(1) !== "=" ? e : b.replace(new RegExp("(?:\\s|^)" + e.substr(2) + "(?![\\w-])"), "") + (e.charAt(0) === "+" ? " " + e.substr(2) : "");
14201        t.setAttribute("class", pt.e);
14202        difData = _cssDif(t, bs, _getAllStyles(t), vars, cnptLookup);
14203        t.setAttribute("class", b);
14204        pt.data = difData.firstMPT;
14205        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).
14206        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)
14207        return pt;
14208      }
14209    });
14210    var _setClearPropsRatio = function _setClearPropsRatio(v) {
14211      if (v === 1 || v === 0) if (this.data._totalTime === this.data._totalDuration && this.data.data !== "isFromStart") {
14212        //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).
14213        var s = this.t.style,
14214          transformParse = _specialProps.transform.parse,
14215          a,
14216          p,
14217          i,
14218          clearTransform,
14219          transform;
14220        if (this.e === "all") {
14221          s.cssText = "";
14222          clearTransform = true;
14223        } else {
14224          a = this.e.split(" ").join("").split(",");
14225          i = a.length;
14226          while (--i > -1) {
14227            p = a[i];
14228            if (_specialProps[p]) {
14229              if (_specialProps[p].parse === transformParse) {
14230                clearTransform = true;
14231              } else {
14232                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"
14233              }
14234            }
14235            _removeProp(s, p);
14236          }
14237        }
14238        if (clearTransform) {
14239          _removeProp(s, _transformProp);
14240          transform = this.t._gsTransform;
14241          if (transform) {
14242            if (transform.svg) {
14243              this.t.removeAttribute("data-svg-origin");
14244              this.t.removeAttribute("transform");
14245            }
14246            delete this.t._gsTransform;
14247          }
14248        }
14249      }
14250    };
14251    _registerComplexSpecialProp("clearProps", {
14252      parser: function parser(t, e, p, cssp, pt) {
14253        pt = new CSSPropTween(t, p, 0, 0, pt, 2);
14254        pt.setRatio = _setClearPropsRatio;
14255        pt.e = e;
14256        pt.pr = -10;
14257        pt.data = cssp._tween;
14258        _hasPriority = true;
14259        return pt;
14260      }
14261    });
14262    p = "bezier,throwProps,physicsProps,physics2D".split(",");
14263    i = p.length;
14264    while (i--) {
14265      _registerPluginProp(p[i]);
14266    }
14267    p = _CSSPlugin.prototype;
14268    p._firstPT = p._lastParsedTransform = p._transform = null;
14269
14270    //gets called when the tween renders for the first time. This kicks everything off, recording start/end values, etc.
14271    p._onInitTween = function (target, vars, tween, index) {
14272      if (!target.nodeType) {
14273        //css is only for dom elements
14274        return false;
14275      }
14276      this._target = _target = target;
14277      this._tween = tween;
14278      this._vars = vars;
14279      _index = index;
14280      _autoRound = vars.autoRound;
14281      _hasPriority = false;
14282      _suffixMap = vars.suffixMap || _CSSPlugin.suffixMap;
14283      _cs = _getComputedStyle(target, "");
14284      _overwriteProps = this._overwriteProps;
14285      var style = target.style,
14286        v,
14287        pt,
14288        pt2,
14289        first,
14290        last,
14291        next,
14292        zIndex,
14293        tpt,
14294        threeD;
14295      if (_reqSafariFix) if (style.zIndex === "") {
14296        v = _getStyle(target, "zIndex", _cs);
14297        if (v === "auto" || v === "") {
14298          //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.
14299          this._addLazySet(style, "zIndex", 0);
14300        }
14301      }
14302      if (typeof vars === "string") {
14303        first = style.cssText;
14304        v = _getAllStyles(target, _cs);
14305        style.cssText = first + ";" + vars;
14306        v = _cssDif(target, v, _getAllStyles(target)).difs;
14307        if (!_supportsOpacity && _opacityValExp.test(vars)) {
14308          v.opacity = parseFloat(RegExp.$1);
14309        }
14310        vars = v;
14311        style.cssText = first;
14312      }
14313      if (vars.className) {
14314        //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.
14315        this._firstPT = pt = _specialProps.className.parse(target, vars.className, "className", this, null, null, vars);
14316      } else {
14317        this._firstPT = pt = this.parse(target, vars, null);
14318      }
14319      if (this._transformType) {
14320        threeD = this._transformType === 3;
14321        if (!_transformProp) {
14322          style.zoom = 1; //helps correct an IE issue.
14323        } else if (_isSafari) {
14324          _reqSafariFix = true;
14325          //if zIndex isn't set, iOS Safari doesn't repaint things correctly sometimes (seemingly at random).
14326          if (style.zIndex === "") {
14327            zIndex = _getStyle(target, "zIndex", _cs);
14328            if (zIndex === "auto" || zIndex === "") {
14329              this._addLazySet(style, "zIndex", 0);
14330            }
14331          }
14332          //Setting WebkitBackfaceVisibility corrects 3 bugs:
14333          // 1) [non-Android] Safari skips rendering changes to "top" and "left" that are made on the same frame/render as a transform update.
14334          // 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.
14335          // 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.
14336          //Note: we allow the user to override the auto-setting by defining WebkitBackfaceVisibility in the vars of the tween.
14337          if (_isSafariLT6) {
14338            this._addLazySet(style, "WebkitBackfaceVisibility", this._vars.WebkitBackfaceVisibility || (threeD ? "visible" : "hidden"));
14339          }
14340        }
14341        pt2 = pt;
14342        while (pt2 && pt2._next) {
14343          pt2 = pt2._next;
14344        }
14345        tpt = new CSSPropTween(target, "transform", 0, 0, null, 2);
14346        this._linkCSSP(tpt, null, pt2);
14347        tpt.setRatio = _transformProp ? _setTransformRatio : _setIETransformRatio;
14348        tpt.data = this._transform || _getTransform(target, _cs, true);
14349        tpt.tween = tween;
14350        tpt.pr = -1; //ensures that the transforms get applied after the components are updated.
14351        _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.
14352      }
14353      if (_hasPriority) {
14354        //reorders the linked list in order of pr (priority)
14355        while (pt) {
14356          next = pt._next;
14357          pt2 = first;
14358          while (pt2 && pt2.pr > pt.pr) {
14359            pt2 = pt2._next;
14360          }
14361          if (pt._prev = pt2 ? pt2._prev : last) {
14362            pt._prev._next = pt;
14363          } else {
14364            first = pt;
14365          }
14366          if (pt._next = pt2) {
14367            pt2._prev = pt;
14368          } else {
14369            last = pt;
14370          }
14371          pt = next;
14372        }
14373        this._firstPT = first;
14374      }
14375      return true;
14376    };
14377    p.parse = function (target, vars, pt, plugin) {
14378      var style = target.style,
14379        p,
14380        sp,
14381        bn,
14382        en,
14383        bs,
14384        es,
14385        bsfx,
14386        esfx,
14387        isStr,
14388        rel;
14389      for (p in vars) {
14390        es = vars[p]; //ending value string
14391        if (typeof es === "function") {
14392          es = es(_index, _target);
14393        }
14394        sp = _specialProps[p]; //SpecialProp lookup.
14395        if (sp) {
14396          pt = sp.parse(target, es, p, this, pt, plugin, vars);
14397        } else if (p.substr(0, 2) === "--") {
14398          //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.
14399          this._tween._propLookup[p] = this._addTween.call(this._tween, target.style, "setProperty", _getComputedStyle(target).getPropertyValue(p) + "", es + "", p, false, p);
14400          continue;
14401        } else {
14402          bs = _getStyle(target, p, _cs) + "";
14403          isStr = typeof es === "string";
14404          if (p === "color" || p === "fill" || p === "stroke" || p.indexOf("Color") !== -1 || isStr && _rgbhslExp.test(es)) {
14405            //Opera uses background: to define color sometimes in addition to backgroundColor:
14406            if (!isStr) {
14407              es = _parseColor(es);
14408              es = (es.length > 3 ? "rgba(" : "rgb(") + es.join(",") + ")";
14409            }
14410            pt = _parseComplex(style, p, bs, es, true, "transparent", pt, 0, plugin);
14411          } else if (isStr && _complexExp.test(es)) {
14412            pt = _parseComplex(style, p, bs, es, true, null, pt, 0, plugin);
14413          } else {
14414            bn = parseFloat(bs);
14415            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.
14416
14417            if (bs === "" || bs === "auto") {
14418              if (p === "width" || p === "height") {
14419                bn = _getDimension(target, p, _cs);
14420                bsfx = "px";
14421              } else if (p === "left" || p === "top") {
14422                bn = _calculateOffset(target, p, _cs);
14423                bsfx = "px";
14424              } else {
14425                bn = p !== "opacity" ? 0 : 1;
14426                bsfx = "";
14427              }
14428            }
14429            rel = isStr && es.charAt(1) === "=";
14430            if (rel) {
14431              en = parseInt(es.charAt(0) + "1", 10);
14432              es = es.substr(2);
14433              en *= parseFloat(es);
14434              esfx = es.replace(_suffixExp, "");
14435            } else {
14436              en = parseFloat(es);
14437              esfx = isStr ? es.replace(_suffixExp, "") : "";
14438            }
14439            if (esfx === "") {
14440              esfx = p in _suffixMap ? _suffixMap[p] : bsfx; //populate the end suffix, prioritizing the map, then if none is found, use the beginning suffix.
14441            }
14442            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.
14443            //if the beginning/ending suffixes don't match, normalize them...
14444            if (bsfx !== esfx) if (esfx !== "" || p === "lineHeight") if (en || en === 0) if (bn) {
14445              //note: if the beginning value (bn) is 0, we don't need to convert units!
14446              bn = _convertToPixels(target, p, bn, bsfx);
14447              if (esfx === "%") {
14448                bn /= _convertToPixels(target, p, 100, "%") / 100;
14449                if (vars.strictUnits !== true) {
14450                  //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.
14451                  bs = bn + "%";
14452                }
14453              } else if (esfx === "em" || esfx === "rem" || esfx === "vw" || esfx === "vh") {
14454                bn /= _convertToPixels(target, p, 1, esfx);
14455
14456                //otherwise convert to pixels.
14457              } else if (esfx !== "px") {
14458                en = _convertToPixels(target, p, en, esfx);
14459                esfx = "px"; //we don't use bsfx after this, so we don't need to set it to px too.
14460              }
14461              if (rel) if (en || en === 0) {
14462                es = en + bn + esfx; //the changes we made affect relative calculations, so adjust the end value here.
14463              }
14464            }
14465            if (rel) {
14466              en += bn;
14467            }
14468            if ((bn || bn === 0) && (en || en === 0)) {
14469              //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.
14470              pt = new CSSPropTween(style, p, bn, en - bn, pt, 0, p, _autoRound !== false && (esfx === "px" || p === "zIndex"), 0, bs, es);
14471              pt.xs0 = esfx;
14472              //DEBUG: _log("tween "+p+" from "+pt.b+" ("+bn+esfx+") to "+pt.e+" with suffix: "+pt.xs0);
14473            } else if (style[p] === undefined || !es && (es + "" === "NaN" || es == null)) {
14474              _log("invalid " + p + " tween value: " + vars[p]);
14475            } else {
14476              pt = new CSSPropTween(style, p, en || bn || 0, 0, pt, -1, p, false, 0, bs, es);
14477              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.
14478              //DEBUG: _log("non-tweening value "+p+": "+pt.xs0);
14479            }
14480          }
14481        }
14482        if (plugin) if (pt && !pt.plugin) {
14483          pt.plugin = plugin;
14484        }
14485      }
14486      return pt;
14487    };
14488
14489    //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.
14490    p.setRatio = function (v) {
14491      var pt = this._firstPT,
14492        min = 0.000001,
14493        val,
14494        str,
14495        i;
14496      //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).
14497      if (v === 1 && (this._tween._time === this._tween._duration || this._tween._time === 0)) {
14498        while (pt) {
14499          if (pt.type !== 2) {
14500            if (pt.r && pt.type !== -1) {
14501              val = Math.round(pt.s + pt.c);
14502              if (!pt.type) {
14503                pt.t[pt.p] = val + pt.xs0;
14504              } else if (pt.type === 1) {
14505                //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
14506                i = pt.l;
14507                str = pt.xs0 + val + pt.xs1;
14508                for (i = 1; i < pt.l; i++) {
14509                  str += pt["xn" + i] + pt["xs" + (i + 1)];
14510                }
14511                pt.t[pt.p] = str;
14512              }
14513            } else {
14514              pt.t[pt.p] = pt.e;
14515            }
14516          } else {
14517            pt.setRatio(v);
14518          }
14519          pt = pt._next;
14520        }
14521      } else if (v || !(this._tween._time === this._tween._duration || this._tween._time === 0) || this._tween._rawPrevTime === -0.000001) {
14522        while (pt) {
14523          val = pt.c * v + pt.s;
14524          if (pt.r) {
14525            val = Math.round(val);
14526          } else if (val < min) if (val > -min) {
14527            val = 0;
14528          }
14529          if (!pt.type) {
14530            pt.t[pt.p] = val + pt.xs0;
14531          } else if (pt.type === 1) {
14532            //complex value (one that typically has multiple numbers inside a string, like "rect(5px,10px,20px,25px)"
14533            i = pt.l;
14534            if (i === 2) {
14535              pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2;
14536            } else if (i === 3) {
14537              pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3;
14538            } else if (i === 4) {
14539              pt.t[pt.p] = pt.xs0 + val + pt.xs1 + pt.xn1 + pt.xs2 + pt.xn2 + pt.xs3 + pt.xn3 + pt.xs4;
14540            } else if (i === 5) {
14541              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;
14542            } else {
14543              str = pt.xs0 + val + pt.xs1;
14544              for (i = 1; i < pt.l; i++) {
14545                str += pt["xn" + i] + pt["xs" + (i + 1)];
14546              }
14547              pt.t[pt.p] = str;
14548            }
14549          } else if (pt.type === -1) {
14550            //non-tweening value
14551            pt.t[pt.p] = pt.xs0;
14552          }
14552 else if (pt.setRatio) {
14553            //custom setRatio() for things like SpecialProps, external plugins, etc.
14554            pt.setRatio(v);
14555          }
14556          pt = pt._next;
14557        }
14558
14559        //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).
14560      } else {
14561        while (pt) {
14562          if (pt.type !== 2) {
14563            pt.t[pt.p] = pt.b;
14564          } else {
14565            pt.setRatio(v);
14566          }
14567          pt = pt._next;
14568        }
14569      }
14570    };
14571
14572    /**
14573     * @private
14574     * Forces rendering of the target's transforms (rotation, scale, etc.) whenever the CSSPlugin's setRatio() is called.
14575     * Basically, this tells the CSSPlugin to create a CSSPropTween (type 2) after instantiation that runs last in the linked
14576     * list and calls the appropriate (3D or 2D) rendering function. We separate this into its own method so that we can call
14577     * it from other plugins like BezierPlugin if, for example, it needs to apply an autoRotation and this CSSPlugin
14578     * doesn't have any transform-related properties of its own. You can call this method as many times as you
14579     * want and it won't create duplicate CSSPropTweens.
14580     *
14581     * @param {boolean} threeD if true, it should apply 3D tweens (otherwise, just 2D ones are fine and typically faster)
14582     */
14583    p._enableTransforms = function (threeD) {
14584      this._transform = this._transform || _getTransform(this._target, _cs, true); //ensures that the element has a _gsTransform property with the appropriate values.
14585      this._transformType = !(this._transform.svg && _useSVGTransformAttr) && (threeD || this._transformType === 3) ? 3 : 2;
14586    };
14587    var lazySet = function lazySet(v) {
14588      this.t[this.p] = this.e;
14589      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.
14590    };
14591    /** @private Gives us a way to set a value on the first render (and only the first render). **/
14592    p._addLazySet = function (t, p, v) {
14593      var pt = this._firstPT = new CSSPropTween(t, p, 0, 0, this._firstPT, 2);
14594      pt.e = v;
14595      pt.setRatio = lazySet;
14596      pt.data = this;
14597    };
14598
14599    /** @private **/
14600    p._linkCSSP = function (pt, next, prev, remove) {
14601      if (pt) {
14602        if (next) {
14603          next._prev = pt;
14604        }
14605        if (pt._next) {
14606          pt._next._prev = pt._prev;
14607        }
14608        if (pt._prev) {
14609          pt._prev._next = pt._next;
14610        } else if (this._firstPT === pt) {
14611          this._firstPT = pt._next;
14612          remove = true; //just to prevent resetting this._firstPT 5 lines down in case pt._next is null. (optimized for speed)
14613        }
14614        if (prev) {
14615          prev._next = pt;
14616        } else if (!remove && this._firstPT === null) {
14617          this._firstPT = pt;
14618        }
14619        pt._next = next;
14620        pt._prev = prev;
14621      }
14622      return pt;
14623    };
14624    p._mod = function (lookup) {
14625      var pt = this._firstPT;
14626      while (pt) {
14627        if (typeof lookup[pt.p] === "function" && lookup[pt.p] === Math.round) {
14628          //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..
14629          pt.r = 1;
14630        }
14631        pt = pt._next;
14632      }
14633    };
14634
14635    //we need to make sure that if alpha or autoAlpha is killed, opacity is too. And autoAlpha affects the "visibility" property.
14636    p._kill = function (lookup) {
14637      var copy = lookup,
14638        pt,
14639        p,
14640        xfirst;
14641      if (lookup.autoAlpha || lookup.alpha) {
14642        copy = {};
14643        for (p in lookup) {
14644          //copy the lookup so that we're not changing the original which may be passed elsewhere.
14645          copy[p] = lookup[p];
14646        }
14647        copy.opacity = 1;
14648        if (copy.autoAlpha) {
14649          copy.visibility = 1;
14650        }
14651      }
14652      if (lookup.className && (pt = this._classNamePT)) {
14653        //for className tweens, we need to kill any associated CSSPropTweens too; a linked list starts at the className's "xfirst".
14654        xfirst = pt.xfirst;
14655        if (xfirst && xfirst._prev) {
14656          this._linkCSSP(xfirst._prev, pt._next, xfirst._prev._prev); //break off the prev
14657        } else if (xfirst === this._firstPT) {
14658          this._firstPT = pt._next;
14659        }
14660        if (pt._next) {
14661          this._linkCSSP(pt._next, pt._next._next, xfirst._prev);
14662        }
14663        this._classNamePT = null;
14664      }
14665      pt = this._firstPT;
14666      while (pt) {
14667        if (pt.plugin && pt.plugin !== p && pt.plugin._kill) {
14668          //for plugins that are registered with CSSPlugin, we should notify them of the kill.
14669          pt.plugin._kill(lookup);
14670          p = pt.plugin;
14671        }
14672        pt = pt._next;
14673      }
14674      return TweenPlugin.prototype._kill.call(this, copy);
14675    };
14676
14677    //used by cascadeTo() for gathering all the style properties of each child element into an array for c
14677omparison.
14678    var _getChildStyles2 = function _getChildStyles(e, props, targets) {
14679      var children, i, child, type;
14680      if (e.slice) {
14681        i = e.length;
14682        while (--i > -1) {
14683          _getChildStyles2(e[i], props, targets);
14684        }
14685        return;
14686      }
14687      children = e.childNodes;
14688      i = children.length;
14689      while (--i > -1) {
14690        child = children[i];
14691        type = child.type;
14692        if (child.style) {
14693          props.push(_getAllStyles(child));
14694          if (targets) {
14695            targets.push(child);
14696          }
14697        }
14698        if ((type === 1 || type === 9 || type === 11) && child.childNodes.length) {
14699          _getChildStyles2(child, props, targets);
14700        }
14701      }
14702    };
14703
14704    /**
14705     * Typically only useful for className tweens that may affect child elements, this method creates a TweenLite
14706     * and then compares the style properties of all the target's child elements at the tween's start and end, and
14707     * if any are different, it also creates tweens for those and returns an array containing ALL of the resulting
14708     * tweens (so that you can easily add() them to a TimelineLite, for example). The reason this functionality is
14709     * wrapped into a separate static method of CSSPlugin instead of being integrated into all regular className tweens
14710     * is because it creates entirely new tweens that may have completely different targets than the original tween,
14711     * so if they were all lumped into the original tween instance, it would be inconsistent with the rest of the API
14712     * and it would create other problems. For example:
14713     *  - 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)
14714     *  - 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.
14715     *  - 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.
14716     *
14717     * @param {Object} target object to be tweened
14718     * @param {number} Duration in seconds (or frames for frames-based tweens)
14719     * @param {Object} Object containing the end values, like {className:"newClass", ease:Linear.easeNone}
14720     * @return {Array} An array of TweenLite instances
14721     */
14722    _CSSPlugin.cascadeTo = function (target, duration, vars) {
14723      var tween = TweenLite.to(target, duration, vars),
14724        results = [tween],
14725        b = [],
14726        e = [],
14727        targets = [],
14728        _reservedProps = TweenLite._internals.reservedProps,
14729        i,
14730        difs,
14731        p,
14732        from;
14733      target = tween._targets || tween.target;
14734      _getChildStyles2(target, b, targets);
14735      tween.render(duration, true, true);
14736      _getChildStyles2(target, e);
14737      tween.render(0, true, true);
14738      tween._enabled(true);
14739      i = targets.length;
14740      while (--i > -1) {
14741        difs = _cssDif(targets[i], b[i], e[i]);
14742        if (difs.firstMPT) {
14743          difs = difs.difs;
14744          for (p in vars) {
14745            if (_reservedProps[p]) {
14746              difs[p] = vars[p];
14747            }
14748          }
14749          from = {};
14750          for (p in difs) {
14751            from[p] = b[i][p];
14752          }
14753          results.push(TweenLite.fromTo(targets[i], duration, from, difs));
14754        }
14755      }
14756      return results;
14757    };
14758    TweenPlugin.activate([_CSSPlugin]);
14759    return _CSSPlugin;
14760  }, true);
14761
14762  /*
14763   * ----------------------------------------------------------------
14764   * RoundPropsPlugin
14765   * ----------------------------------------------------------------
14766   */
14767  (function () {
14768    var RoundPropsPlugin = _gsScope._gsDefine.plugin({
14769        propName: "roundProps",
14770        version: "1.6.0",
14771        priority: -1,
14772        API: 2,
14773        //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
14774        init: function init(target, value, tween) {
14775          this._tween = tween;
14776          return true;
14777        }
14778      }),
14779      _roundLinkedList = function _roundLinkedList(node) {
14780        while (node) {
14781          if (!node.f && !node.blob) {
14782            node.m = Math.round;
14783          }
14784          node = node._next;
14785        }
14786      },
14787      p = RoundPropsPlugin.prototype;
14788    p._onInitAllProps = function () {
14789      var tween = this._tween,
14790        rp = tween.vars.roundProps.join ? tween.vars.roundProps : tween.vars.roundProps.split(","),
14791        i = rp.length,
14792        lookup = {},
14793        rpt = tween._propLookup.roundProps,
14794        prop,
14795        pt,
14796        next;
14797      while (--i > -1) {
14798        lookup[rp[i]] = Math.round;
14799      }
14800      i = rp.length;
14801      while (--i > -1) {
14802        prop = rp[i];
14803        pt = tween._firstPT;
14804        while (pt) {
14805          next = pt._next; //record here, because it may get removed
14806          if (pt.pg) {
14807            pt.t._mod(lookup);
14808          } else if (pt.n === prop) {
14809            if (pt.f === 2 && pt.t) {
14810              //a blob (text containing multiple numeric values)
14811              _roundLinkedList(pt.t._firstPT);
14812            } else {
14813              this._add(pt.t, prop, pt.s, pt.c);
14814              //remove from linked list
14815              if (next) {
14816                next._prev = pt._prev;
14817              }
14818              if (pt._prev) {
14819                pt._prev._next = next;
14820              } else if (tween._firstPT === pt) {
14821                tween._firstPT = next;
14822              }
14823              pt._next = pt._prev = null;
14824              tween._propLookup[prop] = rpt;
14825            }
14826          }
14827          pt = next;
14828        }
14829      }
14830      return false;
14831    };
14832    p._add = function (target, p, s, c) {
14833      this._addTween(target, p, s, s + c, p, Math.round);
14834      this._overwriteProps.push(p);
14835    };
14836  })();
14837
14838  /*
14839   * ----------------------------------------------------------------
14840   * AttrPlugin
14841   * ----------------------------------------------------------------
14842   */
14843
14844  (function () {
14845    _gsScope._gsDefine.plugin({
14846      propName: "attr",
14847      API: 2,
14848      version: "0.6.1",
14849      //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
14850      init: function init(target, value, tween, index) {
14851        var p, end;
14852        if (typeof target.setAttribute !== "function") {
14853          return false;
14854        }
14855        for (p in value) {
14856          end = value[p];
14857          if (typeof end === "function") {
14858            end = end(index, target);
14859          }
14860          this._addTween(target, "setAttribute", target.getAttribute(p) + "", end + "", p, false, p);
14861          this._overwriteProps.push(p);
14862        }
14863        return true;
14864      }
14865    });
14866  })();
14867
14868  /*
14869   * ----------------------------------------------------------------
14870   * DirectionalRotationPlugin
14871   * ----------------------------------------------------------------
14872   */
14873  _gsScope._gsDefine.plugin({
14874    propName: "directionalRotation",
14875    version: "0.3.1",
14876    API: 2,
14877    //called when the tween renders for the first time. This is where initial values should be recorded and any setup routines should run.
14878    init: function init(target, value, tween, index) {
14879      if (_typeof(value) !== "object") {
14880        value = {
14881          rotation: value
14882        };
14883      }
14884      this.finals = {};
14885      var cap = value.useRadians === true ? Math.PI * 2 : 360,
14886        min = 0.000001,
14887        p,
14888        v,
14889        start,
14890        end,
14891        dif,
14892        split;
14893      for (p in value) {
14894        if (p !== "useRadians") {
14895          end = value[p];
14896          if (typeof end === "function") {
14897            end = end(index, target);
14898          }
14899          split = (end + "").split("_");
14900          v = split[0];
14901          start = parseFloat(typeof target[p] !== "function" ? target[p] : target[p.indexOf("set") || typeof target["get" + p.substr(3)] !== "function" ? p : "get" + p.substr(3)]());
14902          end = this.finals[p] = typeof v === "string" && v.charAt(1) === "=" ? start + parseInt(v.charAt(0) + "1", 10) * Number(v.substr(2)) : Number(v) || 0;
14903          dif = end - start;
14904          if (split.length) {
14905            v = split.join("_");
14906            if (v.indexOf("short") !== -1) {
14907              dif = dif % cap;
14908              if (dif !== dif % (cap / 2)) {
14909                dif = dif < 0 ? dif + cap : dif - cap;
14910              }
14911            }
14912            if (v.indexOf("_cw") !== -1 && dif < 0) {
14913              dif = (dif + cap * 9999999999) % cap - (dif / cap | 0) * cap;
14914            } else if (v.indexOf("ccw") !== -1 && dif > 0) {
14915              dif = (dif - cap * 9999999999) % cap - (dif / cap | 0) * cap;
14916            }
14917          }
14918          if (dif > min || dif < -min) {
14919            this._addTween(target, p, start, start + dif, p);
14920            this._overwriteProps.push(p);
14921          }
14922        }
14923      }
14924      return true;
14925    },
14926    //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.)
14927    set: function set(ratio) {
14928      var pt;
14929      if (ratio !== 1) {
14930        this._super.setRatio.call(this, ratio);
14931      } else {
14932        pt = this._firstPT;
14933        while (pt) {
14934          if (pt.f) {
14935            pt.t[pt.p](this.finals[pt.p]);
14936          } else {
14937            pt.t[pt.p] = this.finals[pt.p];
14938          }
14939          pt = pt._next;
14940        }
14941      }
14942    }
14943  })._autoCSS = true;
14944
14945  /*
14946   * ----------------------------------------------------------------
14947   * EasePack
14948   * ----------------------------------------------------------------
14949   */
14950  _gsScope._gsDefine("easing.Back", ["easing.Ease"], function (Ease) {
14951    var w = _gsScope.GreenSockGlobals || _gsScope,
14952      gs = w.com.greensock,
14953      _2PI = Math.PI * 2,
14954      _HALF_PI = Math.PI / 2,
14955      _class = gs._class,
14956      _create = function _create(n, f) {
14957        var C = _class("easing." + n, function () {}, true),
14958          p = C.prototype = new Ease();
14959        p.constructor = C;
14960        p.getRatio = f;
14961        return C;
14962      },
14963      _easeReg = Ease.register || function () {},
14964      //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.
14965      _wrap = function _wrap(name, EaseOut, EaseIn, EaseInOut, aliases) {
14966        var C = _class("easing." + name, {
14967          easeOut: new EaseOut(),
14968          easeIn: new EaseIn(),
14969          easeInOut: new EaseInOut()
14970        }, true);
14971        _easeReg(C, name);
14972        return C;
14973      },
14974      EasePoint = function EasePoint(time, value, next) {
14975        this.t = time;
14976        this.v = value;
14977        if (next) {
14978          this.next = next;
14979          next.prev = this;
14980          this.c = next.v - value;
14981          this.gap = next.t - time;
14982        }
14983      },
14984      //Back
14985      _createBack = function _createBack(n, f) {
14986        var C = _class("easing." + n, function (overshoot) {
14987            this._p1 = overshoot || overshoot === 0 ? overshoot : 1.70158;
14988            this._p2 = this._p1 * 1.525;
14989          }, true),
14990          p = C.prototype = new Ease();
14991        p.constructor = C;
14992        p.getRatio = f;
14993        p.config = function (overshoot) {
14994          return new C(overshoot);
14995        };
14996        return C;
14997      },
14998      Back = _wrap("Back", _createBack("BackOut", function (p) {
14999        return (p = p - 1) * p * ((this._p1 + 1) * p + this._p1) + 1;
15000      }), _createBack("BackIn", function (p) {
15001        return p * p * ((this._p1 + 1) * p - this._p1);
15002      }), _createBack("BackInOut", function (p) {
15003        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);
15004      })),
15005      //SlowMo
15006      SlowMo = _class("easing.SlowMo", function (linearRatio, power, yoyoMode) {
15007        power = power || power === 0 ? power : 0.7;
15008        if (linearRatio == null) {
15009          linearRatio = 0.7;
15010        } else if (linearRatio > 1) {
15011          linearRatio = 1;
15012        }
15013        this._p = linearRatio !== 1 ? power : 0;
15014        this._p1 = (1 - linearRatio) / 2;
15015        this._p2 = linearRatio;
15016        this._p3 = this._p1 + this._p2;
15017        this._calcEnd = yoyoMode === true;
15018      }, true),
15019      p = SlowMo.prototype = new Ease(),
15020      SteppedEase,
15021      ExpoScaleEase,
15022      RoughEase,
15023      _createElastic;
15024    p.constructor = SlowMo;
15025    p.getRatio = function (p) {
15026      var r = p + (0.5 - p) * this._p;
15027      if (p < this._p1) {
15028        return this._calcEnd ? 1 - (p = 1 - p / this._p1) * p : r - (p = 1 - p / this._p1) * p * p * p * r;
15029      } else if (p > this._p3) {
15030        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
15031      }
15032      return this._calcEnd ? 1 : r;
15033    };
15034    SlowMo.ease = new SlowMo(0.7, 0.7);
15035    p.config = SlowMo.config = function (linearRatio, power, yoyoMode) {
15036      return new SlowMo(linearRatio, power, yoyoMode);
15037    };
15038
15039    //SteppedEase
15040    SteppedEase = _class("easing.SteppedEase", function (steps, immediateStart) {
15041      steps = steps || 1;
15042      this._p1 = 1 / steps;
15043      this._p2 = steps + (immediateStart ? 0 : 1);
15044      this._p3 = immediateStart ? 1 : 0;
15045    }, true);
15046    p = SteppedEase.prototype = new Ease();
15047    p.constructor = SteppedEase;
15048    p.getRatio = function (p) {
15049      if (p < 0) {
15050        p = 0;
15051      } else if (p >= 1) {
15052        p = 0.999999999;
15053      }
15054      return ((this._p2 * p | 0) + this._p3) * this._p1;
15055    };
15056    p.config = SteppedEase.config = function (steps, immediateStart) {
15057      return new SteppedEase(steps, immediateStart);
15058    };
15059
15060    //ExpoScaleEase
15061    ExpoScaleEase = _class("easing.ExpoScaleEase", function (start, end, ease) {
15062      this._p1 = Math.log(end / start);
15063      this._p2 = end - start;
15064      this._p3 = start;
15065      this._ease = ease;
15066    }, true);
15067    p = ExpoScaleEase.prototype = new Ease();
15068    p.constructor = ExpoScaleEase;
15069    p.getRatio = function (p) {
15070      if (this._ease) {
15071        p = this._ease.getRatio(p);
15072      }
15073      return (this._p3 * Math.exp(this._p1 * p) - this._p3) / this._p2;
15074    };
15075    p.config = ExpoScaleEase.config = function (start, end, ease) {
15076      return new ExpoScaleEase(start, end, ease);
15077    };
15078
15079    //RoughEase
15080    RoughEase = _class("easing.RoughEase", function (vars) {
15081      vars = vars || {};
15082      var taper = vars.taper || "none",
15083        a = [],
15084        cnt = 0,
15085        points = (vars.points || 20) | 0,
15086        i = points,
15087        randomize = vars.randomize !== false,
15088        clamp = vars.clamp === true,
15089        template = vars.template instanceof Ease ? vars.template : null,
15090        strength = typeof vars.strength === "number" ? vars.strength * 0.4 : 0.4,
15091        x,
15092        y,
15093        bump,
15094        invX,
15095        obj,
15096        pnt;
15097      while (--i > -1) {
15098        x = randomize ? Math.random() : 1 / points * i;
15099        y = template ? template.getRatio(x) : x;
15100        if (taper === "none") {
15101          bump = strength;
15102        } else if (taper === "out") {
15103          invX = 1 - x;
15104          bump = invX * invX * strength;
15105        } else if (taper === "in") {
15106          bump = x * x * strength;
15107        } else if (x < 0.5) {
15108          //"both" (start)
15109          invX = x * 2;
15110          bump = invX * invX * 0.5 * strength;
15111        } else {
15112          //"both" (end)
15113          invX = (1 - x) * 2;
15114          bump = invX * invX * 0.5 * strength;
15115        }
15116        if (randomize) {
15117          y += Math.random() * bump - bump * 0.5;
15118        } else if (i % 2) {
15119          y += bump * 0.5;
15120        } else {
15121          y -= bump * 0.5;
15122        }
15123        if (clamp) {
15124          if (y > 1) {
15125            y = 1;
15126          } else if (y < 0) {
15127            y = 0;
15128          }
15129        }
15130        a[cnt++] = {
15131          x: x,
15132          y: y
15133        };
15134      }
15135      a.sort(function (a, b) {
15136        return a.x - b.x;
15137      });
15138      pnt = new EasePoint(1, 1, null);
15139      i = points;
15140      while (--i > -1) {
15141        obj = a[i];
15142        pnt = new EasePoint(obj.x, obj.y, pnt);
15143      }
15144      this._prev = new EasePoint(0, 0, pnt.t !== 0 ? pnt : pnt.next);
15145    }, true);
15146    p = RoughEase.prototype = new Ease();
15147    p.constructor = RoughEase;
15148    p.getRatio = function (p) {
15149      var pnt = this._prev;
15150      if (p > pnt.t) {
15151        while (pnt.next && p >= pnt.t) {
15152          pnt = pnt.next;
15153        }
15154        pnt = pnt.prev;
15155      } else {
15156        while (pnt.prev && p <= pnt.t) {
15157          pnt = pnt.prev;
15158        }
15159      }
15160      this._prev = pnt;
15161      return pnt.v + (p - pnt.t) / pnt.gap * pnt.c;
15162    };
15163    p.config = function (vars) {
15164      return new RoughEase(vars);
15165    };
15166    RoughEase.ease = new RoughEase();
15167
15168    //Bounce
15169    _wrap("Bounce", _create("BounceOut", function (p) {
15170      if (p < 1 / 2.75) {
15171        return 7.5625 * p * p;
15172      } else if (p < 2 / 2.75) {
15173        return 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;
15174      } else if (p < 2.5 / 2.75) {
15175        return 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;
15176      }
15177      return 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;
15178    }), _create("BounceIn", function (p) {
15179      if ((p = 1 - p) < 1 / 2.75) {
15180        return 1 - 7.5625 * p * p;
15181      } else if (p < 2 / 2.75) {
15182        return 1 - (7.5625 * (p -= 1.5 / 2.75) * p + 0.75);
15183      } else if (p < 2.5 / 2.75) {
15184        return 1 - (7.5625 * (p -= 2.25 / 2.75) * p + 0.9375);
15185      }
15186      return 1 - (7.5625 * (p -= 2.625 / 2.75) * p + 0.984375);
15187    }), _create("BounceInOut", function (p) {
15188      var invert = p < 0.5;
15189      if (invert) {
15190        p = 1 - p * 2;
15191      } else {
15192        p = p * 2 - 1;
15193      }
15194      if (p < 1 / 2.75) {
15195        p = 7.5625 * p * p;
15196      } else if (p < 2 / 2.75) {
15197        p = 7.5625 * (p -= 1.5 / 2.75) * p + 0.75;
15198      } else if (p < 2.5 / 2.75) {
15199        p = 7.5625 * (p -= 2.25 / 2.75) * p + 0.9375;
15200      } else {
15201        p = 7.5625 * (p -= 2.625 / 2.75) * p + 0.984375;
15202      }
15203      return invert ? (1 - p) * 0.5 : p * 0.5 + 0.5;
15204    }));
15205
15206    //CIRC
15207    _wrap("Circ", _create("CircOut", function (p) {
15208      return Math.sqrt(1 - (p = p - 1) * p);
15209    }), _create("CircIn", function (p) {
15210      return -(Math.sqrt(1 - p * p) - 1);
15211    }), _create("CircInOut", function (p) {
15212      return (p *= 2) < 1 ? -0.5 * (Math.sqrt(1 - p * p) - 1) : 0.5 * (Math.sqrt(1 - (p -= 2) * p) + 1);
15213    }));
15214
15215    //Elastic
15216    _createElastic = function _createElastic(n, f, def) {
15217      var C = _class("easing." + n, function (amplitude, period) {
15218          this._p1 = amplitude >= 1 ? amplitude : 1;
15218 //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.
15219          this._p2 = (period || def) / (amplitude < 1 ? amplitude : 1);
15220          this._p3 = this._p2 / _2PI * (Math.asin(1 / this._p1) || 0);
15221          this._p2 = _2PI / this._p2; //precalculate to optimize
15222        }, true),
15223        p = C.prototype = new Ease();
15224      p.constructor = C;
15225      p.getRatio = f;
15226      p.config = function (amplitude, period) {
15227        return new C(amplitude, period);
15228      };
15229      return C;
15230    };
15231    _wrap("Elastic", _createElastic("ElasticOut", function (p) {
15232      return this._p1 * Math.pow(2, -10 * p) * Math.sin((p - this._p3) * this._p2) + 1;
15233    }, 0.3), _createElastic("ElasticIn", function (p) {
15234      return -(this._p1 * Math.pow(2, 10 * (p -= 1)) * Math.sin((p - this._p3) * this._p2));
15235    }, 0.3), _createElastic("ElasticInOut", function (p) {
15236      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;
15237    }, 0.45));
15238
15239    //Expo
15240    _wrap("Expo", _create("ExpoOut", function (p) {
15241      return 1 - Math.pow(2, -10 * p);
15242    }), _create("ExpoIn", function (p) {
15243      return Math.pow(2, 10 * (p - 1)) - 0.001;
15244    }), _create("ExpoInOut", function (p) {
15245      return (p *= 2) < 1 ? 0.5 * Math.pow(2, 10 * (p - 1)) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
15246    }));
15247
15248    //Sine
15249    _wrap("Sine", _create("SineOut", function (p) {
15250      return Math.sin(p * _HALF_PI);
15251    }), _create("SineIn", function (p) {
15252      return -Math.cos(p * _HALF_PI) + 1;
15253    }), _create("SineInOut", function (p) {
15254      return -0.5 * (Math.cos(Math.PI * p) - 1);
15255    }));
15256    _class("easing.EaseLookup", {
15257      find: function find(s) {
15258        return Ease.map[s];
15259      }
15260    }, true);
15261
15262    //register the non-standard eases
15263    _easeReg(w.SlowMo, "SlowMo", "ease,");
15264    _easeReg(RoughEase, "RoughEase", "ease,");
15265    _easeReg(SteppedEase, "SteppedEase", "ease,");
15266    return Back;
15267  }, true);
15268});
15269if (_gsScope._gsDefine) {
15270  _gsScope._gsQueue.pop()();
15271} //necessary in case TweenLite was already loaded separately.
15272
15273/*
15274 * ----------------------------------------------------------------
15275 * Base classes like TweenLite, SimpleTimeline, Ease, Ticker, etc.
15276 * ----------------------------------------------------------------
15277 */
15278(function (window, moduleName) {
15279  "use strict";
15280
15281  var _exports = {},
15282    _doc = window.document,
15283    _globals = window.GreenSockGlobals = window.GreenSockGlobals || window;
15284  if (_globals.TweenLite) {
15285    return; //in case the core set of classes is already loaded, don't instantiate twice.
15286  }
15287  var _namespace = function _namespace(ns) {
15288      var a = ns.split("."),
15289        p = _globals,
15290        i;
15291      for (i = 0; i < a.length; i++) {
15292        p[a[i]] = p = p[a[i]] || {};
15293      }
15294      return p;
15295    },
15296    gs = _namespace("com.greensock"),
15297    _tinyNum = 0.0000000001,
15298    _slice = function _slice(a) {
15299      //don't use Array.prototype.slice.call(target, 0) because that doesn't work in IE8 with a NodeList that's returned by querySelectorAll()
15300      var b = [],
15301        l = a.length,
15302        i;
15303      for (i = 0; i !== l; b.push(a[i++])) {}
15304      return b;
15305    },
15306    _emptyFunc = function _emptyFunc() {},
15307    _isArray = function () {
15308      //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)
15309      var toString = Object.prototype.toString,
15310        array = toString.call([]);
15311      return function (obj) {
15312        return obj != null && (obj instanceof Array || _typeof(obj) === "object" && !!obj.push && toString.call(obj) === array);
15313      };
15314    }(),
15315    a,
15316    i,
15317    p,
15318    _ticker,
15319    _tickerActive,
15320    _defLookup = {},
15321    /**
15322     * @constructor
15323     * Defines a GreenSock class, optionally with an array of dependencies that must be instantiated first and passed into the definition.
15324     * This allows users to load GreenSock JS files in any order even if they have interdependencies (like CSSPlugin extends TweenPlugin which is
15325     * inside TweenLite.js, but if CSSPlugin is loaded first, it should wait to run its code until TweenLite.js loads and instantiates TweenPlugin
15326     * and then pass TweenPlugin to CSSPlugin's definition). This is all done automatically and internally.
15327     *
15328     * Every definition will be added to a "com.greensock" global object (typically window, but if a window.GreenSockGlobals object is found,
15329     * 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,
15330     * it is ALSO referenced at window.TweenLite. However some classes aren't considered global, like the base com.greensock.core.Animation class, so
15331     * those will only be at the package like window.com.greensock.core.Animation. Again, if you define a GreenSockGlobals object on the window, everything
15332     * gets tucked neatly inside there instead of on the window directly. This allows you to do advanced things like load multiple versions of GreenSock
15333     * 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
15334     * sandbox the banner one like:
15335     *
15336     * <script>
15337     *     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.
15338     * </script>
15339     * <script src="js/greensock/v1.7/TweenMax.js"></script>
15340     * <script>
15341     *     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(...)
15342     * </script>
15343     * <script src="js/greensock/v1.6/TweenMax.js"></script>
15344     * <script>
15345     *     gs.TweenLite.to(...); //would use v1.7
15346     *     TweenLite.to(...); //would use v1.6
15347     * </script>
15348     *
15349     * @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".
15350     * @param {!Array.<string>} dependencies An array of dependencies (described as their namespaces minus "com.greensock." prefix). For example ["TweenLite","plugins.TweenPlugin","core.Animation"]
15351     * @param {!function():Object} func The function that should be called and passed the resolved dependencies which will return the actual class for this definition.
15352     * @param {boolean=} global If true, the class will be added to the global scope (typically window unless you define a window.GreenSockGlobals object)
15353     */
15354    _Definition = function Definition(ns, dependencies, func, global) {
15355      this.sc = _defLookup[ns] ? _defLookup[ns].sc : []; //subclasses
15356      _defLookup[ns] = this;
15357      this.gsClass = null;
15358      this.func = func;
15359      var _classes = [];
15360      this.check = function (init) {
15361        var i = dependencies.length,
15362          missing = i,
15363          cur,
15364          a,
15365          n,
15366          cl;
15367        while (--i > -1) {
15368          if ((cur = _defLookup[dependencies[i]] || new _Definition(dependencies[i], [])).gsClass) {
15369            _classes[i] = cur.gsClass;
15370            missing--;
15371          } else if (init) {
15372            cur.sc.push(this);
15373          }
15374        }
15375        if (missing === 0 && func) {
15376          a = ("com.greensock." + ns).split(".");
15377          n = a.pop();
15378          cl = _namespace(a.join("."))[n] = this.gsClass = func.apply(func, _classes);
15379
15380          //exports to multiple environments
15381          if (global) {
15382            _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.)
15383            if (typeof module !== "undefined" && module.exports) {
15384              //node
15385              if (ns === moduleName) {
15386                module.exports = _exports[moduleName] = cl;
15387                for (i in _exports) {
15388                  cl[i] = _exports[i];
15389                }
15390              } else if (_exports[moduleName]) {
15391                _exports[moduleName][n] = cl;
15392              }
15393            } else if (typeof define === "function" && define.amd) {
15394              //AMD
15395              define((window.GreenSockAMDPath ? window.GreenSockAMDPath + "/" : "") + ns.split(".").pop(), [], function () {
15396                return cl;
15397              });
15398            }
15399          }
15400          for (i = 0; i < this.sc.length; i++) {
15401            this.sc[i].check();
15402          }
15403        }
15404      };
15405      this.check(true);
15406    },
15407    //used to create Definition instances (which basically registers a class that has dependencies).
15408    _gsDefine = window._gsDefine = function (ns, dependencies, func, global) {
15409      return new _Definition(ns, dependencies, func, global);
15410    },
15411    //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).
15412    _class = gs._class = function (ns, func, global) {
15413      func = func || function () {};
15414      _gsDefine(ns, [], function () {
15415        return func;
15416      }, global);
15417      return func;
15418    };
15419  _gsDefine.globals = _globals;
15420
15421  /*
15422   * ----------------------------------------------------------------
15423   * Ease
15424   * ----------------------------------------------------------------
15425   */
15426  var _baseParams = [0, 0, 1, 1],
15427    Ease = _class("easing.Ease", function (func, extraParams, type, power) {
15428      this._func = func;
15429      this._type = type || 0;
15430      this._power = power || 0;
15431      this._params = extraParams ? _baseParams.concat(extraParams) : _baseParams;
15432    }, true),
15433    _easeMap = Ease.map = {},
15434    _easeReg = Ease.register = function (ease, names, types, create) {
15435      var na = names.split(","),
15436        i = na.length,
15437        ta = (types || "easeIn,easeOut,easeInOut").split(","),
15438        e,
15439        name,
15440        j,
15441        type;
15442      while (--i > -1) {
15443        name = na[i];
15444        e = create ? _class("easing." + name, null, true) : gs.easing[name] || {};
15445        j = ta.length;
15446        while (--j > -1) {
15447          type = ta[j];
15448          _easeMap[name + "." + type] = _easeMap[type + name] = e[type] = ease.getRatio ? ease : ease[type] || new ease();
15449        }
15450      }
15451    };
15452  p = Ease.prototype;
15453  p._calcEnd = false;
15454  p.getRatio = function (p) {
15455    if (this._func) {
15456      this._params[0] = p;
15457      return this._func.apply(null, this._params);
15458    }
15459    var t = this._type,
15460      pw = this._power,
15461      r = t === 1 ? 1 - p : t === 2 ? p : p < 0.5 ? p * 2 : (1 - p) * 2;
15462    if (pw === 1) {
15463      r *= r;
15464    } else if (pw === 2) {
15465      r *= r * r;
15466    } else if (pw === 3) {
15467      r *= r * r * r;
15468    } else if (pw === 4) {
15469      r *= r * r * r * r;
15470    }
15471    return t === 1 ? 1 - r : t === 2 ? r : p < 0.5 ? r / 2 : 1 - r / 2;
15472  };
15473
15474  //create all the standard eases like Linear, Quad, Cubic, Quart, Quint, Strong, Power0, Power1, Power2, Power3, and Power4 (each with easeIn, easeOut, and easeInOut)
15475  a = ["Linear", "Quad", "Cubic", "Quart", "Quint,Strong"];
15476  i = a.length;
15477  while (--i > -1) {
15478    p = a[i] + ",Power" + i;
15479    _easeReg(new Ease(null, null, 1, i), p, "easeOut", true);
15480    _easeReg(new Ease(null, null, 2, i), p, "easeIn" + (i === 0 ? ",easeNone" : ""));
15481    _easeReg(new Ease(null, null, 3, i), p, "easeInOut");
15482  }
15483  _easeMap.linear = gs.easing.Linear.easeIn;
15484  _easeMap.swing = gs.easing.Quad.easeInOut; //for jQuery folks
15485
15486  /*
15487   * ----------------------------------------------------------------
15488   * EventDispatcher
15489   * ----------------------------------------------------------------
15490   */
15491  var EventDispatcher = _class("events.EventDispatcher", function (target) {
15492    this._listeners = {};
15493    this._eventTarget = target || this;
15494  });
15495  p = EventDispatcher.prototype;
15496  p.addEventListener = function (type, callback, scope, useParam, priority) {
15497    priority = priority || 0;
15498    var list = this._listeners[type],
15499      index = 0,
15500      listener,
15501      i;
15502    if (this === _ticker && !_tickerActive) {
15503      _ticker.wake();
15504    }
15505    if (list == null) {
15506      this._listeners[type] = list = [];
15507    }
15508    i = list.length;
15509    while (--i > -1) {
15510      listener = list[i];
15511      if (listener.c === callback && listener.s === scope) {
15512        list.splice(i, 1);
15513      } else if (index === 0 && listener.pr < priority) {
15514        index = i + 1;
15515      }
15516    }
15517    list.splice(index, 0, {
15518      c: callback,
15519      s: scope,
15520      up: useParam,
15521      pr: priority
15522    });
15523  };
15524  p.removeEventListener = function (type, callback) {
15525    var list = this._listeners[type],
15526      i;
15527    if (list) {
15528      i = list.length;
15529      while (--i > -1) {
15530        if (list[i].c === callback) {
15531          list.splice(i, 1);
15532          return;
15533        }
15534      }
15535    }
15536  };
15537  p.dispatchEvent = function (type) {
15538    var list = this._listeners[type],
15539      i,
15540      t,
15541      listener;
15542    if (list) {
15543      i = list.length;
15544      if (i > 1) {
15545        list = list.slice(0); //in case addEventListener() is called from within a listener/callback (otherwise the index could change, resulting in a skip)
15546      }
15547      t = this._eventTarget;
15548      while (--i > -1) {
15549        listener = list[i];
15550        if (listener) {
15551          if (listener.up) {
15552            listener.c.call(listener.s || t, {
15553              type: type,
15554              target: t
15555            });
15556          } else {
15557            listener.c.call(listener.s || t);
15558          }
15559        }
15560      }
15561    }
15562  };
15563
15564  /*
15565   * ----------------------------------------------------------------
15566   * Ticker
15567   * ----------------------------------------------------------------
15568   */
15569  var _reqAnimFrame = window.requestAnimationFrame,
15570    _cancelAnimFrame = window.cancelAnimationFrame,
15571    _getTime = Date.now || function () {
15572      return new Date().getTime();
15573    },
15574    _lastUpdate = _getTime();
15575
15576  //now try to determine the requestAnimationFrame and cancelAnimationFrame functions and if none are found, we'll use a setTimeout()/clearTimeout() polyfill.
15577  a = ["ms", "moz", "webkit", "o"];
15578  i = a.length;
15579  while (--i > -1 && !_reqAnimFrame) {
15580    _reqAnimFrame = window[a[i] + "RequestAnimationFrame"];
15581    _cancelAnimFrame = window[a[i] + "CancelAnimationFrame"] || window[a[i] + "CancelRequestAnimationFrame"];
15582  }
15583  _class("Ticker", function (fps, useRAF) {
15584    var _self = this,
15585      _startTime = _getTime(),
15586      _useRAF = useRAF !== false && _reqAnimFrame ? "auto" : false,
15587      _lagThreshold = 500,
15588      _adjustedLag = 33,
15589      _tickWord = "tick",
15590      //helps reduce gc burden
15591      _fps,
15592      _req,
15593      _id,
15594      _gap,
15595      _nextTime,
15596      _tick2 = function _tick(manual) {
15597        var elapsed = _getTime() - _lastUpdate,
15598          overlap,
15599          dispatch;
15600        if (elapsed > _lagThreshold) {
15601          _startTime += elapsed - _adjustedLag;
15602        }
15603        _lastUpdate += elapsed;
15604        _self.time = (_lastUpdate - _startTime) / 1000;
15605        overlap = _self.time - _nextTime;
15606        if (!_fps || overlap > 0 || manual === true) {
15607          _self.frame++;
15608          _nextTime += overlap + (overlap >= _gap ? 0.004 : _gap - overlap);
15609          dispatch = true;
15610        }
15611        if (manual !== true) {
15612          //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.
15613          _id = _req(_tick2);
15614        }
15615        if (dispatch) {
15616          _self.dispatchEvent(_tickWord);
15617        }
15618      };
15619    EventDispatcher.call(_self);
15620    _self.time = _self.frame = 0;
15621    _self.tick = function () {
15622      _tick2(true);
15623    };
15624    _self.lagSmoothing = function (threshold, adjustedLag) {
15625      if (!arguments.length) {
15626        //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.
15627        return _lagThreshold < 1 / _tinyNum;
15628      }
15629      _lagThreshold = threshold || 1 / _tinyNum; //zero should be interpreted as basically unlimited
15630      _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0);
15631    };
15632    _self.sleep = function () {
15633      if (_id == null) {
15634        return;
15635      }
15636      if (!_useRAF || !_cancelAnimFrame) {
15637        clearTimeout(_id);
15638      } else {
15639        _cancelAnimFrame(_id);
15640      }
15641      _req = _emptyFunc;
15642      _id = null;
15643      if (_self === _ticker) {
15644        _tickerActive = false;
15645      }
15646    };
15647    _self.wake = function (seamless) {
15648      if (_id !== null) {
15649        _self.sleep();
15650      } else if (seamless) {
15651        _startTime += -_lastUpdate + (_lastUpdate = _getTime());
15652      } else if (_self.frame > 10) {
15653        //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().
15654        _lastUpdate = _getTime() - _lagThreshold + 5;
15655      }
15656      _req = _fps === 0 ? _emptyFunc : !_useRAF || !_reqAnimFrame ? function (f) {
15657        return setTimeout(f, (_nextTime - _self.time) * 1000 + 1 | 0);
15658      } : _reqAnimFrame;
15659      if (_self === _ticker) {
15660        _tickerActive = true;
15661      }
15662      _tick2(2);
15663    };
15664    _self.fps = function (value) {
15665      if (!arguments.length) {
15666        return _fps;
15667      }
15668      _fps = value;
15669      _gap = 1 / (_fps || 60);
15670      _nextTime = this.time + _gap;
15671      _self.wake();
15672    };
15673    _self.useRAF = function (value) {
15674      if (!arguments.length) {
15675        return _useRAF;
15676      }
15677      _self.sleep();
15678      _useRAF = value;
15679      _self.fps(_fps);
15680    };
15681    _self.fps(fps);
15682
15683    //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.
15684    setTimeout(function () {
15685      if (_useRAF === "auto" && _self.frame < 5 && (_doc || {}).visibilityState !== "hidden") {
15686        _self.useRAF(false);
15687      }
15688    }, 1500);
15689  });
15690  p = gs.Ticker.prototype = new gs.events.EventDispatcher();
15691  p.constructor = gs.Ticker;
15692
15693  /*
15694   * ----------------------------------------------------------------
15695   * Animation
15696   * ----------------------------------------------------------------
15697   */
15698  var Animation = _class("core.Animation", function (duration, vars) {
15699    this.vars = vars = vars || {};
15700    this._duration = this._totalDuration = duration || 0;
15701    this._delay = Number(vars.delay) || 0;
15702    this._timeScale = 1;
15703    this._active = vars.immediateRender === true;
15704    this.data = vars.data;
15705    this._reversed = vars.reversed === true;
15706    if (!_rootTimeline) {
15707      return;
15708    }
15709    if (!_tickerActive) {
15710      //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.
15711      _ticker.wake();
15712    }
15713    var tl = this.vars.useFrames ? _rootFramesTimeline : _rootTimeline;
15714    tl.add(this, tl._time);
15715    if (this.vars.paused) {
15716      this.paused(true);
15717    }
15718  });
15719  _ticker = Animation.ticker = new gs.Ticker();
15720  p = Animation.prototype;
15721  p._dirty = p._gc = p._initted = p._paused = false;
15722  p._totalTime = p._time = 0;
15723  p._rawPrevTime = -1;
15724  p._next = p._last = p._onUpdate = p._timeline = p.timeline = null;
15725  p._paused = false;
15726
15727  //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.
15728  var _checkTimeout2 = function _checkTimeout() {
15729    if (_tickerActive && _getTime() - _lastUpdate > 2000 && ((_doc || {}).visibilityState !== "hidden" || !_ticker.lagSmoothing())) {
15730      //note: if the tab is hidden, we should still wake if lagSmoothing has been disabled.
15731      _ticker.wake();
15732    }
15733    var t = setTimeout(_checkTimeout2, 2000);
15734    if (t.unref) {
15735      // 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.
15736      t.unref();
15737    }
15738  };
15739  _checkTimeout2();
15740  p.play = function (from, suppressEvents) {
15741    if (from != null) {
15742      this.seek(from, suppressEvents);
15743    }
15744    return this.reversed(false).paused(false);
15745  };
15746  p.pause = function (atTime, suppressEvents) {
15747    if (atTime != null) {
15748      this.seek(atTime, suppressEvents);
15749    }
15750    return this.paused(true);
15751  };
15752  p.resume = function (from, suppressEvents) {
15753    if (from != null) {
15754      this.seek(from, suppressEvents);
15755    }
15756    return this.paused(false);
15757  };
15758  p.seek = function (time, suppressEvents) {
15759    return this.totalTime(Number(time), suppressEvents !== false);
15760  };
15761  p.restart = function (includeDelay, suppressEvents) {
15762    return this.reversed(false).paused(false).totalTime(includeDelay ? -this._delay : 0, suppressEvents !== false, true);
15763  };
15764  p.reverse = function (from, suppressEvents) {
15765    if (from != null) {
15766      this.seek(from || this.totalDuration(), suppressEvents);
15767    }
15768    return this.reversed(true).paused(false);
15769  };
15770  p.render = function (time, suppressEvents, force) {
15771    //stub - we override this method in subclasses.
15772  };
15773  p.invalidate = function () {
15774    this._time = this._totalTime = 0;
15775    this._initted = this._gc = false;
15776    this._rawPrevTime = -1;
15777    if (this._gc || !this.timeline) {
15778      this._enabled(true);
15779    }
15780    return this;
15781  };
15782  p.isActive = function () {
15783    var tl = this._timeline,
15784      //the 2 root timelines won't have a _timeline; they're always active.
15785      startTime = this._startTime,
15786      rawTime;
15787    return !tl || !this._gc && !this._paused && tl.isActive() && (rawTime = tl.rawTime(true)) >= startTime && rawTime < startTime + this.totalDuration() / this._timeScale - 0.0000001;
15788  };
15789  p._enabled = function (enabled, ignoreTimeline) {
15790    if (!_tickerActive) {
15791      _ticker.wake();
15792    }
15793    this._gc = !enabled;
15794    this._active = this.isActive();
15795    if (ignoreTimeline !== true) {
15796      if (enabled && !this.timeline) {
15797        this._timeline.add(this, this._startTime - this._delay);
15798      } else if (!enabled && this.timeline) {
15799        this._timeline._remove(this, true);
15800      }
15801    }
15802    return false;
15803  };
15804  p._kill = function (vars, target) {
15805    return this._enabled(false, false);
15806  };
15807  p.kill = function (vars, target) {
15808    this._kill(vars, target);
15809    return this;
15810  };
15811  p._uncache = function (includeSelf) {
15812    var tween = includeSelf ? this : this.timeline;
15813    while (tween) {
15814      tween._dirty = true;
15815      tween = tween.timeline;
15816    }
15817    return this;
15818  };
15819  p._swapSelfInParams = function (params) {
15820    var i = params.length,
15821      copy = params.concat();
15822    while (--i > -1) {
15823      if (params[i] === "{self}") {
15824        copy[i] = this;
15825      }
15826    }
15827    return copy;
15828  };
15829  p._callback = function (type) {
15830    var v = this.vars,
15831      callback = v[type],
15832      params = v[type + "Params"],
15833      scope = v[type + "Scope"] || v.callbackScope || this,
15834      l = params ? params.length : 0;
15835    switch (l) {
15836      //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);
15837      case 0:
15838        callback.call(scope);
15839        break;
15840      case 1:
15841        callback.call(scope, params[0]);
15842        break;
15843      case 2:
15844        callback.call(scope, params[0], params[1]);
15845        break;
15846      default:
15847        callback.apply(scope, params);
15848    }
15849  };
15850
15851  //----Animation getters/setters --------------------------------------------------------
15852
15853  p.eventCallback = function (type, callback, params, scope) {
15854    if ((type || "").substr(0, 2) === "on") {
15855      var v = this.vars;
15856      if (arguments.length === 1) {
15857        return v[type];
15858      }
15859      if (callback == null) {
15860        delete v[type];
15861      } else {
15862        v[type] = callback;
15863        v[type + "Params"] = _isArray(params) && params.join("").indexOf("{self}") !== -1 ? this._swapSelfInParams(params) : params;
15864        v[type + "Scope"] = scope;
15865      }
15866      if (type === "onUpdate") {
15867        this._onUpdate = callback;
15868      }
15869    }
15870    return this;
15871  };
15872  p.delay = function (value) {
15873    if (!arguments.length) {
15874      return this._delay;
15875    }
15876    if (this._timeline.smoothChildTiming) {
15877      this.startTime(this._startTime + value - this._delay);
15878    }
15879    this._delay = value;
15880    return this;
15881  };
15882  p.duration = function (value) {
15883    if (!arguments.length) {
15884      this._dirty = false;
15885      return this._duration;
15886    }
15887    this._duration = this._totalDuration = value;
15888    this._uncache(true); //true in case it's a TweenMax or TimelineMax that has a repeat - we'll need to refresh the totalDuration.
15889    if (this._timeline.smoothChildTiming) if (this._time > 0) if (this._time < this._duration) if (value !== 0) {
15890      this.totalTime(this._totalTime * (value / this._duration), true);
15891    }
15892    return this;
15893  };
15894  p.totalDuration = function (value) {
15895    this._dirty = false;
15896    return !arguments.length ? this._totalDuration : this.duration(value);
15897  };
15898  p.time = function (value, suppressEvents) {
15899    if (!arguments.length) {
15900      return this._time;
15901    }
15902    if (this._dirty) {
15903      this.totalDuration();
15904    }
15905    return this.totalTime(value > this._duration ? this._duration : value, suppressEvents);
15906  };
15907  p.totalTime = function (time, suppressEvents, uncapped) {
15908    if (!_tickerActive) {
15909      _ticker.wake();
15910    }
15911    if (!arguments.length) {
15912      return this._totalTime;
15913    }
15914    if (this._timeline) {
15915      if (time < 0 && !uncapped) {
15916        time += this.totalDuration();
15917      }
15918      if (this._timeline.smoothChildTiming) {
15919        if (this._dirty) {
15920          this.totalDuration();
15921        }
15922        var totalDuration = this._totalDuration,
15923          tl = this._timeline;
15924        if (time > totalDuration && !uncapped) {
15925          time = totalDuration;
15926        }
15927        this._startTime = (this._paused ? this._pauseTime : tl._time) - (!this._reversed ? time : totalDuration - time) / this._timeScale;
15928        if (!tl._dirty) {
15929          //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.
15930          this._uncache(false);
15931        }
15932        //in case any of the ancestor timelines had completed but should now be enabled, we should reset their 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.
15933        if (tl._timeline) {
15934          while (tl._timeline) {
15935            if (tl._timeline._time !== (tl._startTime + tl._totalTime) / tl._timeScale) {
15936              tl.totalTime(tl._totalTime, true);
15937            }
15938            tl = tl._timeline;
15939          }
15940        }
15941      }
15942      if (this._gc) {
15943        this._enabled(true, false);
15944      }
15945      if (this._totalTime !== time || this._duration === 0) {
15946        if (_lazyTweens.length) {
15947          _lazyRender();
15948        }
15949        this.render(time, suppressEvents, false);
15950        if (_lazyTweens.length) {
15951          //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.
15952          _lazyRender();
15953        }
15954      }
15955    }
15956    return this;
15957  };
15958  p.progress = p.totalProgress = function (value, suppressEvents) {
15959    var duration = this.duration();
15960    return !arguments.length ? duration ? this._time / duration : this.ratio : this.totalTime(duration * value, suppressEvents);
15961  };
15962  p.startTime = function (value) {
15963    if (!arguments.length) {
15964      return this._startTime;
15965    }
15966    if (value !== this._startTime) {
15967      this._startTime = value;
15968      if (this.timeline) if (this.timeline._sortChildren) {
15969        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.
15970      }
15971    }
15972    return this;
15973  };
15974  p.endTime = function (includeRepeats) {
15975    return this._startTime + (includeRepeats != false ? this.totalDuration() : this.duration()) / this._timeScale;
15976  };
15977  p.timeScale = function (value) {
15978    if (!arguments.length) {
15979      return this._timeScale;
15980    }
15981    var pauseTime, t;
15982    value = value || _tinyNum; //can't allow zero because it'll throw the math off
15983    if (this._timeline && this._timeline.smoothChildTiming) {
15984      pauseTime = this._pauseTime;
15985      t = pauseTime || pauseTime === 0 ? pauseTime : this._timeline.totalTime();
15986      this._startTime = t - (t - this._startTime) * this._timeScale / value;
15987    }
15988    this._timeScale = value;
15989    t = this.timeline;
15990    while (t && t.timeline) {
15991      //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.
15992      t._dirty = true;
15993      t.totalDuration();
15994      t = t.timeline;
15995    }
15996    return this;
15997  };
15998  p.reversed = function (value) {
15999    if (!arguments.length) {
16000      return this._reversed;
16001    }
16002    if (value != this._reversed) {
16003      this._reversed = value;
16004      this.totalTime(this._timeline && !this._timeline.smoothChildTiming ? this.totalDuration() - this._totalTime : this._totalTime, true);
16005    }
16006    return this;
16007  };
16008  p.paused = function (value) {
16009    if (!arguments.length) {
16010      return this._paused;
16011    }
16012    var tl = this._timeline,
16013      raw,
16014      elapsed;
16015    if (value != this._paused) if (tl) {
16016      if (!_tickerActive && !value) {
16017        _ticker.wake();
16018      }
16019      raw = tl.rawTime();
16020      elapsed = raw - this._pauseTime;
16021      if (!value && tl.smoothChildTiming) {
16022        this._startTime += elapsed;
16023        this._uncache(false);
16024      }
16025      this._pauseTime = value ? raw : null;
16026      this._paused = value;
16027      this._active = this.isActive();
16028      if (!value && elapsed !== 0 && this._initted && this.duration()) {
16029        raw = tl.smoothChildTiming ? this._totalTime : (raw - this._startTime) / this._timeScale;
16030        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.
16031      }
16032    }
16033    if (this._gc && !value) {
16034      this._enabled(true, false);
16035    }
16036    return this;
16037  };
16038
16039  /*
16040   * ----------------------------------------------------------------
16041   * SimpleTimeline
16042   * ----------------------------------------------------------------
16043   */
16044  var SimpleTimeline = _class("core.SimpleTimeline", function (vars) {
16045    Animation.call(this, 0, vars);
16046    this.autoRemoveChildren = this.smoothChildTiming = true;
16047  });
16048  p = SimpleTimeline.prototype = new Animation();
16049  p.constructor = SimpleTimeline;
16050  p.kill()._gc = false;
16051  p._first = p._last = p._recent = null;
16052  p._sortChildren = false;
16053  p.add = p.insert = function (child, position, align, stagger) {
16054    var prevTween, st;
16055    child._startTime = Number(position || 0) + child._delay;
16056    if (child._paused) if (this !== child._timeline) {
16057      //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).
16058      child._pauseTime = child._startTime + (this.rawTime() - child._startTime) / child._timeScale;
16059    }
16060    if (child.timeline) {
16061      child.timeline._remove(child, true); //removes from existing timeline so that it can be properly added to this one.
16062    }
16063    child.timeline = child._timeline = this;
16064    if (child._gc) {
16065      child._enabled(true, true);
16066    }
16067    prevTween = this._last;
16068    if (this._sortChildren) {
16069      st = child._startTime;
16070      while (prevTween && prevTween._startTime > st) {
16071        prevTween = prevTween._prev;
16072      }
16073    }
16074    if (prevTween) {
16075      child._next = prevTween._next;
16076      prevTween._next = child;
16077    } else {
16078      child._next = this._first;
16079      this._first = child;
16080    }
16081    if (child._next) {
16082      child._next._prev = child;
16083    } else {
16084      this._last = child;
16085    }
16086    child._prev = prevTween;
16087    this._recent = child;
16088    if (this._timeline) {
16089      this._uncache(true);
16090    }
16091    return this;
16092  };
16093  p._remove = function (tween, skipDisable) {
16094    if (tween.timeline === this) {
16095      if (!skipDisable) {
16096        tween._enabled(false, true);
16097      }
16098      if (tween._prev) {
16099        tween._prev._next = tween._next;
16100      } else if (this._first === tween) {
16101        this._first = tween._next;
16102      }
16103      if (tween._next) {
16104        tween._next._prev = tween._prev;
16105      } else if (this._last === tween) {
16106        this._last = tween._prev;
16107      }
16108      tween._next = tween._prev = tween.timeline = null;
16109      if (tween === this._recent) {
16110        this._recent = this._last;
16111      }
16112      if (this._timeline) {
16113        this._uncache(true);
16114      }
16115    }
16116    return this;
16117  };
16118  p.render = function (time, suppressEvents, force) {
16119    var tween = this._first,
16120      next;
16121    this._totalTime = this._time = this._rawPrevTime = time;
16122    while (tween) {
16123      next = tween._next; //record it here because the value could change after rendering...
16124      if (tween._active || time >= tween._startTime && !tween._paused && !tween._gc) {
16125        if (!tween._reversed) {
16126          tween.render((time - tween._startTime) * tween._timeScale, suppressEvents, force);
16127        } else {
16128          tween.render((!tween._dirty ? tween._totalDuration : tween.totalDuration()) - (time - tween._startTime) * tween._timeScale, suppressEvents, force);
16129        }
16130      }
16131      tween = next;
16132    }
16133  };
16134  p.rawTime = function () {
16135    if (!_tickerActive) {
16136      _ticker.wake();
16137    }
16138    return this._totalTime;
16139  };
16140
16141  /*
16142   * ----------------------------------------------------------------
16143   * TweenLite
16144   * ----------------------------------------------------------------
16145   */
16146  var TweenLite = _class("TweenLite", function (target, duration, vars) {
16147      Animation.call(this, duration, vars);
16148      this.render = TweenLite.prototype.render; //speed optimization (avoid prototype lookup on this "hot" method)
16149
16150      if (target == null) {
16151        throw "Cannot tween a null target.";
16152      }
16153      this.target = target = typeof target !== "string" ? target : TweenLite.selector(target) || target;
16154      var isSelector = target.jquery || target.length && target !== window && target[0] && (target[0] === window || target[0].nodeType && target[0].style && !target.nodeType),
16155        overwrite = this.vars.overwrite,
16156        i,
16157        targ,
16158        targets;
16159      this._overwrite = overwrite = overwrite == null ? _overwriteLookup[TweenLite.defaultOverwrite] : typeof overwrite === "number" ? overwrite >> 0 : _overwriteLookup[overwrite];
16160      if ((isSelector || target instanceof Array || target.push && _isArray(target)) && typeof target[0] !== "number") {
16161        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()
16162        this._propLookup = [];
16163        this._siblings = [];
16164        for (i = 0; i < targets.length; i++) {
16165          targ = targets[i];
16166          if (!targ) {
16167            targets.splice(i--, 1);
16168            continue;
16169          } else if (typeof targ === "string") {
16170            targ = targets[i--] = TweenLite.selector(targ); //in case it's an array of strings
16171            if (typeof targ === "string") {
16172              targets.splice(i + 1, 1); //to avoid an endless loop (can't imagine why the selector would return a string, but just in case)
16173            }
16174            continue;
16175          } else if (targ.length && targ !== window && targ[0] && (targ[0] === window || targ[0].nodeType && targ[0].style && !targ.nodeType)) {
16176            //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.
16177            targets.splice(i--, 1);
16178            this._targets = targets = targets.concat(_slice(targ));
16179            continue;
16180          }
16181          this._siblings[i] = _register(targ, this, false);
16182          if (overwrite === 1) if (this._siblings[i].length > 1) {
16183            _applyOverwrite(targ, this, null, 1, this._siblings[i]);
16184          }
16185        }
16186      } else {
16187        this._propLookup = {};
16188        this._siblings = _register(target, this, false);
16189        if (overwrite === 1) if (this._siblings.length > 1) {
16190          _applyOverwrite(target, this, null, 1, this._siblings);
16191        }
16192      }
16193      if (this.vars.immediateRender || duration === 0 && this._delay === 0 && this.vars.immediateRender !== false) {
16194        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)
16195        this.render(Math.min(0, -this._delay)); //in case delay is negative
16196      }
16197    }, true),
16198    _isSelector = function _isSelector(v) {
16199      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.
16200    },
16201    _autoCSS = function _autoCSS(vars, target) {
16202      var css = {},
16203        p;
16204      for (p in vars) {
16205        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)) {
16206          //note: <img> elements contain read-only "x" and "y" properties. We should also prioritize editing css width/height rather than the element's properties.
16207          css[p] = vars[p];
16208          delete vars[p];
16209        }
16210      }
16211      vars.css = css;
16212    };
16213  p = TweenLite.prototype = new Animation();
16214  p.constructor = TweenLite;
16215  p.kill()._gc = false;
16216
16217  //----TweenLite defaults, overwrite management, and root updates ----------------------------------------------------
16218
16219  p.ratio = 0;
16220  p._firstPT = p._targets = p._overwrittenProps = p._startAt = null;
16221  p._notifyPluginsOfEnabled = p._lazy = false;
16222  TweenLite.version = "1.20.4";
16223  TweenLite.defaultEase = p._ease = new Ease(null, null, 1, 1);
16224  TweenLite.defaultOverwrite = "auto";
16225  TweenLite.ticker = _ticker;
16226  TweenLite.autoSleep = 120;
16227  TweenLite.lagSmoothing = function (threshold, adjustedLag) {
16228    _ticker.lagSmoothing(threshold, adjustedLag);
16229  };
16230  TweenLite.selector = window.$ || window.jQuery || function (e) {
16231    var selector = window.$ || window.jQuery;
16232    if (selector) {
16233      TweenLite.selector = selector;
16234      return selector(e);
16235    }
16236    return typeof _doc === "undefined" ? e : _doc.querySelectorAll ? _doc.querySelectorAll(e) : _doc.getElementById(e.charAt(0) === "#" ? e.substr(1) : e);
16237  };
16238  var _lazyTweens = [],
16239    _lazyLookup = {},
16240    _numbersExp = /(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
16241    _relExp = /[\+-]=-?[\.\d]/,
16242    //_nonNumbersExp = /(?:([\-+](?!(\d|=)))|[^\d\-+=e]|(e(?![\-+][\d])))+/ig,
16243    _setRatio = function _setRatio(v) {
16244      var pt = this._firstPT,
16245        min = 0.000001,
16246        val;
16247      while (pt) {
16248        val = !pt.blob ? pt.c * v + pt.s : v === 1 && this.end != null ? this.end : v ? this.join("") : this.start;
16249        if (pt.m) {
16250          val = pt.m(val, this._target || pt.t);
16251        } else if (val < min) if (val > -min && !pt.blob) {
16252          //prevents issues with converting very small numbers to strings in the browser
16253          val = 0;
16254        }
16255        if (!pt.f) {
16256          pt.t[pt.p] = val;
16257        } else if (pt.fp) {
16258          pt.t[pt.p](pt.fp, val);
16259        } else {
16260          pt.t[pt.p](val);
16261        }
16262        pt = pt._next;
16263      }
16264    },
16265    //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("")).
16266    _blobDif = function _blobDif(start, end, filter, pt) {
16267      var a = [],
16268        charIndex = 0,
16269        s = "",
16270        color = 0,
16271        startNums,
16272        endNums,
16273        num,
16274        i,
16275        l,
16276        nonNumbers,
16277        currentNum;
16278      a.start = start;
16279      a.end = end;
16280      start = a[0] = start + ""; //ensure values are strings
16281      end = a[1] = end + "";
16282      if (filter) {
16283        filter(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.
16284        start = a[0];
16285        end = a[1];
16286      }
16287      a.length = 0;
16288      startNums = start.match(_numbersExp) || [];
16289      endNums = end.match(_numbersExp) || [];
16290      if (pt) {
16291        pt._next = null;
16292        pt.blob = 1;
16293        a._firstPT = a._applyPT = pt; //apply last in the linked list (which means inserting it first)
16294      }
16295      l = endNums.length;
16296      for (i = 0; i < l; i++) {
16297        currentNum = endNums[i];
16298        nonNumbers = end.substr(charIndex, end.indexOf(currentNum, charIndex) - charIndex);
16299        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.
16300        charIndex += nonNumbers.length;
16301        if (color) {
16302          //sense rgba() values and round them.
16303          color = (color + 1) % 5;
16304        } else if (nonNumbers.substr(-5) === "rgba(") {
16305          color = 1;
16306        }
16307        if (currentNum === startNums[i] || startNums.length <= i) {
16308          s += currentNum;
16309        } else {
16310          if (s) {
16311            a.push(s);
16312            s = "";
16313          }
16314          num = parseFloat(startNums[i]);
16315          a.push(num);
16316          a._firstPT = {
16317            _next: a._firstPT,
16318            t: a,
16319            p: a.length - 1,
16320            s: num,
16321            c: (currentNum.charAt(1) === "=" ? parseInt(currentNum.charAt(0) + "1", 10) * parseFloat(currentNum.substr(2)) : parseFloat(currentNum) - num) || 0,
16322            f: 0,
16323            m: color && color < 4 ? Math.round : 0
16324          };
16325          //note: we don't set _prev because we'll never need to remove individual PropTweens from this list.
16326        }
16327        charIndex += currentNum.length;
16328      }
16329      s += end.substr(charIndex);
16330      if (s) {
16331        a.push(s);
16332      }
16333      a.setRatio = _setRatio;
16334      if (_relExp.test(end)) {
16335        //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).
16336        a.end = null;
16337      }
16338      return a;
16339    },
16340    //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.
16341    _addPropTween = function _addPropTween(target, prop, start, end, overwriteProp, mod, funcParam, stringFilter, index) {
16342      if (typeof end === "function") {
16343        end = end(index || 0, target);
16344      }
16345      var type = _typeof(target[prop]),
16346        getterName = type !== "function" ? "" : prop.indexOf("set") || typeof target["get" + prop.substr(3)] !== "function" ? prop : "get" + prop.substr(3),
16347        s = start !== "get" ? start : !getterName ? target[prop] : funcParam ? target[getterName](funcParam) : target[getterName](),
16348        isRelative = typeof end === "string" && end.charAt(1) === "=",
16349        pt = {
16350          t: target,
16351          p: prop,
16352          s: s,
16353          f: type === "function",
16354          pg: 0,
16355          n: overwriteProp || prop,
16356          m: !mod ? 0 : typeof mod === "function" ? mod : Math.round,
16357          pr: 0,
16358          c: isRelative ? parseInt(end.charAt(0) + "1", 10) * parseFloat(end.substr(2)) : parseFloat(end) - s || 0
16359        },
16360        blob;
16361      if (typeof s !== "number" || typeof end !== "number" && !isRelative) {
16362        if (funcParam || isNaN(s) || !isRelative && isNaN(end) || typeof s === "boolean" || typeof end === "boolean") {
16363          //a blob (string that has multiple numbers in it)
16364          pt.fp = funcParam;
16365          blob = _blobDif(s, isRelative ? parseFloat(pt.s) + pt.c + (pt.s + "").replace(/[0-9\-\.]/g, "") : end, stringFilter || TweenLite.defaultStringFilter, pt);
16366          pt = {
16367            t: blob,
16368            p: "setRatio",
16369            s: 0,
16370            c: 1,
16371            f: 2,
16372            pg: 0,
16373            n: overwriteProp || prop,
16374            pr: 0,
16375            m: 0
16376          }; //"2" indicates it's a Blob property tween. Needed for RoundPropsPlugin for example.
16377        } else {
16378          pt.s = parseFloat(s);
16379          if (!isRelative) {
16380            pt.c = parseFloat(end) - pt.s || 0;
16381          }
16382        }
16383      }
16384      if (pt.c) {
16385        //only add it to the linked list if there's a change.
16386        if (pt._next = this._firstPT) {
16387          pt._next._prev = pt;
16388        }
16389        this._firstPT = pt;
16390        return pt;
16391      }
16392    },
16393    _internals = TweenLite._internals = {
16394      isArray: _isArray,
16395      isSelector: _isSelector,
16396      lazyTweens: _lazyTweens,
16397      blobDif: _blobDif
16398    },
16399    //gives us a way to expose certain private values to other GreenSock classes without contaminating tha main TweenLite object.
16400    _plugins = TweenLite._plugins = {},
16401    _tweenLookup = _internals.tweenLookup = {},
16402    _tweenLookupNum = 0,
16403    _reservedProps = _internals.reservedProps = {
16404      ease: 1,
16405      delay: 1,
16406      overwrite: 1,
16407      onComplete: 1,
16408      onCompleteParams: 1,
16409      onCompleteScope: 1,
16410      useFrames: 1,
16411      runBackwards: 1,
16412      startAt: 1,
16413      onUpdate: 1,
16414      onUpdateParams: 1,
16415      onUpdateScope: 1,
16416      onStart: 1,
16417      onStartParams: 1,
16418      onStartScope: 1,
16419      onReverseComplete: 1,
16420      onReverseCompleteParams: 1,
16421      onReverseCompleteScope: 1,
16422      onRepeat: 1,
16423      onRepeatParams: 1,
16424      onRepeatScope: 1,
16425      easeParams: 1,
16426      yoyo: 1,
16427      immediateRender: 1,
16428      repeat: 1,
16429      repeatDelay: 1,
16430      data: 1,
16431      paused: 1,
16432      reversed: 1,
16433      autoCSS: 1,
16434      lazy: 1,
16435      onOverwrite: 1,
16436      callbackScope: 1,
16437      stringFilter: 1,
16438      id: 1,
16439      yoyoEase: 1
16440    },
16441    _overwriteLookup = {
16442      none: 0,
16443      all: 1,
16444      auto: 2,
16445      concurrent: 3,
16446      allOnStart: 4,
16447      preexisting: 5,
16448      "true": 1,
16449      "false": 0
16450    },
16451    _rootFramesTimeline = Animation._rootFramesTimeline = new SimpleTimeline(),
16452    _rootTimeline = Animation._rootTimeline = new SimpleTimeline(),
16453    _nextGCFrame = 30,
16454    _lazyRender = _internals.lazyRender = function () {
16455      var i = _lazyTweens.length,
16456        tween;
16457      _lazyLookup = {};
16458      while (--i > -1) {
16459        tween = _lazyTweens[i];
16460        if (tween && tween._lazy !== false) {
16461          tween.render(tween._lazy[0], tween._lazy[1], true);
16462          tween._lazy = false;
16463        }
16464      }
16465      _lazyTweens.length = 0;
16466    };
16467  _rootTimeline._startTime = _ticker.time;
16468  _rootFramesTimeline._startTime = _ticker.frame;
16469  _rootTimeline._active = _rootFramesTimeline._active = true;
16470  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".
16471
16472  Animation._updateRoot = TweenLite.render = function () {
16473    var i, a, p;
16474    if (_lazyTweens.length) {
16475      //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.
16476      _lazyRender();
16477    }
16478    _rootTimeline.render((_ticker.time - _rootTimeline._startTime) * _rootTimeline._timeScale, false, false);
16479    _rootFramesTimeline.render((_ticker.frame - _rootFramesTimeline._startTime) * _rootFramesTimeline._timeScale, false, false);
16480    if (_lazyTweens.length) {
16481      _lazyRender();
16482    }
16483    if (_ticker.frame >= _nextGCFrame) {
16484      //dump garbage every 120 frames or whatever the user sets TweenLite.autoSleep to
16485      _nextGCFrame = _ticker.frame + (parseInt(TweenLite.autoSleep, 10) || 120);
16486      for (p in _tweenLookup) {
16487        a = _tweenLookup[p].tweens;
16488        i = a.length;
16489        while (--i > -1) {
16490          if (a[i]._gc) {
16491            a.splice(i, 1);
16492          }
16493        }
16494        if (a.length === 0) {
16495          delete _tweenLookup[p];
16496        }
16497      }
16498      //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
16499      p = _rootTimeline._first;
16500      if (!p || p._paused) if (TweenLite.autoSleep && !_rootFramesTimeline._first && _ticker._listeners.tick.length === 1) {
16501        while (p && p._paused) {
16502          p = p._next;
16503        }
16504        if (!p) {
16505          _ticker.sleep();
16506        }
16507      }
16508    }
16509  };
16510  _ticker.addEventListener("tick", Animation._updateRoot);
16511  var _register = function _register(target, tween, scrub) {
16512      var id = target._gsTweenID,
16513        a,
16514        i;
16515      if (!_tweenLookup[id || (target._gsTweenID = id = "t" + _tweenLookupNum++)]) {
16516        _tweenLookup[id] = {
16517          target: target,
16518          tweens: []
16519        };
16520      }
16521      if (tween) {
16522        a = _tweenLookup[id].tweens;
16523        a[i = a.length] = tween;
16524        if (scrub) {
16525          while (--i > -1) {
16526            if (a[i] === tween) {
16527              a.splice(i, 1);
16528            }
16529          }
16530        }
16531      }
16532      return _tweenLookup[id].tweens;
16533    },
16534    _onOverwrite = function _onOverwrite(overwrittenTween, overwritingTween, target, killedProps) {
16535      var func = overwrittenTween.vars.onOverwrite,
16536        r1,
16537        r2;
16538      if (func) {
16539        r1 = func(overwrittenTween, overwritingTween, target, killedProps);
16540      }
16541      func = TweenLite.onOverwrite;
16542      if (func) {
16543        r2 = func(overwrittenTween, overwritingTween, target, killedProps);
16544      }
16545      return r1 !== false && r2 !== false;
16546    },
16547    _applyOverwrite = function _applyOverwrite(target, tween, props, mode, siblings) {
16548      var i, changed, curTween, l;
16549      if (mode === 1 || mode >= 4) {
16550        l = siblings.length;
16551        for (i = 0; i < l; i++) {
16552          if ((curTween = siblings[i]) !== tween) {
16553            if (!curTween._gc) {
16554              if (curTween._kill(null, target, tween)) {
16555                changed = true;
16556              }
16557            }
16558          } else if (mode === 5) {
16559            break;
16560          }
16561        }
16562        return changed;
16563      }
16564      //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)
16565      var startTime = tween._startTime + _tinyNum,
16566        overlaps = [],
16567        oCount = 0,
16568        zeroDur = tween._duration === 0,
16569        globalStart;
16570      i = siblings.length;
16571      while (--i > -1) {
16572        if ((curTween = siblings[i]) === tween || curTween._gc || curTween._paused) {
16573          //ignore
16574        } else if (curTween._timeline !== tween._timeline) {
16575          globalStart = globalStart || _checkOverlap(tween, 0, zeroDur);
16576          if (_checkOverlap(curTween, globalStart, zeroDur) === 0) {
16577            overlaps[oCount++] = curTween;
16578          }
16579        } else if (curTween._startTime <= startTime) if (curTween._startTime + curTween.totalDuration() / curTween._timeScale > startTime) if (!((zeroDur || !curTween._initted) && startTime - curTween._startTime <= 0.0000000002)) {
16580          overlaps[oCount++] = curTween;
16581        }
16582      }
16583      i = oCount;
16584      while (--i > -1) {
16585        curTween = overlaps[i];
16586        if (mode === 2) if (curTween._kill(props, target, tween)) {
16587          changed = true;
16588        }
16589        if (mode !== 2 || !curTween._firstPT && curTween._initted) {
16590          if (mode !== 2 && !_onOverwrite(curTween, tween)) {
16591            continue;
16592          }
16593          if (curTween._enabled(false, false)) {
16594            //if all property tweens have been overwritten, kill the tween.
16595            changed = true;
16596          }
16597        }
16598      }
16599      return changed;
16600    },
16601    _checkOverlap = function _checkOverlap(tween, reference, zeroDur) {
16602      var tl = tween._timeline,
16603        ts = tl._timeScale,
16604        t = tween._startTime;
16605      while (tl._timeline) {
16606        t += tl._startTime;
16607        ts *= tl._timeScale;
16608        if (tl._paused) {
16609          return -100;
16610        }
16611        tl = tl._timeline;
16612      }
16613      t /= ts;
16614      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;
16615    };
16616
16617  //---- TweenLite instance methods -----------------------------------------------------------------------------
16618
16619  p._init = function () {
16620    var v = this.vars,
16621      op = this._overwrittenProps,
16622      dur = this._duration,
16623      immediate = !!v.immediateRender,
16624      ease = v.ease,
16625      i,
16626      initPlugins,
16627      pt,
16628      p,
16629      startVars,
16630      l;
16631    if (v.startAt) {
16632      if (this._startAt) {
16633        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.
16634        this._startAt.kill();
16635      }
16636      startVars = {};
16637      for (p in v.startAt) {
16638        //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);
16639        startVars[p] = v.startAt[p];
16640      }
16641      startVars.data = "isStart";
16642      startVars.overwrite = false;
16643      startVars.immediateRender = true;
16644      startVars.lazy = immediate && v.lazy !== false;
16645      startVars.startAt = startVars.delay = null; //no nesting of startAt objects allowed (otherwise it could cause an infinite loop).
16646      startVars.onUpdate = v.onUpdate;
16647      startVars.onUpdateParams = v.onUpdateParams;
16648      startVars.onUpdateScope = v.onUpdateScope || v.callbackScope || this;
16649      this._startAt = TweenLite.to(this.target, 0, startVars);
16650      if (immediate) {
16651        if (this._time > 0) {
16652          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()).
16653        } else if (dur !== 0) {
16654          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.
16655        }
16656      }
16657    } else if (v.runBackwards && dur !== 0) {
16658      //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)
16659      if (this._startAt) {
16660        this._startAt.render(-1, true);
16661        this._startAt.kill();
16662        this._startAt = null;
16663      } else {
16664        if (this._time !== 0) {
16665          //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
16666          immediate = false;
16667        }
16668        pt = {};
16669        for (p in v) {
16670          //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.
16671          if (!_reservedProps[p] || p === "autoCSS") {
16672            pt[p] = v[p];
16673          }
16674        }
16675        pt.overwrite = 0;
16676        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.
16677        pt.lazy = immediate && v.lazy !== false;
16678        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)
16679        this._startAt = TweenLite.to(this.target, 0, pt);
16680        if (!immediate) {
16681          this._startAt._init(); //ensures that the initial values are recorded
16682          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.
16683          if (this.vars.immediateRender) {
16684            this._startAt = null;
16685          }
16686        } else if (this._time === 0) {
16687          return;
16688        }
16689      }
16690    }
16691    this._ease = ease = !ease ? TweenLite.defaultEase : ease instanceof Ease ? ease : typeof ease === "function" ? new Ease(ease, v.easeParams) : _easeMap[ease] || TweenLite.defaultEase;
16692    if (v.easeParams instanceof Array && ease.config) {
16693      this._ease = ease.config.apply(ease, v.easeParams);
16694    }
16695    this._easeType = this._ease._type;
16696    this._easePower = this._ease._power;
16697    this._firstPT = null;
16698    if (this._targets) {
16699      l = this._targets.length;
16700      for (i = 0; i < l; i++) {
16701        if (this._initProps(this._targets[i], this._propLookup[i] = {}, this._siblings[i], op ? op[i] : null, i)) {
16702          initPlugins = true;
16703        }
16704      }
16705    } else {
16706      initPlugins = this._initProps(this.target, this._propLookup, this._siblings, op, 0);
16707    }
16708    if (initPlugins) {
16709      TweenLite._onPluginEvent("_onInitAllProps", this); //reorders the array in order of priority. Uses a static TweenPlugin method in order to minimize file size in TweenLite
16710    }
16711    if (op) if (!this._firstPT) if (typeof this.target !== "function") {
16712      //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.
16713      this._enabled(false, false);
16714    }
16715    if (v.runBackwards) {
16716      pt = this._firstPT;
16717      while (pt) {
16718        pt.s += pt.c;
16719        pt.c = -pt.c;
16720        pt = pt._next;
16721      }
16722    }
16723    this._onUpdate = v.onUpdate;
16724    this._initted = true;
16725  };
16726  p._initProps = function (target, propLookup, siblings, overwrittenProps, index) {
16727    var p, i, initPlugins, plugin, pt, v;
16728    if (target == null) {
16729      return false;
16730    }
16731    if (_lazyLookup[target._gsTweenID]) {
16732      _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)
16733    }
16734    if (!this.vars.css) if (target.style) if (target !== window && target.nodeType) if (_plugins.css) if (this.vars.autoCSS !== false) {
16735      //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.
16736      _autoCSS(this.vars, target);
16737    }
16738    for (p in this.vars) {
16739      v = this.vars[p];
16740      if (_reservedProps[p]) {
16741        if (v) if (v instanceof Array || v.push && _isArray(v)) if (v.join("").indexOf("{self}") !== -1) {
16742          this.vars[p] = v = this._swapSelfInParams(v, this);
16743        }
16744      } else if (_plugins[p] && (plugin = new _plugins[p]())._onInitTween(target, this.vars[p], this, index)) {
16745        //t - target 		[object]
16746        //p - property 		[string]
16747        //s - start			[number]
16748        //c - change		[number]
16749        //f - isFunction	[boolean]
16750        //n - name			[string]
16751        //pg - isPlugin 	[boolean]
16752        //pr - priority		[number]
16753        //m - mod           [function | 0]
16754        this._firstPT = pt = {
16755          _next: this._firstPT,
16756          t: plugin,
16757          p: "setRatio",
16758          s: 0,
16759          c: 1,
16760          f: 1,
16761          n: p,
16762          pg: 1,
16763          pr: plugin._priority,
16764          m: 0
16765        };
16766        i = plugin._overwriteProps.length;
16767        while (--i > -1) {
16768          propLookup[plugin._overwriteProps[i]] = this._firstPT;
16769        }
16770        if (plugin._priority || plugin._onInitAllProps) {
16771          initPlugins = true;
16772        }
16773        if (plugin._onDisable || plugin._onEnable) {
16774          this._notifyPluginsOfEnabled = true;
16775        }
16776        if (pt._next) {
16777          pt._next._prev = pt;
16778        }
16779      } else {
16780        propLookup[p] = _addPropTween.call(this, target, p, "get", v, p, 0, null, this.vars.stringFilter, index);
16781      }
16782    }
16783    if (overwrittenProps) if (this._kill(overwrittenProps, target)) {
16784      //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)
16785      return this._initProps(target, propLookup, siblings, overwrittenProps, index);
16786    }
16787    if (this._overwrite > 1) if (this._firstPT) if (siblings.length > 1) if (_applyOverwrite(target, this, propLookup, this._overwrite, siblings)) {
16788      this._kill(propLookup, target);
16789      return this._initProps(target, propLookup, siblings, overwrittenProps, index);
16790    }
16791    if (this._firstPT) if (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration) {
16792      //zero duration tweens don't lazy render by default; everything else does.
16793      _lazyLookup[target._gsTweenID] = true;
16794    }
16795    return initPlugins;
16796  };
16797  p.render = function (time, suppressEvents, force) {
16798    var prevTime = this._time,
16799      duration = this._duration,
16800      prevRawPrevTime = this._rawPrevTime,
16801      isComplete,
16802      callback,
16803      pt,
16804      rawPrevTime;
16805    if (time >= duration - 0.0000001 && time >= 0) {
16806      //to work around occasional floating point math artifacts.
16807      this._totalTime = this._time = duration;
16808      this.ratio = this._ease._calcEnd ? this._ease.getRatio(1) : 1;
16809      if (!this._reversed) {
16810        isComplete = true;
16811        callback = "onComplete";
16812        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.
16813      }
16814      if (duration === 0) if (this._initted || !this.vars.lazy || force) {
16815        //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.
16816        if (this._startTime === this._timeline._duration) {
16817          //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
16817ding 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.
16818          time = 0;
16819        }
16820        if (prevRawPrevTime < 0 || time <= 0 && time >= -0.0000001 || prevRawPrevTime === _tinyNum && this.data !== "isPause") if (prevRawPrevTime !== time) {
16821          //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.
16822          force = true;
16823          if (prevRawPrevTime > _tinyNum) {
16824            callback = "onReverseComplete";
16825          }
16826        }
16827        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.
16828      }
16829    } else if (time < 0.0000001) {
16830      //to work around occasional floating point math artifacts, round super small values to 0.
16831      this._totalTime = this._time = 0;
16832      this.ratio = this._ease._calcEnd ? this._ease.getRatio(0) : 0;
16833      if (prevTime !== 0 || duration === 0 && prevRawPrevTime > 0) {
16834        callback = "onReverseComplete";
16835        isComplete = this._reversed;
16836      }
16837      if (time < 0) {
16838        this._active = false;
16839        if (duration === 0) if (this._initted || !this.vars.lazy || force) {
16840          //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.
16841          if (prevRawPrevTime >= 0 && !(prevRawPrevTime === _tinyNum && this.data === "isPause")) {
16842            force = true;
16843          }
16844          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.
16845        }
16846      }
16847      if (!this._initted || this._startAt && this._startAt.progress()) {
16848        //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.
16849        force = true;
16850      }
16851    } else {
16852      this._totalTime = this._time = time;
16853      if (this._easeType) {
16854        var r = time / duration,
16855          type = this._easeType,
16856          pow = this._easePower;
16857        if (type === 1 || type === 3 && r >= 0.5) {
16858          r = 1 - r;
16859        }
16860        if (type === 3) {
16861          r *= 2;
16862        }
16863        if (pow === 1) {
16864          r *= r;
16865        } else if (pow === 2) {
16866          r *= r * r;
16867        } else if (pow === 3) {
16868          r *= r * r * r;
16869        } else if (pow === 4) {
16870          r *= r * r * r * r;
16871        }
16872        if (type === 1) {
16873          this.ratio = 1 - r;
16874        } else if (type === 2) {
16875          this.ratio = r;
16876        } else if (time / duration < 0.5) {
16877          this.ratio = r / 2;
16878        } else {
16879          this.ratio = 1 - r / 2;
16880        }
16881      } else {
16882        this.ratio = this._ease.getRatio(time / duration);
16883      }
16884    }
16885    if (this._time === prevTime && !force) {
16886      return;
16887    } else if (!this._initted) {
16888      this._init();
16889      if (!this._initted || this._gc) {
16890        //immediateRender tweens typically won't initialize until the playhead advances (_time is greater than 0) in order to ensure that over
16890writing 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.
16891        return;
16892      } else if (!force && this._firstPT && (this.vars.lazy !== false && this._duration || this.vars.lazy && !this._duration)) {
16893        this._time = this._totalTime = prevTime;
16894        this._rawPrevTime = prevRawPrevTime;
16895        _lazyTweens.push(this);
16896        this._lazy = [time, suppressEvents];
16897        return;
16898      }
16899      //_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.
16900      if (this._time && !isComplete) {
16901        this.ratio = this._ease.getRatio(this._time / duration);
16902      } else if (isComplete && this._ease._calcEnd) {
16903        this.ratio = this._ease.getRatio(this._time === 0 ? 0 : 1);
16904      }
16905    }
16906    if (this._lazy !== false) {
16907      //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.
16908      this._lazy = false;
16909    }
16910    if (!this._active) if (!this._paused && this._time !== prevTime && time >= 0) {
16911      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.
16912    }
16913    if (prevTime === 0) {
16914      if (this._startAt) {
16915        if (time >= 0) {
16916          this._startAt.render(time, true, force);
16917        } else if (!callback) {
16918          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.
16919        }
16920      }
16921      if (this.vars.onStart) if (this._time !== 0 || duration === 0) if (!suppressEvents) {
16922        this._callback("onStart");
16923      }
16924    }
16925    pt = this._firstPT;
16926    while (pt) {
16927      if (pt.f) {
16928        pt.t[pt.p](pt.c * this.ratio + pt.s);
16929      } else {
16930        pt.t[pt.p] = pt.c * this.ratio + pt.s;
16931      }
16932      pt = pt._next;
16933    }
16934    if (this._onUpdate) {
16935      if (time < 0) if (this._startAt && time !== -0.0001) {
16936        //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.
16937        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.
16938      }
16939      if (!suppressEvents) if (this._time !== prevTime || isComplete || force) {
16940        this._callback("onUpdate");
16941      }
16942    }
16943    if (callback) if (!this._gc || force) {
16944      //check _gc because there's a chance that kill() could be called in an onUpdate
16945      if (time < 0 && this._startAt && !this._onUpdate && time !== -0.0001) {
16946        //-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.
16947        this._startAt.render(time, true, force);
16948      }
16949      if (isComplete) {
16950        if (this._timeline.autoRemoveChildren) {
16951          this._enabled(false, false);
16952        }
16953        this._active = false;
16954      }
16955      if (!suppressEvents && this.vars[callback]) {
16956        this._callback(callback);
16957      }
16958      if (duration === 0 && this._rawPrevTime === _tinyNum && rawPrevTime !== _tinyNum) {
16959        //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 scenario, but possible nonetheless.
16960        this._rawPrevTime = 0;
16961      }
16962    }
16963  };
16964  p._kill = function (vars, target, overwritingTween) {
16965    if (vars === "all") {
16966      vars = null;
16967    }
16968    if (vars == null) if (target == null || target === this.target) {
16969      this._lazy = false;
16970      return this._enabled(false, false);
16971    }
16972    target = typeof target !== "string" ? target || this._targets || this.target : TweenLite.selector(target) || target;
16973    var simultaneousOverwrite = overwritingTween && this._time && overwritingTween._startTime === this._startTime && this._timeline === overwritingTween._timeline,
16974      i,
16975      overwrittenProps,
16976      p,
16977      pt,
16978      propLookup,
16979      changed,
16980      killProps,
16981      record,
16982      killed;
16983    if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") {
16984      i = target.length;
16985      while (--i > -1) {
16986        if (this._kill(vars, target[i], overwritingTween)) {
16987          changed = true;
16988        }
16989      }
16990    } else {
16991      if (this._targets) {
16992        i = this._targets.length;
16993        while (--i > -1) {
16994          if (target === this._targets[i]) {
16995            propLookup = this._propLookup[i] || {};
16996            this._overwrittenProps = this._overwrittenProps || [];
16997            overwrittenProps = this._overwrittenProps[i] = vars ? this._overwrittenProps[i] || {} : "all";
16998            break;
16999          }
17000        }
17001      } else if (target !== this.target) {
17002        return false;
17003      } else {
17004        propLookup = this._propLookup;
17005        overwrittenProps = this._overwrittenProps = vars ? this._overwrittenProps || {} : "all";
17006      }
17007      if (propLookup) {
17008        killProps = vars || propLookup;
17009        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)
17010        if (overwritingTween && (TweenLite.onOverwrite || this.vars.onOverwrite)) {
17011          for (p in killProps) {
17012            if (propLookup[p]) {
17013              if (!killed) {
17014                killed = [];
17015              }
17016              killed.push(p);
17017            }
17018          }
17019          if ((killed || !vars) && !_onOverwrite(this, overwritingTween, target, killed)) {
17020            //if the onOverwrite returned false, that means the user wants to override the overwriting (cancel it).
17021            return false;
17022          }
17023        }
17024        for (p in killProps) {
17025          if (pt = propLookup[p]) {
17026            if (simultaneousOverwrite) {
17027              //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.
17028              if (pt.f) {
17029                pt.t[pt.p](pt.s);
17030              } else {
17031                pt.t[pt.p] = pt.s;
17032              }
17033              changed = true;
17034            }
17035            if (pt.pg && pt.t._kill(killProps)) {
17036              changed = true; //some plugins need to be notified so they can perform cleanup tasks first
17037            }
17038            if (!pt.pg || pt.t._overwriteProps.length === 0) {
17039              if (pt._prev) {
17040                pt._prev._next = pt._next;
17041              } else if (pt === this._firstPT) {
17042                this._firstPT = pt._next;
17043              }
17044              if (pt._next) {
17045                pt._next._prev = pt._prev;
17046              }
17047              pt._next = pt._prev = null;
17048            }
17049            delete propLookup[p];
17050          }
17051          if (record) {
17052            overwrittenProps[p] = 1;
17053          }
17054        }
17055        if (!this._firstPT && this._initted) {
17056          //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.
17057          this._enabled(false, false);
17058        }
17059      }
17060    }
17061    return changed;
17062  };
17063  p.invalidate = function () {
17064    if (this._notifyPluginsOfEnabled) {
17065      TweenLite._onPluginEvent("_onDisable", this);
17066    }
17067    this._firstPT = this._overwrittenProps = this._startAt = this._onUpdate = null;
17068    this._notifyPluginsOfEnabled = this._active = this._lazy = false;
17069    this._propLookup = this._targets ? {} : [];
17070    Animation.prototype.invalidate.call(this);
17071    if (this.vars.immediateRender) {
17072      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)
17073      this.render(Math.min(0, -this._delay)); //in case delay is negative.
17074    }
17075    return this;
17076  };
17077  p._enabled = function (enabled, ignoreTimeline) {
17078    if (!_tickerActive) {
17079      _ticker.wake();
17080    }
17081    if (enabled && this._gc) {
17082      var targets = this._targets,
17083        i;
17084      if (targets) {
17085        i = targets.length;
17086        while (--i > -1) {
17087          this._siblings[i] = _register(targets[i], this, true);
17088        }
17089      } else {
17090        this._siblings = _register(this.target, this, true);
17091      }
17092    }
17093    Animation.prototype._enabled.call(this, enabled, ignoreTimeline);
17094    if (this._notifyPluginsOfEnabled) if (this._firstPT) {
17095      return TweenLite._onPluginEvent(enabled ? "_onEnable" : "_onDisable", this);
17096    }
17097    return false;
17098  };
17099
17100  //----TweenLite static methods -----------------------------------------------------
17101
17102  TweenLite.to = function (target, duration, vars) {
17103    return new TweenLite(target, duration, vars);
17104  };
17105  TweenLite.from = function (target, duration, vars) {
17106    vars.runBackwards = true;
17107    vars.immediateRender = vars.immediateRender != false;
17108    return new TweenLite(target, duration, vars);
17109  };
17110  TweenLite.fromTo = function (target, duration, fromVars, toVars) {
17111    toVars.startAt = fromVars;
17112    toVars.immediateRender = toVars.immediateRender != false && fromVars.immediateRender != false;
17113    return new TweenLite(target, duration, toVars);
17114  };
17115  TweenLite.delayedCall = function (delay, callback, params, scope, useFrames) {
17116    return new TweenLite(callback, 0, {
17117      delay: delay,
17118      onComplete: callback,
17119      onCompleteParams: params,
17120      callbackScope: scope,
17121      onReverseComplete: callback,
17122      onReverseCompleteParams: params,
17123      immediateRender: false,
17124      lazy: false,
17125      useFrames: useFrames,
17126      overwrite: 0
17127    });
17128  };
17129  TweenLite.set = function (target, vars) {
17130    return new TweenLite(target, 0, vars);
17131  };
17132  TweenLite.getTweensOf = function (target, onlyActive) {
17133    if (target == null) {
17134      return [];
17135    }
17136    target = typeof target !== "string" ? target : TweenLite.selector(target) || target;
17137    var i, a, j, t;
17138    if ((_isArray(target) || _isSelector(target)) && typeof target[0] !== "number") {
17139      i = target.length;
17140      a = [];
17141      while (--i > -1) {
17142        a = a.concat(TweenLite.getTweensOf(target[i], onlyActive));
17143      }
17144      i = a.length;
17145      //now get rid of any duplicates (tweens of arrays of objects could cause duplicates)
17146      while (--i > -1) {
17147        t = a[i];
17148        j = i;
17149        while (--j > -1) {
17150          if (t === a[j]) {
17151            a.splice(i, 1);
17152          }
17153        }
17154      }
17155    } else if (target._gsTweenID) {
17156      a = _register(target).concat();
17157      i = a.length;
17158      while (--i > -1) {
17159        if (a[i]._gc || onlyActive && !a[i].isActive()) {
17160          a.splice(i, 1);
17161        }
17162      }
17163    }
17164    return a || [];
17165  };
17166  TweenLite.killTweensOf = TweenLite.killDelayedCallsTo = function (target, onlyActive, vars) {
17167    if (_typeof(onlyActive) === "object") {
17168      vars = onlyActive; //for backwards compatibility (before "onlyActive" parameter was inserted)
17169      onlyActive = false;
17170    }
17171    var a = TweenLite.getTweensOf(target, onlyActive),
17172      i = a.length;
17173    while (--i > -1) {
17174      a[i]._kill(vars, target);
17175    }
17176  };
17177
17178  /*
17179   * ----------------------------------------------------------------
17180   * 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)
17181   * ----------------------------------------------------------------
17182   */
17183  var TweenPlugin = _class("plugins.TweenPlugin", function (props, priority) {
17184    this._overwriteProps = (props || "").split(",");
17185    this._propName = this._overwriteProps[0];
17186    this._priority = priority || 0;
17187    this._super = TweenPlugin.prototype;
17188  }, true);
17189  p = TweenPlugin.prototype;
17190  TweenPlugin.version = "1.19.0";
17191  TweenPlugin.API = 2;
17192  p._firstPT = null;
17193  p._addTween = _addPropTween;
17194  p.setRatio = _setRatio;
17195  p._kill = function (lookup) {
17196    var a = this._overwriteProps,
17197      pt = this._firstPT,
17198      i;
17199    if (lookup[this._propName] != null) {
17200      this._overwriteProps = [];
17201    } else {
17202      i = a.length;
17203      while (--i > -1) {
17204        if (lookup[a[i]] != null) {
17205          a.splice(i, 1);
17206        }
17207      }
17208    }
17209    while (pt) {
17210      if (lookup[pt.n] != null) {
17211        if (pt._next) {
17212          pt._next._prev = pt._prev;
17213        }
17214        if (pt._prev) {
17215          pt._prev._next = pt._next;
17216          pt._prev = null;
17217        } else if (this._firstPT === pt) {
17218          this._firstPT = pt._next;
17219        }
17220      }
17221      pt = pt._next;
17222    }
17223    return false;
17224  };
17225  p._mod = p._roundProps = function (lookup) {
17226    var pt = this._firstPT,
17227      val;
17228    while (pt) {
17229      val = lookup[this._propName] || pt.n != null && lookup[pt.n.split(this._propName + "_").join("")];
17230      if (val && typeof val === "function") {
17231        //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.
17232        if (pt.f === 2) {
17233          pt.t._applyPT.m = val;
17234        } else {
17235          pt.m = val;
17236        }
17237      }
17238      pt = pt._next;
17239    }
17240  };
17241  TweenLite._onPluginEvent = function (type, tween) {
17242    var pt = tween._firstPT,
17243      changed,
17244      pt2,
17245      first,
17246      last,
17247      next;
17248    if (type === "_onInitAllProps") {
17249      //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.
17250      while (pt) {
17251        next = pt._next;
17252        pt2 = first;
17253        while (pt2 && pt2.pr > pt.pr) {
17254          pt2 = pt2._next;
17255        }
17256        if (pt._prev = pt2 ? pt2._prev : last) {
17257          pt._prev._next = pt;
17258        } else {
17259          first = pt;
17260        }
17261        if (pt._next = pt2) {
17262          pt2._prev = pt;
17263        } else {
17264          last = pt;
17265        }
17266        pt = next;
17267      }
17268      pt = tween._firstPT = first;
17269    }
17270    while (pt) {
17271      if (pt.pg) if (typeof pt.t[type] === "function") if (pt.t[type]()) {
17272        changed = true;
17273      }
17274      pt = pt._next;
17275    }
17276    return changed;
17277  };
17278  TweenPlugin.activate = function (plugins) {
17279    var i = plugins.length;
17280    while (--i > -1) {
17281      if (plugins[i].API === TweenPlugin.API) {
17282        _plugins[new plugins[i]()._propName] = plugins[i];
17283      }
17284    }
17285    return true;
17286  };
17287
17288  //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.
17289  _gsDefine.plugin = function (config) {
17290    if (!config || !config.propName || !config.init || !config.API) {
17291      throw "illegal plugin definition.";
17292    }
17293    var propName = config.propName,
17294      priority = config.priority || 0,
17295      overwriteProps = config.overwriteProps,
17296      map = {
17297        init: "_onInitTween",
17298        set: "setRatio",
17299        kill: "_kill",
17300        round: "_mod",
17301        mod: "_mod",
17302        initAll: "_onInitAllProps"
17303      },
17304      Plugin = _class("plugins." + propName.charAt(0).toUpperCase() + propName.substr(1) + "Plugin", function () {
17305        TweenPlugin.call(this, propName, priority);
17306        this._overwriteProps = overwriteProps || [];
17307      }, config.global === true),
17308      p = Plugin.prototype = new TweenPlugin(propName),
17309      prop;
17310    p.constructor = Plugin;
17311    Plugin.API = config.API;
17312    for (prop in map) {
17313      if (typeof config[prop] === "function") {
17314        p[map[prop]] = config[prop];
17315      }
17316    }
17317    Plugin.version = config.version;
17318    TweenPlugin.activate([Plugin]);
17319    return Plugin;
17320  };
17321
17322  //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.
17323  a = window._gsQueue;
17324  if (a) {
17325    for (i = 0; i < a.length; i++) {
17326      a[i]();
17327    }
17328    for (p in _defLookup) {
17329      if (!_defLookup[p].func) {
17330        window.console.log("GSAP encountered missing dependency: " + p);
17331      }
17332    }
17333  }
17334  _tickerActive = false; //ensures that the first official animation forces a ticker.tick() to update the time when it is instantiated
17335})(typeof module !== "undefined" && module.exports && typeof global !== "undefined" ? global : void 0 || window, "TweenMax");
17336
17337}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
17338},{}],6:[function(require,module,exports){
17339"use strict";
17340
17341/*!
17342	Zoom 1.7.21
17343	license: MIT
17344	http://www.jacklmoore.com/zoom
17345*/
17346(function ($) {
17347  var defaults = {
17348    url: false,
17349    callback: false,
17350    target: false,
17351    duration: 120,
17352    on: 'mouseover',
17353    // other options: grab, click, toggle
17354    touch: true,
17355    // enables a touch fallback
17356    onZoomIn: false,
17357    onZoomOut: false,
17358    magnify: 1
17359  };
17360
17361  // Core Zoom Logic, independent of event listeners.
17362  $.zoom = function (target, source, img, magnify) {
17363    var targetHeight,
17364      targetWidth,
17365      sourceHeight,
17366      sourceWidth,
17367      xRatio,
17368      yRatio,
17369      offset,
17370      $target = $(target),
17371      position = $target.css('position'),
17372      $source = $(source);
17373
17374    // The parent element needs positioning so that the zoomed element can be correctly positioned within.
17375    target.style.position = /(absolute|fixed)/.test(position) ? position : 'relative';
17376    target.style.overflow = 'hidden';
17377    img.style.width = img.style.height = '';
17378    $(img).addClass('zoomImg').css({
17379      position: 'absolute',
17380      top: 0,
17381      left: 0,
17382      opacity: 0,
17383      width: img.width * magnify,
17384      height: img.height * magnify,
17385      border: 'none',
17386      maxWidth: 'none',
17387      maxHeight: 'none'
17388    }).appendTo(target);
17389    return {
17390      init: function init() {
17391        targetWidth = $target.outerWidth();
17392        targetHeight = $target.outerHeight();
17393        if (source === target) {
17394          sourceWidth = targetWidth;
17395          sourceHeight = targetHeight;
17396        } else {
17397          sourceWidth = $source.outerWidth();
17398          sourceHeight = $source.outerHeight();
17399        }
17400        xRatio = (img.width - targetWidth) / sourceWidth;
17401        yRatio = (img.height - targetHeight) / sourceHeight;
17402        offset = $source.offset();
17403      },
17404      move: function move(e) {
17405        var left = e.pageX - offset.left,
17406          top = e.pageY - offset.top;
17407        top = Math.max(Math.min(top, sourceHeight), 0);
17408        left = Math.max(Math.min(left, sourceWidth), 0);
17409        img.style.left = left * -xRatio + 'px';
17410        img.style.top = top * -yRatio + 'px';
17411      }
17412    };
17413  };
17414  $.fn.zoom = function (options) {
17415    return this.each(function () {
17416      var settings = $.extend({}, defaults, options || {}),
17417        //target will display the zoomed image
17418        target = settings.target && $(settings.target)[0] || this,
17419        //source will provide zoom location info (thumbnail)
17420        source = this,
17421        $source = $(source),
17422        img = document.createElement('img'),
17423        $img = $(img),
17424        mousemove = 'mousemove.zoom',
17425        clicked = false,
17426        touched = false;
17427
17428      // If a url wasn't specified, look for an image element.
17429      if (!settings.url) {
17430        var srcElement = source.querySelector('img');
17431        if (srcElement) {
17432          settings.url = srcElement.getAttribute('data-src') || srcElement.currentSrc || srcElement.src;
17433        }
17434        if (!settings.url) {
17435          return;
17436        }
17437      }
17438      $source.one('zoom.destroy', function (position, overflow) {
17439        $source.off(".zoom");
17440        target.style.position = position;
17441        target.style.overflow = overflow;
17442        img.onload = null;
17443        $img.remove();
17444      }.bind(this, target.style.position, target.style.overflow));
17445      img.onload = function () {
17446        var zoom = $.zoom(target, source, img, settings.magnify);
17447        function start(e) {
17448          zoom.init();
17449          zoom.move(e);
17450
17451          // Skip the fade-in for IE8 and lower since it chokes on fading-in
17452          // and changing position based on mousemovement at the same time.
17453          $img.stop().fadeTo($.support.opacity ? settings.duration : 0, 1, $.isFunction(settings.onZoomIn) ? settings.onZoomIn.call(img) : false);
17454        }
17455        function stop() {
17456          $img.stop().fadeTo(settings.duration, 0, $.isFunction(settings.onZoomOut) ? settings.onZoomOut.call(img) : false);
17457        }
17458
17459        // Mouse events
17460        if (settings.on === 'grab') {
17461          $source.on('mousedown.zoom', function (e) {
17462            if (e.which === 1) {
17463              $(document).one('mouseup.zoom', function () {
17464                stop();
17465                $(document).off(mousemove, zoom.move);
17466              });
17467              start(e);
17468              $(document).on(mousemove, zoom.move);
17469              e.preventDefault();
17470            }
17471          });
17472        } else if (settings.on === 'click') {
17473          $source.on('click.zoom', function (e) {
17474            if (clicked) {
17475              // bubble the event up to the document to trigger the unbind.
17476              return;
17477            } else {
17478              clicked = true;
17479              start(e);
17480              $(document).on(mousemove, zoom.move);
17481              $(document).one('click.zoom', function () {
17482                stop();
17483                clicked = false;
17484                $(document).off(mousemove, zoom.move);
17485              });
17486              return false;
17487            }
17488          });
17489        } else if (settings.on === 'toggle') {
17490          $source.on('click.zoom', function (e) {
17491            if (clicked) {
17492              stop();
17493            } else {
17494              start(e);
17495            }
17496            clicked = !clicked;
17497          });
17498        } else if (settings.on === 'mouseover') {
17499          zoom.init(); // Preemptively call init because IE7 will fire the mousemove handler before the hover handler.
17500
17501          $source.on('mouseenter.zoom', start).on('mouseleave.zoom', stop).on(mousemove, zoom.move);
17502        }
17503
17504        // Touch fallback
17505        if (settings.touch) {
17506          $source.on('touchstart.zoom', function (e) {
17507            e.preventDefault();
17508            if (touched) {
17509              touched = false;
17510              stop();
17511            } else {
17512              touched = true;
17513              start(e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]);
17514            }
17515          }).on('touchmove.zoom', function (e) {
17516            e.preventDefault();
17517            zoom.move(e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]);
17518          }).on('touchend.zoom', function (e) {
17519            e.preventDefault();
17520            if (touched) {
17521              touched = false;
17522              stop();
17523            }
17524          });
17525        }
17526        if ($.isFunction(settings.callback)) {
17527          settings.callback.call(img);
17528        }
17529      };
17530      img.setAttribute('role', 'presentation');
17531      img.alt = '';
17532      img.src = settings.url;
17533    });
17534  };
17535  $.fn.zoom.defaults = defaults;
17536})(window.jQuery);
17537
17538},{}],7:[function(require,module,exports){
17539(function (global){(function (){
17540"use strict";
17541
17542function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
17543/*
17544     _ _      _       _
17545 ___| (_) ___| | __  (_)___
17546/ __| | |/ __| |/ /  | / __|
17547\__ \ | | (__|   < _ | \__ \
17548|___/_|_|\___|_|\_(_)/ |___/
17549                   |__/
17550
17551 Version: 1.6.0
17552  Author: Ken Wheeler
17553 Website: http://kenwheeler.github.io
17554    Docs: http://kenwheeler.github.io/slick
17555    Repo: http://github.com/kenwheeler/slick
17556  Issues: http://github.com/kenwheeler/slick/issues
17557
17558 */
17559/* global window, document, define, jQuery, setInterval, clearInterval */
17560(function (factory) {
17561  'use strict';
17562
17563  if (typeof define === 'function' && define.amd) {
17564    define(['jquery'], factory);
17565  } else if (typeof exports !== 'undefined') {
17566    module.exports = factory((typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null));
17567  } else {
17568    factory(jQuery);
17569  }
17570})(function ($) {
17571  'use strict';
17572
17573  var Slick = window.Slick || {};
17574  Slick = function () {
17575    var instanceUid = 0;
17576    function Slick(element, settings) {
17577      var _ = this,
17578        dataSettings;
17579      _.defaults = {
17580        accessibility: true,
17581        adaptiveHeight: false,
17582        appendArrows: $(element),
17583        appendDots: $(element),
17584        arrows: true,
17585        asNavFor: null,
17586        prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button">Previous</button>',
17587        nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button">Next</button>',
17588        autoplay: false,
17589        autoplaySpeed: 3000,
17590        centerMode: false,
17591        centerPadding: '50px',
17592        cssEase: 'ease',
17593        customPaging: function customPaging(slider, i) {
17594          return $('<button type="button" data-role="none" role="button" tabindex="0" />').text(i + 1);
17595        },
17596        dots: false,
17597        dotsClass: 'slick-dots',
17598        draggable: true,
17599        easing: 'linear',
17600        edgeFriction: 0.35,
17601        fade: false,
17602        focusOnSelect: false,
17603        infinite: true,
17604        initialSlide: 0,
17605        lazyLoad: 'ondemand',
17606        mobileFirst: false,
17607        pauseOnHover: true,
17608        pauseOnFocus: true,
17609        pauseOnDotsHover: false,
17610        respondTo: 'window',
17611        responsive: null,
17612        rows: 1,
17613        rtl: false,
17614        slide: '',
17615        slidesPerRow: 1,
17616        slidesToShow: 1,
17617        slidesToScroll: 1,
17618        speed: 500,
17619        swipe: true,
17620        swipeToSlide: false,
17621        touchMove: true,
17622        touchThreshold: 5,
17623        useCSS: true,
17624        useTransform: true,
17625        variableWidth: false,
17626        vertical: false,
17627        verticalSwiping: false,
17628        waitForAnimate: true,
17629        zIndex: 1000
17630      };
17631      _.initials = {
17632        animating: false,
17633        dragging: false,
17634        autoPlayTimer: null,
17635        currentDirection: 0,
17636        currentLeft: null,
17637        currentSlide: 0,
17638        direction: 1,
17639        $dots: null,
17640        listWidth: null,
17641        listHeight: null,
17642        loadIndex: 0,
17643        $nextArrow: null,
17644        $prevArrow: null,
17645        slideCount: null,
17646        slideWidth: null,
17647        $slideTrack: null,
17648        $slides: null,
17649        sliding: false,
17650        slideOffset: 0,
17651        swipeLeft: null,
17652        $list: null,
17653        touchObject: {},
17654        transformsEnabled: false,
17655        unslicked: false
17656      };
17657      $.extend(_, _.initials);
17658      _.activeBreakpoint = null;
17659      _.animType = null;
17660      _.animProp = null;
17661      _.breakpoints = [];
17662      _.breakpointSettings = [];
17663      _.cssTransitions = false;
17664      _.focussed = false;
17665      _.interrupted = false;
17666      _.hidden = 'hidden';
17667      _.paused = true;
17668      _.positionProp = null;
17669      _.respondTo = null;
17670      _.rowCount = 1;
17671      _.shouldClick = true;
17672      _.$slider = $(element);
17673      _.$slidesCache = null;
17674      _.transformType = null;
17675      _.transitionType = null;
17676      _.visibilityChange = 'visibilitychange';
17677      _.windowWidth = 0;
17678      _.windowTimer = null;
17679      dataSettings = $(element).data('slick') || {};
17680      _.options = $.extend({}, _.defaults, settings, dataSettings);
17681      _.currentSlide = _.options.initialSlide;
17682      _.originalSettings = _.options;
17683      if (typeof document.mozHidden !== 'undefined') {
17684        _.hidden = 'mozHidden';
17685        _.visibilityChange = 'mozvisibilitychange';
17686      } else if (typeof document.webkitHidden !== 'undefined') {
17687        _.hidden = 'webkitHidden';
17688        _.visibilityChange = 'webkitvisibilitychange';
17689      }
17690      _.autoPlay = $.proxy(_.autoPlay, _);
17691      _.autoPlayClear = $.proxy(_.autoPlayClear, _);
17692      _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
17693      _.changeSlide = $.proxy(_.changeSlide, _);
17694      _.clickHandler = $.proxy(_.clickHandler, _);
17695      _.selectHandler = $.proxy(_.selectHandler, _);
17696      _.setPosition = $.proxy(_.setPosition, _);
17697      _.swipeHandler = $.proxy(_.swipeHandler, _);
17698      _.dragHandler = $.proxy(_.dragHandler, _);
17699      _.keyHandler = $.proxy(_.keyHandler, _);
17700      _.instanceUid = instanceUid++;
17701
17702      // A simple way to check for HTML strings
17703      // Strict HTML recognition (must start with <)
17704      // Extracted from jQuery v1.11 source
17705      _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
17706      _.registerBreakpoints();
17707      _.init(true);
17708    }
17709    return Slick;
17710  }();
17711  Slick.prototype.activateADA = function () {
17712    var _ = this;
17713    _.$slideTrack.find('.slick-active').attr({
17714      'aria-hidden': 'false'
17715    }).find('a, input, button, select').attr({
17716      'tabindex': '0'
17717    });
17718  };
17719  Slick.prototype.addSlide = Slick.prototype.slickAdd = function (markup, index, addBefore) {
17720    var _ = this;
17721    if (typeof index === 'boolean') {
17722      addBefore = index;
17723      index = null;
17724    } else if (index < 0 || index >= _.slideCount) {
17725      return false;
17726    }
17727    _.unload();
17728    if (typeof index === 'number') {
17729      if (index === 0 && _.$slides.length === 0) {
17730        $(markup).appendTo(_.$slideTrack);
17731      } else if (addBefore) {
17732        $(markup).insertBefore(_.$slides.eq(index));
17733      } else {
17734        $(markup).insertAfter(_.$slides.eq(index));
17735      }
17736    } else {
17737      if (addBefore === true) {
17738        $(markup).prependTo(_.$slideTrack);
17739      } else {
17740        $(markup).appendTo(_.$slideTrack);
17741      }
17742    }
17743    _.$slides = _.$slideTrack.children(this.options.slide);
17744    _.$slideTrack.children(this.options.slide).detach();
17745    _.$slideTrack.append(_.$slides);
17746    _.$slides.each(function (index, element) {
17747      $(element).attr('data-slick-index', index);
17748    });
17749    _.$slidesCache = _.$slides;
17750    _.reinit();
17751  };
17752  Slick.prototype.animateHeight = function () {
17753    var _ = this;
17754    if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
17755      var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
17756      _.$list.animate({
17757        height: targetHeight
17758      }, _.options.speed);
17759    }
17760  };
17761  Slick.prototype.animateSlide = function (targetLeft, callback) {
17762    var animProps = {},
17763      _ = this;
17764    _.animateHeight();
17765    if (_.options.rtl === true && _.options.vertical === false) {
17766      targetLeft = -targetLeft;
17767    }
17768    if (_.transformsEnabled === false) {
17769      if (_.options.vertical === false) {
17770        _.$slideTrack.animate({
17771          left: targetLeft
17772        }, _.options.speed, _.options.easing, callback);
17773      } else {
17774        _.$slideTrack.animate({
17775          top: targetLeft
17776        }, _.options.speed, _.options.easing, callback);
17777      }
17778    } else {
17779      if (_.cssTransitions === false) {
17780        if (_.options.rtl === true) {
17781          _.currentLeft = -_.currentLeft;
17782        }
17783        $({
17784          animStart: _.currentLeft
17785        }).animate({
17786          animStart: targetLeft
17787        }, {
17788          duration: _.options.speed,
17789          easing: _.options.easing,
17790          step: function step(now) {
17791            now = Math.ceil(now);
17792            if (_.options.vertical === false) {
17793              animProps[_.animType] = 'translate(' + now + 'px, 0px)';
17794              _.$slideTrack.css(animProps);
17795            } else {
17796              animProps[_.animType] = 'translate(0px,' + now + 'px)';
17797              _.$slideTrack.css(animProps);
17798            }
17799          },
17800          complete: function complete() {
17801            if (callback) {
17802              callback.call();
17803            }
17804          }
17805        });
17806      } else {
17807        _.applyTransition();
17808        targetLeft = Math.ceil(targetLeft);
17809        if (_.options.vertical === false) {
17810          animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
17811        } else {
17812          animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
17813        }
17814        _.$slideTrack.css(animProps);
17815        if (callback) {
17816          setTimeout(function () {
17817            _.disableTransition();
17818            callback.call();
17819          }, _.options.speed);
17820        }
17821      }
17822    }
17823  };
17824  Slick.prototype.getNavTarget = function () {
17825    var _ = this,
17826      asNavFor = _.options.asNavFor;
17827    if (asNavFor && asNavFor !== null) {
17828      asNavFor = $(asNavFor).not(_.$slider);
17829    }
17830    return asNavFor;
17831  };
17832  Slick.prototype.asNavFor = function (index) {
17833    var _ = this,
17834      asNavFor = _.getNavTarget();
17835    if (asNavFor !== null && _typeof(asNavFor) === 'object') {
17836      asNavFor.each(function () {
17837        var target = $(this).slick('getSlick');
17838        if (!target.unslicked) {
17839          target.slideHandler(index, true);
17840        }
17841      });
17842    }
17843  };
17844  Slick.prototype.applyTransition = function (slide) {
17845    var _ = this,
17846      transition = {};
17847    if (_.options.fade === false) {
17848      transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
17849    } else {
17850      transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
17851    }
17852    if (_.options.fade === false) {
17853      _.$slideTrack.css(transition);
17854    } else {
17855      _.$slides.eq(slide).css(transition);
17856    }
17857  };
17858  Slick.prototype.autoPlay = function () {
17859    var _ = this;
17860    _.autoPlayClear();
17861    if (_.slideCount > _.options.slidesToShow) {
17862      _.autoPlayTimer = setInterval(_.autoPlayIterator, _.options.autoplaySpeed);
17863    }
17864  };
17865  Slick.prototype.autoPlayClear = function () {
17866    var _ = this;
17867    if (_.autoPlayTimer) {
17868      clearInterval(_.autoPlayTimer);
17869    }
17870  };
17871  Slick.prototype.autoPlayIterator = function () {
17872    var _ = this,
17873      slideTo = _.currentSlide + _.options.slidesToScroll;
17874    if (!_.paused && !_.interrupted && !_.focussed) {
17875      if (_.options.infinite === false) {
17876        if (_.direction === 1 && _.currentSlide + 1 === _.slideCount - 1) {
17877          _.direction = 0;
17878        } else if (_.direction === 0) {
17879          slideTo = _.currentSlide - _.options.slidesToScroll;
17880          if (_.currentSlide - 1 === 0) {
17881            _.direction = 1;
17882          }
17883        }
17884      }
17885      _.slideHandler(slideTo);
17886    }
17887  };
17888  Slick.prototype.buildArrows = function () {
17889    var _ = this;
17890    if (_.options.arrows === true) {
17891      _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
17892      _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
17893      if (_.slideCount > _.options.slidesToShow) {
17894        _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
17895        _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
17896        if (_.htmlExpr.test(_.options.prevArrow)) {
17897          _.$prevArrow.prependTo(_.options.appendArrows);
17898        }
17899        if (_.htmlExpr.test(_.options.nextArrow)) {
17900          _.$nextArrow.appendTo(_.options.appendArrows);
17901        }
17902        if (_.options.infinite !== true) {
17903          _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
17904        }
17905      } else {
17906        _.$prevArrow.add(_.$nextArrow).addClass('slick-hidden').attr({
17907          'aria-disabled': 'true',
17908          'tabindex': '-1'
17909        });
17910      }
17911    }
17912  };
17913  Slick.prototype.buildDots = function () {
17914    var _ = this,
17915      i,
17916      dot;
17917    if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
17918      _.$slider.addClass('slick-dotted');
17919      dot = $('<ul />').addClass(_.options.dotsClass);
17920      for (i = 0; i <= _.getDotCount(); i += 1) {
17921        dot.append($('<li />').append(_.options.customPaging.call(this, _, i)));
17922      }
17923      _.$dots = dot.appendTo(_.options.appendDots);
17924      _.$dots.find('li').first().addClass('slick-active').attr('aria-hidden', 'false');
17925    }
17926  };
17927  Slick.prototype.buildOut = function () {
17928    var _ = this;
17929    _.$slides = _.$slider.children(_.options.slide + ':not(.slick-cloned)').addClass('slick-slide');
17930    _.slideCount = _.$slides.length;
17931    _.$slides.each(function (index, element) {
17932      $(element).attr('data-slick-index', index).data('originalStyling', $(element).attr('style') || '');
17933    });
17934    _.$slider.addClass('slick-slider');
17935    _.$slideTrack = _.slideCount === 0 ? $('<div class="slick-track"/>').appendTo(_.$slider) : _.$slides.wrapAll('<div class="slick-track"/>').parent();
17936    _.$list = _.$slideTrack.wrap('<div aria-live="polite" class="slick-list"/>').parent();
17937    _.$slideTrack.css('opacity', 0);
17938    if (_.options.centerMode === true || _.options.swipeToSlide === true) {
17939      _.options.slidesToScroll = 1;
17940    }
17941    $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
17942    _.setupInfinite();
17943    _.buildArrows();
17944    _.buildDots();
17945    _.updateDots();
17946    _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
17947    if (_.options.draggable === true) {
17948      _.$list.addClass('draggable');
17949    }
17950  };
17951  Slick.prototype.buildRows = function () {
17952    var _ = this,
17953      a,
17954      b,
17955      c,
17956      newSlides,
17957      numOfSlides,
17958      originalSlides,
17959      slidesPerSection;
17960    newSlides = document.createDocumentFragment();
17961    originalSlides = _.$slider.children();
17962    if (_.options.rows > 1) {
17963      slidesPerSection = _.options.slidesPerRow * _.options.rows;
17964      numOfSlides = Math.ceil(originalSlides.length / slidesPerSection);
17965      for (a = 0; a < numOfSlides; a++) {
17966        var slide = document.createElement('div');
17967        for (b = 0; b < _.options.rows; b++) {
17968          var row = document.createElement('div');
17969          for (c = 0; c < _.options.slidesPerRow; c++) {
17970            var target = a * slidesPerSection + (b * _.options.slidesPerRow + c);
17971            if (originalSlides.get(target)) {
17972              row.appendChild(originalSlides.get(target));
17973            }
17974          }
17975          slide.appendChild(row);
17976        }
17977        newSlides.appendChild(slide);
17978      }
17979      _.$slider.empty().append(newSlides);
17980      _.$slider.children().children().children().css({
17981        'width': 100 / _.options.slidesPerRow + '%',
17982        'display': 'inline-block'
17983      });
17984    }
17985  };
17986  Slick.prototype.checkResponsive = function (initial, forceUpdate) {
17987    var _ = this,
17988      breakpoint,
17989      targetBreakpoint,
17990      respondToWidth,
17991      triggerBreakpoint = false;
17992    var sliderWidth = _.$slider.width();
17993    var windowWidth = window.innerWidth || $(window).width();
17994    if (_.respondTo === 'window') {
17995      respondToWidth = windowWidth;
17996    } else if (_.respondTo === 'slider') {
17997      respondToWidth = sliderWidth;
17998    } else if (_.respondTo === 'min') {
17999      respondToWidth = Math.min(windowWidth, sliderWidth);
18000    }
18001    if (_.options.responsive && _.options.responsive.length && _.options.responsive !== null) {
18002      targetBreakpoint = null;
18003      for (breakpoint in _.breakpoints) {
18004        if (_.breakpoints.hasOwnProperty(breakpoint)) {
18005          if (_.originalSettings.mobileFirst === false) {
18006            if (respondToWidth < _.breakpoints[breakpoint]) {
18007              targetBreakpoint = _.breakpoints[breakpoint];
18008            }
18009          } else {
18010            if (respondToWidth > _.breakpoints[breakpoint]) {
18011              targetBreakpoint = _.breakpoints[breakpoint];
18012            }
18013          }
18014        }
18015      }
18016      if (targetBreakpoint !== null) {
18017        if (_.activeBreakpoint !== null) {
18018          if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
18019            _.activeBreakpoint = targetBreakpoint;
18020            if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
18021              _.unslick(targetBreakpoint);
18022            } else {
18023              _.options = $.extend({}, _.originalSettings, _.breakpointSettings[targetBreakpoint]);
18024              if (initial === true) {
18025                _.currentSlide = _.options.initialSlide;
18026              }
18027              _.refresh(initial);
18028            }
18029            triggerBreakpoint = targetBreakpoint;
18030          }
18031        } else {
18032          _.activeBreakpoint = targetBreakpoint;
18033          if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
18034            _.unslick(targetBreakpoint);
18035          } else {
18036            _.options = $.extend({}, _.originalSettings, _.breakpointSettings[targetBreakpoint]);
18037            if (initial === true) {
18038              _.currentSlide = _.options.initialSlide;
18039            }
18040            _.refresh(initial);
18041          }
18042          triggerBreakpoint = targetBreakpoint;
18043        }
18044      } else {
18045        if (_.activeBreakpoint !== null) {
18046          _.activeBreakpoint = null;
18047          _.options = _.originalSettings;
18048          if (initial === true) {
18049            _.currentSlide = _.options.initialSlide;
18050          }
18051          _.refresh(initial);
18052          triggerBreakpoint = targetBreakpoint;
18053        }
18054      }
18055
18056      // only trigger breakpoints during an actual break. not on initialize.
18057      if (!initial && triggerBreakpoint !== false) {
18058        _.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
18059      }
18060    }
18061  };
18062  Slick.prototype.changeSlide = function (event, dontAnimate) {
18063    var _ = this,
18064      $target = $(event.currentTarget),
18065      indexOffset,
18066      slideOffset,
18067      unevenOffset;
18068
18069    // If target is a link, prevent default action.
18070    if ($target.is('a')) {
18071      event.preventDefault();
18072    }
18073
18074    // If target is not the <li> element (ie: a child), find the <li>.
18075    if (!$target.is('li')) {
18076      $target = $target.closest('li');
18077    }
18078    unevenOffset = _.slideCount % _.options.slidesToScroll !== 0;
18079    indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
18080    switch (event.data.message) {
18081      case 'previous':
18082        slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
18083        if (_.slideCount > _.options.slidesToShow) {
18084          _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
18085        }
18086        break;
18087      case 'next':
18088        slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
18089        if (_.slideCount > _.options.slidesToShow) {
18090          _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
18091        }
18092        break;
18093      case 'index':
18094        var index = event.data.index === 0 ? 0 : event.data.index || $target.index() * _.options.slidesToScroll;
18095        _.slideHandler(_.checkNavigable(index), false, dontAnimate);
18096        $target.children().trigger('focus');
18097        break;
18098      default:
18099        return;
18100    }
18101  };
18102  Slick.prototype.checkNavigable = function (index) {
18103    var _ = this,
18104      navigables,
18105      prevNavigable;
18106    navigables = _.getNavigableIndexes();
18107    prevNavigable = 0;
18108    if (index > navigables[navigables.length - 1]) {
18109      index = navigables[navigables.length - 1];
18110    } else {
18111      for (var n in navigables) {
18112        if (index < navigables[n]) {
18113          index = prevNavigable;
18114          break;
18115        }
18116        prevNavigable = navigables[n];
18117      }
18118    }
18119    return index;
18120  };
18121  Slick.prototype.cleanUpEvents = function () {
18122    var _ = this;
18123    if (_.options.dots && _.$dots !== null) {
18124      $('li', _.$dots).off('click.slick', _.changeSlide).off('mouseenter.slick', $.proxy(_.interrupt, _, true)).off('mouseleave.slick', $.proxy(_.interrupt, _, false));
18125    }
18126    _.$slider.off('focus.slick blur.slick');
18127    if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
18128      _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
18129      _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
18130    }
18131    _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
18132    _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
18133    _.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
18134    _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
18135    _.$list.off('click.slick', _.clickHandler);
18136    $(document).off(_.visibilityChange, _.visibility);
18137    _.cleanUpSlideEvents();
18138    if (_.options.accessibility === true) {
18139      _.$list.off('keydown.slick', _.keyHandler);
18140    }
18141    if (_.options.focusOnSelect === true) {
18142      $(_.$slideTrack).children().off('click.slick', _.selectHandler);
18143    }
18144    $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
18145    $(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
18146    $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
18147    $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
18148    $(document).off('ready.slick.slick-' + _.instanceUid, _.setPosition);
18149  };
18150  Slick.prototype.cleanUpSlideEvents = function () {
18151    var _ = this;
18152    _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
18153    _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
18154  };
18155  Slick.prototype.cleanUpRows = function () {
18156    var _ = this,
18157      originalSlides;
18158    if (_.options.rows > 1) {
18159      originalSlides = _.$slides.children().children();
18160      originalSlides.removeAttr('style');
18161      _.$slider.empty().append(originalSlides);
18162    }
18163  };
18164  Slick.prototype.clickHandler = function (event) {
18165    var _ = this;
18166    if (_.shouldClick === false) {
18167      event.stopImmediatePropagation();
18168      event.stopPropagation();
18169      event.preventDefault();
18170    }
18171  };
18172  Slick.prototype.destroy = function (refresh) {
18173    var _ = this;
18174    _.autoPlayClear();
18175    _.touchObject = {};
18176    _.cleanUpEvents();
18177    $('.slick-cloned', _.$slider).detach();
18178    if (_.$dots) {
18179      _.$dots.remove();
18180    }
18181    if (_.$prevArrow && _.$prevArrow.length) {
18182      _.$prevArrow.removeClass('slick-disabled slick-arrow slick-hidden').removeAttr('aria-hidden aria-disabled tabindex').css('display', '');
18183      if (_.htmlExpr.test(_.options.prevArrow)) {
18184        _.$prevArrow.remove();
18185      }
18186    }
18187    if (_.$nextArrow && _.$nextArrow.length) {
18188      _.$nextArrow.removeClass('slick-disabled slick-arrow slick-hidden').removeAttr('aria-hidden aria-disabled tabindex').css('display', '');
18189      if (_.htmlExpr.test(_.options.nextArrow)) {
18190        _.$nextArrow.remove();
18191      }
18192    }
18193    if (_.$slides) {
18194      _.$slides.removeClass('slick-slide slick-active slick-center slick-visible slick-current').removeAttr('aria-hidden').removeAttr('data-slick-index').each(function () {
18195        $(this).attr('style', $(this).data('originalStyling'));
18196      });
18197      _.$slideTrack.children(this.options.slide).detach();
18198      _.$slideTrack.detach();
18199      _.$list.detach();
18200      _.$slider.append(_.$slides);
18201    }
18202    _.cleanUpRows();
18203    _.$slider.removeClass('slick-slider');
18204    _.$slider.removeClass('slick-initialized');
18205    _.$slider.removeClass('slick-dotted');
18206    _.unslicked = true;
18207    if (!refresh) {
18208      _.$slider.trigger('destroy', [_]);
18209    }
18210  };
18211  Slick.prototype.disableTransition = function (slide) {
18212    var _ = this,
18213      transition = {};
18214    transition[_.transitionType] = '';
18215    if (_.options.fade === false) {
18216      _.$slideTrack.css(transition);
18217    } else {
18218      _.$slides.eq(slide).css(transition);
18219    }
18220  };
18221  Slick.prototype.fadeSlide = function (slideIndex, callback) {
18222    var _ = this;
18223    if (_.cssTransitions === false) {
18224      _.$slides.eq(slideIndex).css({
18225        zIndex: _.options.zIndex
18226      });
18227      _.$slides.eq(slideIndex).animate({
18228        opacity: 1
18229      }, _.options.speed, _.options.easing, callback);
18230    } else {
18231      _.applyTransition(slideIndex);
18232      _.$slides.eq(slideIndex).css({
18233        opacity: 1,
18234        zIndex: _.options.zIndex
18235      });
18236      if (callback) {
18237        setTimeout(function () {
18238          _.disableTransition(slideIndex);
18239          callback.call();
18240        }, _.options.speed);
18241      }
18242    }
18243  };
18244  Slick.prototype.fadeSlideOut = function (slideIndex) {
18245    var _ = this;
18246    if (_.cssTransitions === false) {
18247      _.$slides.eq(slideIndex).animate({
18248        opacity: 0,
18249        zIndex: _.options.zIndex - 2
18250      }, _.options.speed, _.options.easing);
18251    } else {
18252      _.applyTransition(slideIndex);
18253      _.$slides.eq(slideIndex).css({
18254        opacity: 0,
18255        zIndex: _.options.zIndex - 2
18256      });
18257    }
18258  };
18259  Slick.prototype.filterSlides = Slick.prototype.slickFilter = function (filter) {
18260    var _ = this;
18261    if (filter !== null) {
18262      _.$slidesCache = _.$slides;
18263      _.unload();
18264      _.$slideTrack.children(this.options.slide).detach();
18265      _.$slidesCache.filter(filter).appendTo(_.$slideTrack);
18266      _.reinit();
18267    }
18268  };
18269  Slick.prototype.focusHandler = function () {
18270    var _ = this;
18271    _.$slider.off('focus.slick blur.slick').on('focus.slick blur.slick', '*:not(.slick-arrow)', function (event) {
18272      event.stopImmediatePropagation();
18273      var $sf = $(this);
18274      setTimeout(function () {
18275        if (_.options.pauseOnFocus) {
18276          _.focussed = $sf.is(':focus');
18277          _.autoPlay();
18278        }
18279      }, 0);
18280    });
18281  };
18282  Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function () {
18283    var _ = this;
18284    return _.currentSlide;
18285  };
18286  Slick.prototype.getDotCount = function () {
18287    var _ = this;
18288    var breakPoint = 0;
18289    var counter = 0;
18290    var pagerQty = 0;
18291    if (_.options.infinite === true) {
18292      while (breakPoint < _.slideCount) {
18293        ++pagerQty;
18294        breakPoint = counter + _.options.slidesToScroll;
18295        counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
18296      }
18297    } else if (_.options.centerMode === true) {
18298      pagerQty = _.slideCount;
18299    } else if (!_.options.asNavFor) {
18300      pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
18301    } else {
18302      while (breakPoint < _.slideCount) {
18303        ++pagerQty;
18304        breakPoint = counter + _.options.slidesToScroll;
18305        counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
18306      }
18307    }
18308    return pagerQty - 1;
18309  };
18310  Slick.prototype.getLeft = function (slideIndex) {
18311    var _ = this,
18312      targetLeft,
18313      verticalHeight,
18314      verticalOffset = 0,
18315      targetSlide;
18316    _.slideOffset = 0;
18317    verticalHeight = _.$slides.first().outerHeight(true);
18318    if (_.options.infinite === true) {
18319      if (_.slideCount > _.options.slidesToShow) {
18320        _.slideOffset = _.slideWidth * _.options.slidesToShow * -1;
18321        verticalOffset = verticalHeight * _.options.slidesToShow * -1;
18322      }
18323      if (_.slideCount % _.options.slidesToScroll !== 0) {
18324        if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
18325          if (slideIndex > _.slideCount) {
18326            _.slideOffset = (_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth * -1;
18327            verticalOffset = (_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight * -1;
18328          } else {
18329            _.slideOffset = _.slideCount % _.options.slidesToScroll * _.slideWidth * -1;
18330            verticalOffset = _.slideCount % _.options.slidesToScroll * verticalHeight * -1;
18331          }
18332        }
18333      }
18334    } else {
18335      if (slideIndex + _.options.slidesToShow > _.slideCount) {
18336        _.slideOffset = (slideIndex + _.options.slidesToShow - _.slideCount) * _.slideWidth;
18337        verticalOffset = (slideIndex + _.options.slidesToShow - _.slideCount) * verticalHeight;
18338      }
18339    }
18340    if (_.slideCount <= _.options.slidesToShow) {
18341      _.slideOffset = 0;
18342      verticalOffset = 0;
18343    }
18344    if (_.options.centerMode === true && _.options.infinite === true) {
18345      _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
18346    } else if (_.options.centerMode === true) {
18347      _.slideOffset = 0;
18348      _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
18349    }
18350    if (_.options.vertical === false) {
18351      targetLeft = slideIndex * _.slideWidth * -1 + _.slideOffset;
18352    } else {
18353      targetLeft = slideIndex * verticalHeight * -1 + verticalOffset;
18354    }
18355    if (_.options.variableWidth === true) {
18356      if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
18357        targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
18358      } else {
18359        targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
18360      }
18361      if (_.options.rtl === true) {
18362        if (targetSlide[0]) {
18363          targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
18364        } else {
18365          targetLeft = 0;
18366        }
18367      } else {
18368        targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
18369      }
18370      if (_.options.centerMode === true) {
18371        if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
18372          targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
18373        } else {
18374          targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
18375        }
18376        if (_.options.rtl === true) {
18377          if (targetSlide[0]) {
18378            targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
18379          } else {
18380            targetLeft = 0;
18381          }
18382        } else {
18383          targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
18384        }
18385        targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
18386      }
18387    }
18388    return targetLeft;
18389  };
18390  Slick.prototype.getOption = Slick.prototype.slickGetOption = function (option) {
18391    var _ = this;
18392    return _.options[option];
18393  };
18394  Slick.prototype.getNavigableIndexes = function () {
18395    var _ = this,
18396      breakPoint = 0,
18397      counter = 0,
18398      indexes = [],
18399      max;
18400    if (_.options.infinite === false) {
18401      max = _.slideCount;
18402    } else {
18403      breakPoint = _.options.slidesToScroll * -1;
18404      counter = _.options.slidesToScroll * -1;
18405      max = _.slideCount * 2;
18406    }
18407    while (breakPoint < max) {
18408      indexes.push(breakPoint);
18409      breakPoint = counter + _.options.slidesToScroll;
18410      counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
18411    }
18412    return indexes;
18413  };
18414  Slick.prototype.getSlick = function () {
18415    return this;
18416  };
18417  Slick.prototype.getSlideCount = function () {
18418    var _ = this,
18419      slidesTraversed,
18420      swipedSlide,
18421      centerOffset;
18422    centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;
18423    if (_.options.swipeToSlide === true) {
18424      _.$slideTrack.find('.slick-slide').each(function (index, slide) {
18425        if (slide.offsetLeft - centerOffset + $(slide).outerWidth() / 2 > _.swipeLeft * -1) {
18426          swipedSlide = slide;
18427          return false;
18428        }
18429      });
18430      slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
18431      return slidesTraversed;
18432    } else {
18433      return _.options.slidesToScroll;
18434    }
18435  };
18436  Slick.prototype.goTo = Slick.prototype.slickGoTo = function (slide, dontAnimate) {
18437    var _ = this;
18438    _.changeSlide({
18439      data: {
18440        message: 'index',
18441        index: parseInt(slide)
18442      }
18443    }, dontAnimate);
18444  };
18445  Slick.prototype.init = function (creation) {
18446    var _ = this;
18447    if (!$(_.$slider).hasClass('slick-initialized')) {
18448      $(_.$slider).addClass('slick-initialized');
18449      _.buildRows();
18450      _.buildOut();
18451      _.setProps();
18452      _.startLoad();
18453      _.loadSlider();
18454      _.initializeEvents();
18455      _.updateArrows();
18456      _.updateDots();
18457      _.checkResponsive(true);
18458      _.focusHandler();
18459    }
18460    if (creation) {
18461      _.$slider.trigger('init', [_]);
18462    }
18463    if (_.options.accessibility === true) {
18464      _.initADA();
18465    }
18466    if (_.options.autoplay) {
18467      _.paused = false;
18468      _.autoPlay();
18469    }
18470  };
18471  Slick.prototype.initADA = function () {
18472    var _ = this;
18473    _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
18474      'aria-hidden': 'true',
18475      'tabindex': '-1'
18476    }).find('a, input, button, select').attr({
18477      'tabindex': '-1'
18478    });
18479    _.$slideTrack.attr('role', 'listbox');
18480    _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function (i) {
18481      $(this).attr({
18482        'role': 'option',
18483        'aria-describedby': 'slick-slide' + _.instanceUid + i + ''
18484      });
18485    });
18486    if (_.$dots !== null) {
18487      _.$dots.attr('role', 'tablist').find('li').each(function (i) {
18488        $(this).attr({
18489          'role': 'presentation',
18490          'aria-selected': 'false',
18491          'aria-controls': 'navigation' + _.instanceUid + i + '',
18492          'id': 'slick-slide' + _.instanceUid + i + ''
18493        });
18494      }).first().attr('aria-selected', 'true').end().find('button').attr('role', 'button').end().closest('div').attr('role', 'toolbar');
18495    }
18496    _.activateADA();
18497  };
18498  Slick.prototype.initArrowEvents = function () {
18499    var _ = this;
18500    if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
18501      _.$prevArrow.off('click.slick').on('click.slick', {
18502        message: 'previous'
18503      }, _.changeSlide);
18504      _.$nextArrow.off('click.slick').on('click.slick', {
18505        message: 'next'
18506      }, _.changeSlide);
18507    }
18508  };
18509  Slick.prototype.initDotEvents = function () {
18510    var _ = this;
18511    if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
18512      $('li', _.$dots).on('click.slick', {
18513        message: 'index'
18514      }, _.changeSlide);
18515    }
18516    if (_.options.dots === true && _.options.pauseOnDotsHover === true) {
18517      $('li', _.$dots).on('mouseenter.slick', $.proxy(_.interrupt, _, true)).on('mouseleave.
18517slick', $.proxy(_.interrupt, _, false));
18518    }
18519  };
18520  Slick.prototype.initSlideEvents = function () {
18521    var _ = this;
18522    if (_.options.pauseOnHover) {
18523      _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
18524      _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
18525    }
18526  };
18527  Slick.prototype.initializeEvents = function () {
18528    var _ = this;
18529    _.initArrowEvents();
18530    _.initDotEvents();
18531    _.initSlideEvents();
18532    _.$list.on('touchstart.slick mousedown.slick', {
18533      action: 'start'
18534    }, _.swipeHandler);
18535    _.$list.on('touchmove.slick mousemove.slick', {
18536      action: 'move'
18537    }, _.swipeHandler);
18538    _.$list.on('touchend.slick mouseup.slick', {
18539      action: 'end'
18540    }, _.swipeHandler);
18541    _.$list.on('touchcancel.slick mouseleave.slick', {
18542      action: 'end'
18543    }, _.swipeHandler);
18544    _.$list.on('click.slick', _.clickHandler);
18545    $(document).on(_.visibilityChange, $.proxy(_.visibility, _));
18546    if (_.options.accessibility === true) {
18547      _.$list.on('keydown.slick', _.keyHandler);
18548    }
18549    if (_.options.focusOnSelect === true) {
18550      $(_.$slideTrack).children().on('click.slick', _.selectHandler);
18551    }
18552    $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
18553    $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
18554    $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
18555    $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
18556    $(document).on('ready.slick.slick-' + _.instanceUid, _.setPosition);
18557  };
18558  Slick.prototype.initUI = function () {
18559    var _ = this;
18560    if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
18561      _.$prevArrow.show();
18562      _.$nextArrow.show();
18563    }
18564    if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
18565      _.$dots.show();
18566    }
18567  };
18568  Slick.prototype.keyHandler = function (event) {
18569    var _ = this;
18570    //Dont slide if the cursor is inside the form fields and arrow keys are pressed
18571    if (!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
18572      if (event.keyCode === 37 && _.options.accessibility === true) {
18573        _.changeSlide({
18574          data: {
18575            message: _.options.rtl === true ? 'next' : 'previous'
18576          }
18577        });
18578      } else if (event.keyCode === 39 && _.options.accessibility === true) {
18579        _.changeSlide({
18580          data: {
18581            message: _.options.rtl === true ? 'previous' : 'next'
18582          }
18583        });
18584      }
18585    }
18586  };
18587  Slick.prototype.lazyLoad = function () {
18588    var _ = this,
18589      loadRange,
18590      cloneRange,
18591      rangeStart,
18592      rangeEnd;
18593    function loadImages(imagesScope) {
18594      $('img[data-lazy]', imagesScope).each(function () {
18595        var image = $(this),
18596          imageSource = $(this).attr('data-lazy'),
18597          imageToLoad = document.createElement('img');
18598        imageToLoad.onload = function () {
18599          image.animate({
18600            opacity: 0
18601          }, 100, function () {
18602            image.attr('src', imageSource).animate({
18603              opacity: 1
18604            }, 200, function () {
18605              image.removeAttr('data-lazy').removeClass('slick-loading');
18606            });
18607            _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
18608          });
18609        };
18610        imageToLoad.onerror = function () {
18611          image.removeAttr('data-lazy').removeClass('slick-loading').addClass('slick-lazyload-error');
18612          _.$slider.trigger('lazyLoadError', [_, image, imageSource]);
18613        };
18614        imageToLoad.src = imageSource;
18615      });
18616    }
18617    if (_.options.centerMode === true) {
18618      if (_.options.infinite === true) {
18619        rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
18620        rangeEnd = rangeStart + _.options.slidesToShow + 2;
18621      } else {
18622        rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
18623        rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
18624      }
18625    } else {
18626      rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
18627      rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
18628      if (_.options.fade === true) {
18629        if (rangeStart > 0) rangeStart--;
18630        if (rangeEnd <= _.slideCount) rangeEnd++;
18631      }
18632    }
18633    loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
18634    loadImages(loadRange);
18635    if (_.slideCount <= _.options.slidesToShow) {
18636      cloneRange = _.$slider.find('.slick-slide');
18637      loadImages(cloneRange);
18638    } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
18639      cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
18640      loadImages(cloneRange);
18641    } else if (_.currentSlide === 0) {
18642      cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
18643      loadImages(cloneRange);
18644    }
18645  };
18646  Slick.prototype.loadSlider = function () {
18647    var _ = this;
18648    _.setPosition();
18649    _.$slideTrack.css({
18650      opacity: 1
18651    });
18652    _.$slider.removeClass('slick-loading');
18653    _.initUI();
18654    if (_.options.lazyLoad === 'progressive') {
18655      _.progressiveLazyLoad();
18656    }
18657  };
18658  Slick.prototype.next = Slick.prototype.slickNext = function () {
18659    var _ = this;
18660    _.changeSlide({
18661      data: {
18662        message: 'next'
18663      }
18664    });
18665  };
18666  Slick.prototype.orientationChange = function () {
18667    var _ = this;
18668    _.checkResponsive();
18669    _.setPosition();
18670  };
18671  Slick.prototype.pause = Slick.prototype.slickPause = function () {
18672    var _ = this;
18673    _.autoPlayClear();
18674    _.paused = true;
18675  };
18676  Slick.prototype.play = Slick.prototype.slickPlay = function () {
18677    var _ = this;
18678    _.autoPlay();
18679    _.options.autoplay = true;
18680    _.paused = false;
18681    _.focussed = false;
18682    _.interrupted = false;
18683  };
18684  Slick.prototype.postSlide = function (index) {
18685    var _ = this;
18686    if (!_.unslicked) {
18687      _.$slider.trigger('afterChange', [_, index]);
18688      _.animating = false;
18689      _.setPosition();
18690      _.swipeLeft = null;
18691      if (_.options.autoplay) {
18692        _.autoPlay();
18693      }
18694      if (_.options.accessibility === true) {
18695        _.initADA();
18696      }
18697    }
18698  };
18699  Slick.prototype.prev = Slick.prototype.slickPrev = function () {
18700    var _ = this;
18701    _.changeSlide({
18702      data: {
18703        message: 'previous'
18704      }
18705    });
18706  };
18707  Slick.prototype.preventDefault = function (event) {
18708    event.preventDefault();
18709  };
18710  Slick.prototype.progressiveLazyLoad = function (tryCount) {
18711    tryCount = tryCount || 1;
18712    var _ = this,
18713      $imgsToLoad = $('img[data-lazy]', _.$slider),
18714      image,
18715      imageSource,
18716      imageToLoad;
18717    if ($imgsToLoad.length) {
18718      image = $imgsToLoad.first();
18719      imageSource = image.attr('data-lazy');
18720      imageToLoad = document.createElement('img');
18721      imageToLoad.onload = function () {
18722        image.attr('src', imageSource).removeAttr('data-lazy').removeClass('slick-loading');
18723        if (_.options.adaptiveHeight === true) {
18724          _.setPosition();
18725        }
18726        _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
18727        _.progressiveLazyLoad();
18728      };
18729      imageToLoad.onerror = function () {
18730        if (tryCount < 3) {
18731          /**
18732           * try to load the image 3 times,
18733           * leave a slight delay so we don't get
18734           * servers blocking the request.
18735           */
18736          setTimeout(function () {
18737            _.progressiveLazyLoad(tryCount + 1);
18738          }, 500);
18739        } else {
18740          image.removeAttr('data-lazy').removeClass('slick-loading').addClass('slick-lazyload-error');
18741          _.$slider.trigger('lazyLoadError', [_, image, imageSource]);
18742          _.progressiveLazyLoad();
18743        }
18744      };
18745      imageToLoad.src = imageSource;
18746    } else {
18747      _.$slider.trigger('allImagesLoaded', [_]);
18748    }
18749  };
18750  Slick.prototype.refresh = function (initializing) {
18751    var _ = this,
18752      currentSlide,
18753      lastVisibleIndex;
18754    lastVisibleIndex = _.slideCount - _.options.slidesToShow;
18755
18756    // in non-infinite sliders, we don't want to go past the
18757    // last visible index.
18758    if (!_.options.infinite && _.currentSlide > lastVisibleIndex) {
18759      _.currentSlide = lastVisibleIndex;
18760    }
18761
18762    // if less slides than to show, go to start.
18763    if (_.slideCount <= _.options.slidesToShow) {
18764      _.currentSlide = 0;
18765    }
18766    currentSlide = _.currentSlide;
18767    _.destroy(true);
18768    $.extend(_, _.initials, {
18769      currentSlide: currentSlide
18770    });
18771    _.init();
18772    if (!initializing) {
18773      _.changeSlide({
18774        data: {
18775          message: 'index',
18776          index: currentSlide
18777        }
18778      }, false);
18779    }
18780  };
18781  Slick.prototype.registerBreakpoints = function () {
18782    var _ = this,
18783      breakpoint,
18784      currentBreakpoint,
18785      l,
18786      responsiveSettings = _.options.responsive || null;
18787    if ($.type(responsiveSettings) === 'array' && responsiveSettings.length) {
18788      _.respondTo = _.options.respondTo || 'window';
18789      for (breakpoint in responsiveSettings) {
18790        l = _.breakpoints.length - 1;
18791        currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
18792        if (responsiveSettings.hasOwnProperty(breakpoint)) {
18793          // loop through the breakpoints and cut out any existing
18794          // ones with the same breakpoint number, we don't want dupes.
18795          while (l >= 0) {
18796            if (_.breakpoints[l] && _.breakpoints[l] === currentBreakpoint) {
18797              _.breakpoints.splice(l, 1);
18798            }
18799            l--;
18800          }
18801          _.breakpoints.push(currentBreakpoint);
18802          _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
18803        }
18804      }
18805      _.breakpoints.sort(function (a, b) {
18806        return _.options.mobileFirst ? a - b : b - a;
18807      });
18808    }
18809  };
18810  Slick.prototype.reinit = function () {
18811    var _ = this;
18812    _.$slides = _.$slideTrack.children(_.options.slide).addClass('slick-slide');
18813    _.slideCount = _.$slides.length;
18814    if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
18815      _.currentSlide = _.currentSlide - _.options.slidesToScroll;
18816    }
18817    if (_.slideCount <= _.options.slidesToShow) {
18818      _.currentSlide = 0;
18819    }
18820    _.registerBreakpoints();
18821    _.setProps();
18822    _.setupInfinite();
18823    _.buildArrows();
18824    _.updateArrows();
18825    _.initArrowEvents();
18826    _.buildDots();
18827    _.updateDots();
18828    _.initDotEvents();
18829    _.cleanUpSlideEvents();
18830    _.initSlideEvents();
18831    _.checkResponsive(false, true);
18832    if (_.options.focusOnSelect === true) {
18833      $(_.$slideTrack).children().on('click.slick', _.selectHandler);
18834    }
18835    _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
18836    _.setPosition();
18837    _.focusHandler();
18838    _.paused = !_.options.autoplay;
18839    _.autoPlay();
18840    _.$slider.trigger('reInit', [_]);
18841  };
18842  Slick.prototype.resize = function () {
18843    var _ = this;
18844    if ($(window).width() !== _.windowWidth) {
18845      clearTimeout(_.windowDelay);
18846      _.windowDelay = window.setTimeout(function () {
18847        _.windowWidth = $(window).width();
18848        _.checkResponsive();
18849        if (!_.unslicked) {
18850          _.setPosition();
18851        }
18852      }, 50);
18853    }
18854  };
18855  Slick.prototype.removeSlide = Slick.prototype.slickRemove = function (index, removeBefore, removeAll) {
18856    var _ = this;
18857    if (typeof index === 'boolean') {
18858      removeBefore = index;
18859      index = removeBefore === true ? 0 : _.slideCount - 1;
18860    } else {
18861      index = removeBefore === true ? --index : index;
18862    }
18863    if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
18864      return false;
18865    }
18866    _.unload();
18867    if (removeAll === true) {
18868      _.$slideTrack.children().remove();
18869    } else {
18870      _.$slideTrack.children(this.options.slide).eq(index).remove();
18871    }
18872    _.$slides = _.$slideTrack.children(this.options.slide);
18873    _.$slideTrack.children(this.options.slide).detach();
18874    _.$slideTrack.append(_.$slides);
18875    _.$slidesCache = _.$slides;
18876    _.reinit();
18877  };
18878  Slick.prototype.setCSS = function (position) {
18879    var _ = this,
18880      positionProps = {},
18881      x,
18882      y;
18883    if (_.options.rtl === true) {
18884      position = -position;
18885    }
18886    x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
18887    y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
18888    positionProps[_.positionProp] = position;
18889    if (_.transformsEnabled === false) {
18890      _.$slideTrack.css(positionProps);
18891    } else {
18892      positionProps = {};
18893      if (_.cssTransitions === false) {
18894        positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
18895        _.$slideTrack.css(positionProps);
18896      } else {
18897        positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
18898        _.$slideTrack.css(positionProps);
18899      }
18900    }
18901  };
18902  Slick.prototype.setDimensions = function () {
18903    var _ = this;
18904    if (_.options.vertical === false) {
18905      if (_.options.centerMode === true) {
18906        _.$list.css({
18907          padding: '0px ' + _.options.centerPadding
18908        });
18909      }
18910    } else {
18911      _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
18912      if (_.options.centerMode === true) {
18913        _.$list.css({
18914          padding: _.options.centerPadding + ' 0px'
18915        });
18916      }
18917    }
18918    _.listWidth = _.$list.width();
18919    _.listHeight = _.$list.height();
18920    if (_.options.vertical === false && _.options.variableWidth === false) {
18921      _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
18922      _.$slideTrack.width(Math.ceil(_.slideWidth * _.$slideTrack.children('.slick-slide').length));
18923    } else if (_.options.variableWidth === true) {
18924      _.$slideTrack.width(5000 * _.slideCount);
18925    } else {
18926      _.slideWidth = Math.ceil(_.listWidth);
18927      _.$slideTrack.height(Math.ceil(_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length));
18928    }
18929    var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
18930    if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
18931  };
18932  Slick.prototype.setFade = function () {
18933    var _ = this,
18934      targetLeft;
18935    _.$slides.each(function (index, element) {
18936      targetLeft = _.slideWidth * index * -1;
18937      if (_.options.rtl === true) {
18938        $(element).css({
18939          position: 'relative',
18940          right: targetLeft,
18941          top: 0,
18942          zIndex: _.options.zIndex - 2,
18943          opacity: 0
18944        });
18945      } else {
18946        $(element).css({
18947          position: 'relative',
18948          left: targetLeft,
18949          top: 0,
18950          zIndex: _.options.zIndex - 2,
18951          opacity: 0
18952        });
18953      }
18954    });
18955    _.$slides.eq(_.currentSlide).css({
18956      zIndex: _.options.zIndex - 1,
18957      opacity: 1
18958    });
18959  };
18960  Slick.prototype.setHeight = function () {
18961    var _ = this;
18962    if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
18963      var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
18964      _.$list.css('height', targetHeight);
18965    }
18966  };
18967  Slick.prototype.setOption = Slick.prototype.slickSetOption = function () {
18968    /**
18969     * accepts arguments in format of:
18970     *
18971     *  - for changing a single option's value:
18972     *     .slick("setOption", option, value, refresh )
18973     *
18974     *  - for changing a set of responsive options:
18975     *     .slick("setOption", 'responsive', [{}, ...], refresh )
18976     *
18977     *  - for updating multiple values at once (not responsive)
18978     *     .slick("setOption", { 'option': value, ... }, refresh )
18979     */
18980
18981    var _ = this,
18982      l,
18983      item,
18984      option,
18985      value,
18986      refresh = false,
18987      type;
18988    if ($.type(arguments[0]) === 'object') {
18989      option = arguments[0];
18990      refresh = arguments[1];
18991      type = 'multiple';
18992    } else if ($.type(arguments[0]) === 'string') {
18993      option = arguments[0];
18994      value = arguments[1];
18995      refresh = arguments[2];
18996      if (arguments[0] === 'responsive' && $.type(arguments[1]) === 'array') {
18997        type = 'responsive';
18998      } else if (typeof arguments[1] !== 'undefined') {
18999        type = 'single';
19000      }
19001    }
19002    if (type === 'single') {
19003      _.options[option] = value;
19004    } else if (type === 'multiple') {
19005      $.each(option, function (opt, val) {
19006        _.options[opt] = val;
19007      });
19008    } else if (type === 'responsive') {
19009      for (item in value) {
19010        if ($.type(_.options.responsive) !== 'array') {
19011          _.options.responsive = [value[item]];
19012        } else {
19013          l = _.options.responsive.length - 1;
19014
19015          // loop through the responsive object and splice out duplicates.
19016          while (l >= 0) {
19017            if (_.options.responsive[l].breakpoint === value[item].breakpoint) {
19018              _.options.responsive.splice(l, 1);
19019            }
19020            l--;
19021          }
19022          _.options.responsive.push(value[item]);
19023        }
19024      }
19025    }
19026    if (refresh) {
19027      _.unload();
19028      _.reinit();
19029    }
19030  };
19031  Slick.prototype.setPosition = function () {
19032    var _ = this;
19033    _.setDimensions();
19034    _.setHeight();
19035    if (_.options.fade === false) {
19036      _.setCSS(_.getLeft(_.currentSlide));
19037    } else {
19038      _.setFade();
19039    }
19040    _.$slider.trigger('setPosition', [_]);
19041  };
19042  Slick.prototype.setProps = function () {
19043    var _ = this,
19044      bodyStyle = document.body.style;
19045    _.positionProp = _.options.vertical === true ? 'top' : 'left';
19046    if (_.positionProp === 'top') {
19047      _.$slider.addClass('slick-vertical');
19048    } else {
19049      _.$slider.removeClass('slick-vertical');
19050    }
19051    if (bodyStyle.WebkitTransition !== undefined || bodyStyle.MozTransition !== undefined || bodyStyle.msTransition !== undefined) {
19052      if (_.options.useCSS === true) {
19053        _.cssTransitions = true;
19054      }
19055    }
19056    if (_.options.fade) {
19057      if (typeof _.options.zIndex === 'number') {
19058        if (_.options.zIndex < 3) {
19059          _.options.zIndex = 3;
19060        }
19061      } else {
19062        _.options.zIndex = _.defaults.zIndex;
19063      }
19064    }
19065    if (bodyStyle.OTransform !== undefined) {
19066      _.animType = 'OTransform';
19067      _.transformType = '-o-transform';
19068      _.transitionType = 'OTransition';
19069      if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
19070    }
19071    if (bodyStyle.MozTransform !== undefined) {
19072      _.animType = 'MozTransform';
19073      _.transformType = '-moz-transform';
19074      _.transitionType = 'MozTransition';
19075      if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
19076    }
19077    if (bodyStyle.webkitTransform !== undefined) {
19078      _.animType = 'webkitTransform';
19079      _.transformType = '-webkit-transform';
19080      _.transitionType = 'webkitTransition';
19081      if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
19082    }
19083    if (bodyStyle.msTransform !== undefined) {
19084      _.animType = 'msTransform';
19085      _.transformType = '-ms-transform';
19086      _.transitionType = 'msTransition';
19087      if (bodyStyle.msTransform === undefined) _.animType = false;
19088    }
19089    if (bodyStyle.transform !== undefined && _.animType !== false) {
19090      _.animType = 'transform';
19091      _.transformType = 'transform';
19092      _.transitionType = 'transition';
19093    }
19094    _.transformsEnabled = _.options.useTransform && _.animType !== null && _.animType !== false;
19095  };
19096  Slick.prototype.setSlideClasses = function (index) {
19097    var _ = this,
19098      centerOffset,
19099      allSlides,
19100      indexOffset,
19101      remainder;
19102    allSlides = _.$slider.find('.slick-slide').removeClass('slick-active slick-center slick-current').attr('aria-hidden', 'true');
19103    _.$slides.eq(index).addClass('slick-current');
19104    if (_.options.centerMode === true) {
19105      centerOffset = Math.floor(_.options.slidesToShow / 2);
19106      if (_.options.infinite === true) {
19107        if (index >= centerOffset && index <= _.slideCount - 1 - centerOffset) {
19108          _.$slides.slice(index - centerOffset, index + centerOffset + 1).addClass('slick-active').attr('aria-hidden', 'false');
19109        } else {
19110          indexOffset = _.options.slidesToShow + index;
19111          allSlides.slice(indexOffset - centerOffset + 1, indexOffset + centerOffset + 2).addClass('slick-active').attr('aria-hidden', 'false');
19112        }
19113        if (index === 0) {
19114          allSlides.eq(allSlides.length - 1 - _.options.slidesToShow).addClass('slick-center');
19115        } else if (index === _.slideCount - 1) {
19116          allSlides.eq(_.options.slidesToShow).addClass('slick-center');
19117        }
19118      }
19119      _.$slides.eq(index).addClass('slick-center');
19120    } else {
19121      if (index >= 0 && index <= _.slideCount - _.options.slidesToShow) {
19122        _.$slides.slice(index, index + _.options.slidesToShow).addClass('slick-active').attr('aria-hidden', 'false');
19123      } else if (allSlides.length <= _.options.slidesToShow) {
19124        allSlides.addClass('slick-active').attr('aria-hidden', 'false');
19125      } else {
19126        remainder = _.slideCount % _.options.slidesToShow;
19127        indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
19128        if (_.options.slidesToShow == _.options.slidesToScroll && _.slideCount - index < _.options.slidesToShow) {
19129          allSlides.slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder).addClass('slick-active').attr('aria-hidden', 'false');
19130        } else {
19131          allSlides.slice(indexOffset, indexOffset + _.options.slidesToShow).addClass('slick-active').attr('aria-hidden', 'false');
19132        }
19133      }
19134    }
19135    if (_.options.lazyLoad === 'ondemand') {
19136      _.lazyLoad();
19137    }
19138  };
19139  Slick.prototype.setupInfinite = function () {
19140    var _ = this,
19141      i,
19142      slideIndex,
19143      infiniteCount;
19144    if (_.options.fade === true) {
19145      _.options.centerMode = false;
19146    }
19147    if (_.options.infinite === true && _.options.fade === false) {
19148      slideIndex = null;
19149      if (_.slideCount > _.options.slidesToShow) {
19150        if (_.options.centerMode === true) {
19151          infiniteCount = _.options.slidesToShow + 1;
19152        } else {
19153          infiniteCount = _.options.slidesToShow;
19154        }
19155        for (i = _.slideCount; i > _.slideCount - infiniteCount; i -= 1) {
19156          slideIndex = i - 1;
19157          $(_.$slides[slideIndex]).clone(true).attr('id', '').attr('data-slick-index', slideIndex - _.slideCount).prependTo(_.$slideTrack).addClass('slick-cloned');
19158        }
19159        for (i = 0; i < infiniteCount; i += 1) {
19160          slideIndex = i;
19161          $(_.$slides[slideIndex]).clone(true).attr('id', '').attr('data-slick-index', slideIndex + _.slideCount).appendTo(_.$slideTrack).addClass('slick-cloned');
19162        }
19163        _.$slideTrack.find('.slick-cloned').find('[id]').each(function () {
19164          $(this).attr('id', '');
19165        });
19166      }
19167    }
19168  };
19169  Slick.prototype.interrupt = function (toggle) {
19170    var _ = this;
19171    if (!toggle) {
19172      _.autoPlay();
19173    }
19174    _.interrupted = toggle;
19175  };
19176  Slick.prototype.selectHandler = function (event) {
19177    var _ = this;
19178    var targetElement = $(event.target).is('.slick-slide') ? $(event.target) : $(event.target).parents('.slick-slide');
19179    var index = parseInt(targetElement.attr('data-slick-index'));
19180    if (!index) index = 0;
19181    if (_.slideCount <= _.options.slidesToShow) {
19182      _.setSlideClasses(index);
19183      _.asNavFor(index);
19184      return;
19185    }
19186    _.slideHandler(index);
19187  };
19188  Slick.prototype.slideHandler = function (index, sync, dontAnimate) {
19189    var targetSlide,
19190      animSlide,
19191      oldSlide,
19192      slideLeft,
19193      targetLeft = null,
19194      _ = this,
19195      navTarget;
19196    sync = sync || false;
19197    if (_.animating === true && _.options.waitForAnimate === true) {
19198      return;
19199    }
19200    if (_.options.fade === true && _.currentSlide === index) {
19201      return;
19202    }
19203    if (_.slideCount <= _.options.slidesToShow) {
19204      return;
19205    }
19206    if (sync === false) {
19207      _.asNavFor(index);
19208    }
19209    targetSlide = index;
19210    targetLeft = _.getLeft(targetSlide);
19211    slideLeft = _.getLeft(_.currentSlide);
19212    _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
19213    if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
19214      if (_.options.fade === false) {
19215        targetSlide = _.currentSlide;
19216        if (dontAnimate !== true) {
19217          _.animateSlide(slideLeft, function () {
19218            _.postSlide(targetSlide);
19219          });
19220        } else {
19221          _.postSlide(targetSlide);
19222        }
19223      }
19224      return;
19225    } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > _.slideCount - _.options.slidesToScroll)) {
19226      if (_.options.fade === false) {
19227        targetSlide = _.currentSlide;
19228        if (dontAnimate !== true) {
19229          _.animateSlide(slideLeft, function () {
19230            _.postSlide(targetSlide);
19231          });
19232        } else {
19233          _.postSlide(targetSlide);
19234        }
19235      }
19236      return;
19237    }
19238    if (_.options.autoplay) {
19239      clearInterval(_.autoPlayTimer);
19240    }
19241    if (targetSlide < 0) {
19242      if (_.slideCount % _.options.slidesToScroll !== 0) {
19243        animSlide = _.slideCount - _.slideCount % _.options.slidesToScroll;
19244      } else {
19245        animSlide = _.slideCount + targetSlide;
19246      }
19247    } else if (targetSlide >= _.slideCount) {
19248      if (_.slideCount % _.options.slidesToScroll !== 0) {
19249        animSlide = 0;
19250      } else {
19251        animSlide = targetSlide - _.slideCount;
19252      }
19253    } else {
19254      animSlide = targetSlide;
19255    }
19256    _.animating = true;
19257    _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
19258    oldSlide = _.currentSlide;
19259    _.currentSlide = animSlide;
19260    _.setSlideClasses(_.currentSlide);
19261    if (_.options.asNavFor) {
19262      navTarget = _.getNavTarget();
19263      navTarget = navTarget.slick('getSlick');
19264      if (navTarget.slideCount <= navTarget.options.slidesToShow) {
19265        navTarget.setSlideClasses(_.currentSlide);
19266      }
19267    }
19268    _.updateDots();
19269    _.updateArrows();
19270    if (_.options.fade === true) {
19271      if (dontAnimate !== true) {
19272        _.fadeSlideOut(oldSlide);
19273        _.fadeSlide(animSlide, function () {
19274          _.postSlide(animSlide);
19275        });
19276      } else {
19277        _.postSlide(animSlide);
19278      }
19279      _.animateHeight();
19280      return;
19281    }
19282    if (dontAnimate !== true) {
19283      _.animateSlide(targetLeft, function () {
19284        _.postSlide(animSlide);
19285      });
19286    } else {
19287      _.postSlide(animSlide);
19288    }
19289  };
19290  Slick.prototype.startLoad = function () {
19291    var _ = this;
19292    if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
19293      _.$prevArrow.hide();
19294      _.$nextArrow.hide();
19295    }
19296    if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
19297      _.$dots.hide();
19298    }
19299    _.$slider.addClass('slick-loading');
19300  };
19301  Slick.prototype.swipeDirection = function () {
19302    var xDist,
19303      yDist,
19304      r,
19305      swipeAngle,
19306      _ = this;
19307    xDist = _.touchObject.startX - _.touchObject.curX;
19308    yDist = _.touchObject.startY - _.touchObject.curY;
19309    r = Math.atan2(yDist, xDist);
19310    swipeAngle = Math.round(r * 180 / Math.PI);
19311    if (swipeAngle < 0) {
19312      swipeAngle = 360 - Math.abs(swipeAngle);
19313    }
19314    if (swipeAngle <= 45 && swipeAngle >= 0) {
19315      return _.options.rtl === false ? 'left' : 'right';
19316    }
19317    if (swipeAngle <= 360 && swipeAngle >= 315) {
19318      return _.options.rtl === false ? 'left' : 'right';
19319    }
19320    if (swipeAngle >= 135 && swipeAngle <= 225) {
19321      return _.options.rtl === false ? 'right' : 'left';
19322    }
19323    if (_.options.verticalSwiping === true) {
19324      if (swipeAngle >= 35 && swipeAngle <= 135) {
19325        return 'down';
19326      } else {
19327        return 'up';
19328      }
19329    }
19330    return 'vertical';
19331  };
19332  Slick.prototype.swipeEnd = function (event) {
19333    var _ = this,
19334      slideCount,
19335      direction;
19336    _.dragging = false;
19337    _.interrupted = false;
19338    _.shouldClick = _.touchObject.swipeLength > 10 ? false : true;
19339    if (_.touchObject.curX === undefined) {
19340      return false;
19341    }
19342    if (_.touchObject.edgeHit === true) {
19343      _.$slider.trigger('edge', [_, _.swipeDirection()]);
19344    }
19345    if (_.touchObject.swipeLength >= _.touchObject.minSwipe) {
19346      direction = _.swipeDirection();
19347      switch (direction) {
19348        case 'left':
19349        case 'down':
19350          slideCount = _.options.swipeToSlide ? _.checkNavigable(_.currentSlide + _.getSlideCount()) : _.currentSlide + _.getSlideCount();
19351          _.currentDirection = 0;
19352          break;
19353        case 'right':
19354        case 'up':
19355          slideCount = _.options.swipeToSlide ? _.checkNavigable(_.currentSlide - _.getSlideCount()) : _.currentSlide - _.getSlideCount();
19356          _.currentDirection = 1;
19357          break;
19358        default:
19359      }
19360      if (direction != 'vertical') {
19361        _.slideHandler(slideCount);
19362        _.touchObject = {};
19363        _.$slider.trigger('swipe', [_, direction]);
19364      }
19365    } else {
19366      if (_.touchObject.startX !== _.touchObject.curX) {
19367        _.slideHandler(_.currentSlide);
19368        _.touchObject = {};
19369      }
19370    }
19371  };
19372  Slick.prototype.swipeHandler = function (event) {
19373    var _ = this;
19374    if (_.options.swipe === false || 'ontouchend' in document && _.options.swipe === false) {
19375      return;
19376    } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
19377      return;
19378    }
19379    _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ? event.originalEvent.touches.length : 1;
19380    _.touchObject.minSwipe = _.listWidth / _.options.touchThreshold;
19381    if (_.options.verticalSwiping === true) {
19382      _.touchObject.minSwipe = _.listHeight / _.options.touchThreshold;
19383    }
19384    switch (event.data.action) {
19385      case 'start':
19386        _.swipeStart(event);
19387        break;
19388      case 'move':
19389        _.swipeMove(event);
19390        break;
19391      case 'end':
19392        _.swipeEnd(event);
19393        break;
19394    }
19395  };
19396  Slick.prototype.swipeMove = function (event) {
19397    var _ = this,
19398      edgeWasHit = false,
19399      curLeft,
19400      swipeDirection,
19401      swipeLength,
19402      positionOffset,
19403      touches;
19404    touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
19405    if (!_.dragging || touches && touches.length !== 1) {
19406      return false;
19407    }
19408    curLeft = _.getLeft(_.currentSlide);
19409    _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
19410    _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
19411    _.touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
19412    if (_.options.verticalSwiping === true) {
19413      _.touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
19414    }
19415    swipeDirection = _.swipeDirection();
19416    if (swipeDirection === 'vertical') {
19417      return;
19418    }
19419    if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
19420      event.preventDefault();
19421    }
19422    positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
19423    if (_.options.verticalSwiping === true) {
19424      positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
19425    }
19426    swipeLength = _.touchObject.swipeLength;
19427    _.touchObject.edgeHit = false;
19428    if (_.options.infinite === false) {
19429      if (_.currentSlide === 0 && swipeDirection === 'right' || _.currentSlide >= _.getDotCount() && swipeDirection === 'left') {
19430        swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
19431        _.touchObject.edgeHit = true;
19432      }
19433    }
19434    if (_.options.vertical === false) {
19435      _.swipeLeft = curLeft + swipeLength * positionOffset;
19436    } else {
19437      _.swipeLeft = curLeft + swipeLength * (_.$list.height() / _.listWidth) * positionOffset;
19438    }
19439    if (_.options.verticalSwiping === true) {
19440      _.swipeLeft = curLeft + swipeLength * positionOffset;
19441    }
19442    if (_.options.fade === true || _.options.touchMove === false) {
19443      return false;
19444    }
19445    if (_.animating === true) {
19446      _.swipeLeft = null;
19447      return false;
19448    }
19449    _.setCSS(_.swipeLeft);
19450  };
19451  Slick.prototype.swipeStart = function (event) {
19452    var _ = this,
19453      touches;
19454    _.interrupted = true;
19455    if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
19456      _.touchObject = {};
19457      return false;
19458    }
19459    if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
19460      touches = event.originalEvent.touches[0];
19461    }
19462    _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
19463    _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
19464    _.dragging = true;
19465  };
19466  Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function () {
19467    var _ = this;
19468    if (_.$slidesCache !== null) {
19469      _.unload();
19470      _.$slideTrack.children(this.options.slide).detach();
19471      _.$slidesCache.appendTo(_.$slideTrack);
19472      _.reinit();
19473    }
19474  };
19475  Slick.prototype.unload = function () {
19476    var _ = this;
19477    $('.slick-cloned', _.$slider).remove();
19478    if (_.$dots) {
19479      _.$dots.remove();
19480    }
19481    if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
19482      _.$prevArrow.remove();
19483    }
19484    if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
19485      _.$nextArrow.remove();
19486    }
19487    _.$slides.removeClass('slick-slide slick-active slick-visible slick-current').attr('aria-hidden', 'true').css('width', '');
19488  };
19489  Slick.prototype.unslick = function (fromBreakpoint) {
19490    var _ = this;
19491    _.$slider.trigger('unslick', [_, fromBreakpoint]);
19492    _.destroy();
19493  };
19494  Slick.prototype.updateArrows = function () {
19495    var _ = this,
19496      centerOffset;
19497    centerOffset = Math.floor(_.options.slidesToShow / 2);
19498    if (_.options.arrows === true && _.slideCount > _.options.slidesToShow && !_.options.infinite) {
19499      _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
19500      _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
19501      if (_.currentSlide === 0) {
19502        _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
19503        _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
19504      } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
19505        _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
19506        _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
19507      } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
19508        _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
19509        _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
19510      }
19511    }
19512  };
19513  Slick.prototype.updateDots = function () {
19514    var _ = this;
19515    if (_.$dots !== null) {
19516      _.$dots.find('li').removeClass('slick-active').attr('aria-hidden', 'true');
19517      _.$dots.find('li').eq(Math.floor(_.currentSlide / _.options.slidesToScroll)).addClass('slick-active').attr('aria-hidden', 'false');
19518    }
19519  };
19520  Slick.prototype.visibility = function () {
19521    var _ = this;
19522    if (_.options.autoplay) {
19523      if (document[_.hidden]) {
19524        _.interrupted = true;
19525      } else {
19526        _.interrupted = false;
19527      }
19528    }
19529  };
19530  $.fn.slick = function () {
19531    var _ = this,
19532      opt = arguments[0],
19533      args = Array.prototype.slice.call(arguments, 1),
19534      l = _.length,
19535      i,
19536      ret;
19537    for (i = 0; i < l; i++) {
19538      if (_typeof(opt) == 'object' || typeof opt == 'undefined') _[i].slick = new Slick(_[i], opt);else ret = _[i].slick[opt].apply(_[i].slick, args);
19539      if (typeof ret != 'undefined') return ret;
19540    }
19541    return _;
19542  };
19543});
19544
19545}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
19546},{}],8:[function(require,module,exports){
19547(function (global){(function (){
19548"use strict";
19549
19550function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
19551(function (global, factory) {
19552  (typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define('underscore', factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, function () {
19553    var current = global._;
19554    var exports = global._ = factory();
19555    exports.noConflict = function () {
19556      global._ = current;
19557      return exports;
19558    };
19559  }());
19560})(void 0, function () {
19561  //     Underscore.js 1.13.7
19562  //     https://underscorejs.org
19563  //     (c) 2009-2024 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
19564  //     Underscore may be freely distributed under the MIT license.
19565
19566  // Current version.
19567  var VERSION = '1.13.7';
19568
19569  // Establish the root object, `window` (`self`) in the browser, `global`
19570  // on the server, or `this` in some virtual machines. We use `self`
19571  // instead of `window` for `WebWorker` support.
19572  var root = (typeof self === "undefined" ? "undefined" : _typeof(self)) == 'object' && self.self === self && self || (typeof global === "undefined" ? "undefined" : _typeof(global)) == 'object' && global.global === global && global || Function('return this')() || {};
19573
19574  // Save bytes in the minified (but not gzipped) version:
19575  var ArrayProto = Array.prototype,
19576    ObjProto = Object.prototype;
19577  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
19578
19579  // Create quick reference variables for speed access to core prototypes.
19580  var push = ArrayProto.push,
19581    slice = ArrayProto.slice,
19582    toString = ObjProto.toString,
19583    hasOwnProperty = ObjProto.hasOwnProperty;
19584
19585  // Modern feature detection.
19586  var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',
19587    supportsDataView = typeof DataView !== 'undefined';
19588
19589  // All **ECMAScript 5+** native function implementations that we hope to use
19590  // are declared here.
19591  var nativeIsArray = Array.isArray,
19592    nativeKeys = Object.keys,
19593    nativeCreate = Object.create,
19594    nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;
19595
19596  // Create references to these builtin functions because we override them.
19597  var _isNaN = isNaN,
19598    _isFinite = isFinite;
19599
19600  // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
19601  var hasEnumBug = !{
19602    toString: null
19603  }.propertyIsEnumerable('toString');
19604  var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
19605
19606  // The largest integer that can be represented exactly.
19607  var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
19608
19609  // Some functions take a variable number of arguments, or a few expected
19610  // arguments at the beginning and then a variable number of values to operate
19611  // on. This helper accumulates all remaining arguments past the function’s
19612  // argument length (or an explicit `startIndex`), into an array that becomes
19613  // the last argument. Similar to ES6’s "rest parameter".
19614  function restArguments(func, startIndex) {
19615    startIndex = startIndex == null ? func.length - 1 : +startIndex;
19616    return function () {
19617      var length = Math.max(arguments.length - startIndex, 0),
19618        rest = Array(length),
19619        index = 0;
19620      for (; index < length; index++) {
19621        rest[index] = arguments[index + startIndex];
19622      }
19623      switch (startIndex) {
19624        case 0:
19625          return func.call(this, rest);
19626        case 1:
19627          return func.call(this, arguments[0], rest);
19628        case 2:
19629          return func.call(this, arguments[0], arguments[1], rest);
19630      }
19631      var args = Array(startIndex + 1);
19632      for (index = 0; index < startIndex; index++) {
19633        args[index] = arguments[index];
19634      }
19635      args[startIndex] = rest;
19636      return func.apply(this, args);
19637    };
19638  }
19639
19640  // Is a given variable an object?
19641  function isObject(obj) {
19642    var type = _typeof(obj);
19643    return type === 'function' || type === 'object' && !!obj;
19644  }
19645
19646  // Is a given value equal to null?
19647  function isNull(obj) {
19648    return obj === null;
19649  }
19650
19651  // Is a given variable undefined?
19652  function isUndefined(obj) {
19653    return obj === void 0;
19654  }
19655
19656  // Is a given value a boolean?
19657  function isBoolean(obj) {
19658    return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
19659  }
19660
19661  // Is a given value a DOM element?
19662  function isElement(obj) {
19663    return !!(obj && obj.nodeType === 1);
19664  }
19665
19666  // Internal function for creating a `toString`-based type tester.
19667  function tagTester(name) {
19668    var tag = '[object ' + name + ']';
19669    return function (obj) {
19670      return toString.call(obj) === tag;
19671    };
19672  }
19673  var isString = tagTester('String');
19674  var isNumber = tagTester('Number');
19675  var isDate = tagTester('Date');
19676  var isRegExp = tagTester('RegExp');
19677  var isError = tagTester('Error');
19678  var isSymbol = tagTester('Symbol');
19679  var isArrayBuffer = tagTester('ArrayBuffer');
19680  var isFunction = tagTester('Function');
19681
19682  // Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old
19683  // v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
19684  var nodelist = root.document && root.document.childNodes;
19685  if (typeof /./ != 'function' && (typeof Int8Array === "undefined" ? "undefined" : _typeof(Int8Array)) != 'object' && typeof nodelist != 'function') {
19686    isFunction = function isFunction(obj) {
19687      return typeof obj == 'function' || false;
19688    };
19689  }
19690  var isFunction$1 = isFunction;
19691  var hasObjectTag = tagTester('Object');
19692
19693  // In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
19694  // In IE 11, the most common among them, this problem also applies to
19695  // `Map`, `WeakMap` and `Set`.
19696  // Also, there are cases where an application can override the native
19697  // `DataView` object, in cases like that we can't use the constructor
19698  // safely and should just rely on alternate `DataView` checks
19699  var hasDataViewBug = supportsDataView && (!/\[native code\]/.test(String(DataView)) || hasObjectTag(new DataView(new ArrayBuffer(8)))),
19700    isIE11 = typeof Map !== 'undefined' && hasObjectTag(new Map());
19701  var isDataView = tagTester('DataView');
19702
19703  // In IE 10 - Edge 13, we need a different heuristic
19704  // to determine whether an object is a `DataView`.
19705  // Also, in cases where the native `DataView` is
19706  // overridden we can't rely on the tag itself.
19707  function alternateIsDataView(obj) {
19708    return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);
19709  }
19710  var isDataView$1 = hasDataViewBug ? alternateIsDataView : isDataView;
19711
19712  // Is a given value an array?
19713  // Delegates to ECMA5's native `Array.isArray`.
19714  var isArray = nativeIsArray || tagTester('Array');
19715
19716  // Internal function to check whether `key` is an own property name of `obj`.
19717  function has$1(obj, key) {
19718    return obj != null && hasOwnProperty.call(obj, key);
19719  }
19720  var isArguments = tagTester('Arguments');
19721
19722  // Define a fallback version of the method in browsers (ahem, IE < 9), where
19723  // there isn't any inspectable "Arguments" type.
19724  (function () {
19725    if (!isArguments(arguments)) {
19726      isArguments = function isArguments(obj) {
19727        return has$1(obj, 'callee');
19728      };
19729    }
19730  })();
19731  var isArguments$1 = isArguments;
19732
19733  // Is a given object a finite number?
19734  function isFinite$1(obj) {
19735    return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));
19736  }
19737
19738  // Is the given value `NaN`?
19739  function isNaN$1(obj) {
19740    return isNumber(obj) && _isNaN(obj);
19741  }
19742
19743  // Predicate-generating function. Often useful outside of Underscore.
19744  function constant(value) {
19745    return function () {
19746      return value;
19747    };
19748  }
19749
19750  // Common internal logic for `isArrayLike` and `isBufferLike`.
19751  function createSizePropertyCheck(getSizeProperty) {
19752    return function (collection) {
19753      var sizeProperty = getSizeProperty(collection);
19754      return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;
19755    };
19756  }
19757
19758  // Internal helper to generate a function to obtain property `key` from `obj`.
19759  function shallowProperty(key) {
19760    return function (obj) {
19761      return obj == null ? void 0 : obj[key];
19762    };
19763  }
19764
19765  // Internal helper to obtain the `byteLength` property of an object.
19766  var getByteLength = shallowProperty('byteLength');
19767
19768  // Internal helper to determine whether we should spend extensive checks against
19769  // `ArrayBuffer` et al.
19770  var isBufferLike = createSizePropertyCheck(getByteLength);
19771
19772  // Is a given value a typed array?
19773  var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;
19774  function isTypedArray(obj) {
19775    // `ArrayBuffer.isView` is the most future-proof, so use it when available.
19776    // Otherwise, fall back on the above regular expression.
19777    return nativeIsView ? nativeIsView(obj) && !isDataView$1(obj) : isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));
19778  }
19779  var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant(false);
19780
19781  // Internal helper to obtain the `length` property of an object.
19782  var getLength = shallowProperty('length');
19783
19784  // Internal helper to create a simple lookup structure.
19785  // `collectNonEnumProps` used to depend on `_.contains`, but this led to
19786  // circular imports. `emulatedSet` is a one-off solution that only works for
19787  // arrays of strings.
19788  function emulatedSet(keys) {
19789    var hash = {};
19790    for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;
19791    return {
19792      contains: function contains(key) {
19793        return hash[key] === true;
19794      },
19795      push: function push(key) {
19796        hash[key] = true;
19797        return keys.push(key);
19798      }
19799    };
19800  }
19801
19802  // Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
19803  // be iterated by `for key in ...` and thus missed. Extends `keys` in place if
19804  // needed.
19805  function collectNonEnumProps(obj, keys) {
19806    keys = emulatedSet(keys);
19807    var nonEnumIdx = nonEnumerableProps.length;
19808    var constructor = obj.constructor;
19809    var proto = isFunction$1(constructor) && constructor.prototype || ObjProto;
19810
19811    // Constructor is a special case.
19812    var prop = 'constructor';
19813    if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);
19814    while (nonEnumIdx--) {
19815      prop = nonEnumerableProps[nonEnumIdx];
19816      if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
19817        keys.push(prop);
19818      }
19819    }
19820  }
19821
19822  // Retrieve the names of an object's own properties.
19823  // Delegates to **ECMAScript 5**'s native `Object.keys`.
19824  function keys(obj) {
19825    if (!isObject(obj)) return [];
19826    if (nativeKeys) return nativeKeys(obj);
19827    var keys = [];
19828    for (var key in obj) if (has$1(obj, key)) keys.push(key);
19829    // Ahem, IE < 9.
19830    if (hasEnumBug) collectNonEnumProps(obj, keys);
19831    return keys;
19832  }
19833
19834  // Is a given array, string, or object empty?
19835  // An "empty" object has no enumerable own-properties.
19836  function isEmpty(obj) {
19837    if (obj == null) return true;
19838    // Skip the more expensive `toString`-based type checks if `obj` has no
19839    // `.length`.
19840    var length = getLength(obj);
19841    if (typeof length == 'number' && (isArray(obj) || isString(obj) || isArguments$1(obj))) return length === 0;
19842    return getLength(keys(obj)) === 0;
19843  }
19844
19845  // Returns whether an object has a given set of `key:value` pairs.
19846  function isMatch(object, attrs) {
19847    var _keys = keys(attrs),
19848      length = _keys.length;
19849    if (object == null) return !length;
19850    var obj = Object(object);
19851    for (var i = 0; i < length; i++) {
19852      var key = _keys[i];
19853      if (attrs[key] !== obj[key] || !(key in obj)) return false;
19854    }
19855    return true;
19856  }
19857
19858  // If Underscore is called as a function, it returns a wrapped object that can
19859  // be used OO-style. This wrapper holds altered versions of all functions added
19860  // through `_.mixin`. Wrapped objects may be chained.
19861  function _$1(obj) {
19862    if (obj instanceof _$1) return obj;
19863    if (!(this instanceof _$1)) return new _$1(obj);
19864    this._wrapped = obj;
19865  }
19866  _$1.VERSION = VERSION;
19867
19868  // Extracts the result from a wrapped and chained object.
19869  _$1.prototype.value = function () {
19870    return this._wrapped;
19871  };
19872
19873  // Provide unwrapping proxies for some methods used in engine operations
19874  // such as arithmetic and JSON stringification.
19875  _$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;
19876  _$1.prototype.toString = function () {
19877    return String(this._wrapped);
19878  };
19879
19880  // Internal function to wrap or shallow-copy an ArrayBuffer,
19881  // typed array or DataView to a new view, reusing the buffer.
19882  function toBufferView(bufferSource) {
19883    return new Uint8Array(bufferSource.buffer || bufferSource, bufferSource.byteOffset || 0, getByteLength(bufferSource));
19884  }
19885
19886  // We use this string twice, so give it a name for minification.
19887  var tagDataView = '[object DataView]';
19888
19889  // Internal recursive comparison function for `_.isEqual`.
19890  function eq(a, b, aStack, bStack) {
19891    // Identical objects are equal. `0 === -0`, but they aren't identical.
19892    // See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).
19893    if (a === b) return a !== 0 || 1 / a === 1 / b;
19894    // `null` or `undefined` only equal to itself (strict comparison).
19895    if (a == null || b == null) return false;
19896    // `NaN`s are equivalent, but non-reflexive.
19897    if (a !== a) return b !== b;
19898    // Exhaust primitive checks
19899    var type = _typeof(a);
19900    if (type !== 'function' && type !== 'object' && _typeof(b) != 'object') return false;
19901    return deepEq(a, b, aStack, bStack);
19902  }
19903
19904  // Internal recursive comparison function for `_.isEqual`.
19905  function deepEq(a, b, aStack, bStack) {
19906    // Unwrap any wrapped objects.
19907    if (a instanceof _$1) a = a._wrapped;
19908    if (b instanceof _$1) b = b._wrapped;
19909    // Compare `[[Class]]` names.
19910    var className = toString.call(a);
19911    if (className !== toString.call(b)) return false;
19912    // Work around a bug in IE 10 - Edge 13.
19913    if (hasDataViewBug && className == '[object Object]' && isDataView$1(a)) {
19914      if (!isDataView$1(b)) return false;
19915      className = tagDataView;
19916    }
19917    switch (className) {
19918      // These types are compared by value.
19919      case '[object RegExp]':
19920      // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
19921      case '[object String]':
19922        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
19923        // equivalent to `new String("5")`.
19924        return '' + a === '' + b;
19925      case '[object Number]':
19926        // `NaN`s are equivalent, but non-reflexive.
19927        // Object(NaN) is equivalent to NaN.
19928        if (+a !== +a) return +b !== +b;
19929        // An `egal` comparison is performed for other numeric values.
19930        return +a === 0 ? 1 / +a === 1 / b : +a === +b;
19931      case '[object Date]':
19932      case '[object Boolean]':
19933        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
19934        // millisecond representations. Note that invalid dates with millisecond representations
19935        // of `NaN` are not equivalent.
19936        return +a === +b;
19937      case '[object Symbol]':
19938        return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
19939      case '[object ArrayBuffer]':
19940      case tagDataView:
19941        // Coerce to typed array so we can fall through.
19942        return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);
19943    }
19944    var areArrays = className === '[object Array]';
19945    if (!areArrays && isTypedArray$1(a)) {
19946      var byteLength = getByteLength(a);
19947      if (byteLength !== getByteLength(b)) return false;
19948      if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;
19949      areArrays = true;
19950    }
19951    if (!areArrays) {
19952      if (_typeof(a) != 'object' || _typeof(b) != 'object') return false;
19953
19954      // Objects with different constructors are not equivalent, but `Object`s or `Array`s
19955      // from different frames are.
19956      var aCtor = a.constructor,
19957        bCtor = b.constructor;
19958      if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor && isFunction$1(bCtor) && bCtor instanceof bCtor) && 'constructor' in a && 'constructor' in b) {
19959        return false;
19960      }
19961    }
19962    // Assume equality for cyclic structures. The algorithm for detecting cyclic
19963    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
19964
19965    // Initializing stack of traversed objects.
19966    // It's done here since we only need them for objects and arrays comparison.
19967    aStack = aStack || [];
19968    bStack = bStack || [];
19969    var length = aStack.length;
19970    while (length--) {
19971      // Linear search. Performance is inversely proportional to the number of
19972      // unique nested structures.
19973      if (aStack[length] === a) return bStack[length] === b;
19974    }
19975
19976    // Add the first object to the stack of traversed objects.
19977    aStack.push(a);
19978    bStack.push(b);
19979
19980    // Recursively compare objects and arrays.
19981    if (areArrays) {
19982      // Compare array lengths to determine if a deep comparison is necessary.
19983      length = a.length;
19984      if (length !== b.length) return false;
19985      // Deep compare the contents, ignoring non-numeric properties.
19986      while (length--) {
19987        if (!eq(a[length], b[length], aStack, bStack)) return false;
19988      }
19989    } else {
19990      // Deep compare objects.
19991      var _keys = keys(a),
19992        key;
19993      length = _keys.length;
19994      // Ensure that both objects contain the same number of properties before comparing deep equality.
19995      if (keys(b).length !== length) return false;
19996      while (length--) {
19997        // Deep compare each member
19998        key = _keys[length];
19999        if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
vendor: 5,414 bytes, lines 20000-20164
20000      }
20001    }
20002    // Remove the first object from the stack of traversed objects.
20003    aStack.pop();
20004    bStack.pop();
20005    return true;
20006  }
20007
20008  // Perform a deep comparison to check if two objects are equal.
20009  function isEqual(a, b) {
20010    return eq(a, b);
20011  }
20012
20013  // Retrieve all the enumerable property names of an object.
20014  function allKeys(obj) {
20015    if (!isObject(obj)) return [];
20016    var keys = [];
20017    for (var key in obj) keys.push(key);
20018    // Ahem, IE < 9.
20019    if (hasEnumBug) collectNonEnumProps(obj, keys);
20020    return keys;
20021  }
20022
20023  // Since the regular `Object.prototype.toString` type tests don't work for
20024  // some types in IE 11, we use a fingerprinting heuristic instead, based
20025  // on the methods. It's not great, but it's the best we got.
20026  // The fingerprint method lists are defined below.
20027  function ie11fingerprint(methods) {
20028    var length = getLength(methods);
20029    return function (obj) {
20030      if (obj == null) return false;
20031      // `Map`, `WeakMap` and `Set` have no enumerable keys.
20032      var keys = allKeys(obj);
20033      if (getLength(keys)) return false;
20034      for (var i = 0; i < length; i++) {
20035        if (!isFunction$1(obj[methods[i]])) return false;
20036      }
20037      // If we are testing against `WeakMap`, we need to ensure that
20038      // `obj` doesn't have a `forEach` method in order to distinguish
20039      // it from a regular `Map`.
20040      return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);
20041    };
20042  }
20043
20044  // In the interest of compact minification, we write
20045  // each string in the fingerprints only once.
20046  var forEachName = 'forEach',
20047    hasName = 'has',
20048    commonInit = ['clear', 'delete'],
20049    mapTail = ['get', hasName, 'set'];
20050
20051  // `Map`, `WeakMap` and `Set` each have slightly different
20052  // combinations of the above sublists.
20053  var mapMethods = commonInit.concat(forEachName, mapTail),
20054    weakMapMethods = commonInit.concat(mapTail),
20055    setMethods = ['add'].concat(commonInit, forEachName, hasName);
20056  var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');
20057  var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');
20058  var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');
20059  var isWeakSet = tagTester('WeakSet');
20060
20061  // Retrieve the values of an object's properties.
20062  function values(obj) {
20063    var _keys = keys(obj);
20064    var length = _keys.length;
20065    var values = Array(length);
20066    for (var i = 0; i < length; i++) {
20067      values[i] = obj[_keys[i]];
20068    }
20069    return values;
20070  }
20071
20072  // Convert an object into a list of `[key, value]` pairs.
20073  // The opposite of `_.object` with one argument.
20074  function pairs(obj) {
20075    var _keys = keys(obj);
20076    var length = _keys.length;
20077    var pairs = Array(length);
20078    for (var i = 0; i < length; i++) {
20079      pairs[i] = [_keys[i], obj[_keys[i]]];
20080    }
20081    return pairs;
20082  }
20083
20084  // Invert the keys and values of an object. The values must be serializable.
20085  function invert(obj) {
20086    var result = {};
20087    var _keys = keys(obj);
20088    for (var i = 0, length = _keys.length; i < length; i++) {
20089      result[obj[_keys[i]]] = _keys[i];
20090    }
20091    return result;
20092  }
20093
20094  // Return a sorted list of the function names available on the object.
20095  function functions(obj) {
20096    var names = [];
20097    for (var key in obj) {
20098      if (isFunction$1(obj[key])) names.push(key);
20099    }
20100    return names.sort();
20101  }
20102
20103  // An internal function for creating assigner functions.
20104  function createAssigner(keysFunc, defaults) {
20105    return function (obj) {
20106      var length = arguments.length;
20107      if (defaults) obj = Object(obj);
20108      if (length < 2 || obj == null) return obj;
20109      for (var index = 1; index < length; index++) {
20110        var source = arguments[index],
20111          keys = keysFunc(source),
20112          l = keys.length;
20113        for (var i = 0; i < l; i++) {
20114          var key = keys[i];
20115          if (!defaults || obj[key] === void 0) obj[key] = source[key];
20116        }
20117      }
20118      return obj;
20119    };
20120  }
20121
20122  // Extend a given object with all the properties in passed-in object(s).
20123  var extend = createAssigner(allKeys);
20124
20125  // Assigns a given object with all the own properties in the passed-in
20126  // object(s).
20127  // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
20128  var extendOwn = createAssigner(keys);
20129
20130  // Fill in a given object with default properties.
20131  var defaults = createAssigner(allKeys, true);
20132
20133  // Create a naked function reference for surrogate-prototype-swapping.
20134  function ctor() {
20135    return function () {};
20136  }
20137
20138  // An internal function for creating a new object that inherits from another.
20139  function baseCreate(prototype) {
20140    if (!isObject(prototype)) return {};
20141    if (nativeCreate) return nativeCreate(prototype);
20142    var Ctor = ctor();
20143    Ctor.prototype = prototype;
20144    var result = new Ctor();
20145    Ctor.prototype = null;
20146    return result;
20147  }
20148
20149  // Creates an object that inherits from the given prototype object.
20150  // If additional properties are provided then they will be added to the
20151  // created object.
20152  function create(prototype, props) {
20153    var result = baseCreate(prototype);
20154    if (props) extendOwn(result, props);
20155    return result;
20156  }
20157
20158  // Create a (shallow-cloned) duplicate of an object.
20159  function clone(obj) {
20160    if (!isObject(obj)) return obj;
20161    return isArray(obj) ? obj.slice() : extend({}, obj);
20162  }
20163
20164  // Invokes `interceptor` with the `obj` and then returns `obj`.
vendor: 10,353 bytes, lines 20165-20458
20165  // The primary purpose of this method is to "tap into" a method chain, in
20166  // order to perform operations on intermediate results within the chain.
20167  function tap(obj, interceptor) {
20168    interceptor(obj);
20169    return obj;
20170  }
20171
20172  // Normalize a (deep) property `path` to array.
20173  // Like `_.iteratee`, this function can be customized.
20174  function toPath$1(path) {
20175    return isArray(path) ? path : [path];
20176  }
20177  _$1.toPath = toPath$1;
20178
20179  // Internal wrapper for `_.toPath` to enable minification.
20180  // Similar to `cb` for `_.iteratee`.
20181  function toPath(path) {
20182    return _$1.toPath(path);
20183  }
20184
20185  // Internal function to obtain a nested property in `obj` along `path`.
20186  function deepGet(obj, path) {
20187    var length = path.length;
20188    for (var i = 0; i < length; i++) {
20189      if (obj == null) return void 0;
20190      obj = obj[path[i]];
20191    }
20192    return length ? obj : void 0;
20193  }
20194
20195  // Get the value of the (deep) property on `path` from `object`.
20196  // If any property in `path` does not exist or if the value is
20197  // `undefined`, return `defaultValue` instead.
20198  // The `path` is normalized through `_.toPath`.
20199  function get(object, path, defaultValue) {
20200    var value = deepGet(object, toPath(path));
20201    return isUndefined(value) ? defaultValue : value;
20202  }
20203
20204  // Shortcut function for checking if an object has a given property directly on
20205  // itself (in other words, not on a prototype). Unlike the internal `has`
20206  // function, this public version can also traverse nested properties.
20207  function has(obj, path) {
20208    path = toPath(path);
20209    var length = path.length;
20210    for (var i = 0; i < length; i++) {
20211      var key = path[i];
20212      if (!has$1(obj, key)) return false;
20213      obj = obj[key];
20214    }
20215    return !!length;
20216  }
20217
20218  // Keep the identity function around for default iteratees.
20219  function identity(value) {
20220    return value;
20221  }
20222
20223  // Returns a predicate for checking whether an object has a given set of
20224  // `key:value` pairs.
20225  function matcher(attrs) {
20226    attrs = extendOwn({}, attrs);
20227    return function (obj) {
20228      return isMatch(obj, attrs);
20229    };
20230  }
20231
20232  // Creates a function that, when passed an object, will traverse that object’s
20233  // properties down the given `path`, specified as an array of keys or indices.
20234  function property(path) {
20235    path = toPath(path);
20236    return function (obj) {
20237      return deepGet(obj, path);
20238    };
20239  }
20240
20241  // Internal function that returns an efficient (for current engines) version
20242  // of the passed-in callback, to be repeatedly applied in other Underscore
20243  // functions.
20244  function optimizeCb(func, context, argCount) {
20245    if (context === void 0) return func;
20246    switch (argCount == null ? 3 : argCount) {
20247      case 1:
20248        return function (value) {
20249          return func.call(context, value);
20250        };
20251      // The 2-argument case is omitted because we’re not using it.
20252      case 3:
20253        return function (value, index, collection) {
20254          return func.call(context, value, index, collection);
20255        };
20256      case 4:
20257        return function (accumulator, value, index, collection) {
20258          return func.call(context, accumulator, value, index, collection);
20259        };
20260    }
20261    return function () {
20262      return func.apply(context, arguments);
20263    };
20264  }
20265
20266  // An internal function to generate callbacks that can be applied to each
20267  // element in a collection, returning the desired result — either `_.identity`,
20268  // an arbitrary callback, a property matcher, or a property accessor.
20269  function baseIteratee(value, context, argCount) {
20270    if (value == null) return identity;
20271    if (isFunction$1(value)) return optimizeCb(value, context, argCount);
20272    if (isObject(value) && !isArray(value)) return matcher(value);
20273    return property(value);
20274  }
20275
20276  // External wrapper for our callback generator. Users may customize
20277  // `_.iteratee` if they want additional predicate/iteratee shorthand styles.
20278  // This abstraction hides the internal-only `argCount` argument.
20279  function iteratee(value, context) {
20280    return baseIteratee(value, context, Infinity);
20281  }
20282  _$1.iteratee = iteratee;
20283
20284  // The function we call internally to generate a callback. It invokes
20285  // `_.iteratee` if overridden, otherwise `baseIteratee`.
20286  function cb(value, context, argCount) {
20287    if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);
20288    return baseIteratee(value, context, argCount);
20289  }
20290
20291  // Returns the results of applying the `iteratee` to each element of `obj`.
20292  // In contrast to `_.map` it returns an object.
20293  function mapObject(obj, iteratee, context) {
20294    iteratee = cb(iteratee, context);
20295    var _keys = keys(obj),
20296      length = _keys.length,
20297      results = {};
20298    for (var index = 0; index < length; index++) {
20299      var currentKey = _keys[index];
20300      results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
20301    }
20302    return results;
20303  }
20304
20305  // Predicate-generating function. Often useful outside of Underscore.
20306  function noop() {}
20307
20308  // Generates a function for a given object that returns a given property.
20309  function propertyOf(obj) {
20310    if (obj == null) return noop;
20311    return function (path) {
20312      return get(obj, path);
20313    };
20314  }
20315
20316  // Run a function **n** times.
20317  function times(n, iteratee, context) {
20318    var accum = Array(Math.max(0, n));
20319    iteratee = optimizeCb(iteratee, context, 1);
20320    for (var i = 0; i < n; i++) accum[i] = iteratee(i);
20321    return accum;
20322  }
20323
20324  // Return a random integer between `min` and `max` (inclusive).
20325  function random(min, max) {
20326    if (max == null) {
20327      max = min;
20328      min = 0;
20329    }
20330    return min + Math.floor(Math.random() * (max - min + 1));
20331  }
20332
20333  // A (possibly faster) way to get the current timestamp as an integer.
20334  var now = Date.now || function () {
20335    return new Date().getTime();
20336  };
20337
20338  // Internal helper to generate functions for escaping and unescaping strings
20339  // to/from HTML interpolation.
20340  function createEscaper(map) {
20341    var escaper = function escaper(match) {
20342      return map[match];
20343    };
20344    // Regexes for identifying a key that needs to be escaped.
20345    var source = '(?:' + keys(map).join('|') + ')';
20346    var testRegexp = RegExp(source);
20347    var replaceRegexp = RegExp(source, 'g');
20348    return function (string) {
20349      string = string == null ? '' : '' + string;
20350      return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
20351    };
20352  }
20353
20354  // Internal list of HTML entities for escaping.
20355  var escapeMap = {
20356    '&': '&amp;',
20357    '<': '&lt;',
20358    '>': '&gt;',
20359    '"': '&quot;',
20360    "'": '&#x27;',
20361    '`': '&#x60;'
20362  };
20363
20364  // Function for escaping strings to HTML interpolation.
20365  var _escape = createEscaper(escapeMap);
20366
20367  // Internal list of HTML entities for unescaping.
20368  var unescapeMap = invert(escapeMap);
20369
20370  // Function for unescaping strings from HTML interpolation.
20371  var _unescape = createEscaper(unescapeMap);
20372
20373  // By default, Underscore uses ERB-style template delimiters. Change the
20374  // following template settings to use alternative delimiters.
20375  var templateSettings = _$1.templateSettings = {
20376    evaluate: /<%([\s\S]+?)%>/g,
20377    interpolate: /<%=([\s\S]+?)%>/g,
20378    escape: /<%-([\s\S]+?)%>/g
20379  };
20380
20381  // When customizing `_.templateSettings`, if you don't want to define an
20382  // interpolation, evaluation or escaping regex, we need one that is
20383  // guaranteed not to match.
20384  var noMatch = /(.)^/;
20385
20386  // Certain characters need to be escaped so that they can be put into a
20387  // string literal.
20388  var escapes = {
20389    "'": "'",
20390    '\\': '\\',
20391    '\r': 'r',
20392    '\n': 'n',
20393    "\u2028": 'u2028',
20394    "\u2029": 'u2029'
20395  };
20396  var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
20397  function escapeChar(match) {
20398    return '\\' + escapes[match];
20399  }
20400
20401  // In order to prevent third-party code injection through
20402  // `_.templateSettings.variable`, we test it against the following regular
20403  // expression. It is intentionally a bit more liberal than just matching valid
20404  // identifiers, but still prevents possible loopholes through defaults or
20405  // destructuring assignment.
20406  var bareIdentifier = /^\s*(\w|\$)+\s*$/;
20407
20408  // JavaScript micro-templating, similar to John Resig's implementation.
20409  // Underscore templating handles arbitrary delimiters, preserves whitespace,
20410  // and correctly escapes quotes within interpolated code.
20411  // NB: `oldSettings` only exists for backwards compatibility.
20412  function template(text, settings, oldSettings) {
20413    if (!settings && oldSettings) settings = oldSettings;
20414    settings = defaults({}, settings, _$1.templateSettings);
20415
20416    // Combine delimiters into one regular expression via alternation.
20417    var matcher = RegExp([(settings.escape || noMatch).source, (settings.interpolate || noMatch).source, (settings.evaluate || noMatch).source].join('|') + '|$', 'g');
20418
20419    // Compile the template source, escaping string literals appropriately.
20420    var index = 0;
20421    var source = "__p+='";
20422    text.replace(matcher, function (match, escape, interpolate, evaluate, offset) {
20423      source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
20424      index = offset + match.length;
20425      if (escape) {
20426        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
20427      } else if (interpolate) {
20428        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
20429      } else if (evaluate) {
20430        source += "';\n" + evaluate + "\n__p+='";
20431      }
20432
20433      // Adobe VMs need the match returned to produce the correct offset.
20434      return match;
20435    });
20436    source += "';\n";
20437    var argument = settings.variable;
20438    if (argument) {
20439      // Insure against third-party code injection. (CVE-2021-23358)
20440      if (!bareIdentifier.test(argument)) throw new Error('variable is not a bare identifier: ' + argument);
20441    } else {
20442      // If a variable is not specified, place data values in local scope.
20443      source = 'with(obj||{}){\n' + source + '}\n';
20444      argument = 'obj';
20445    }
20446    source = "var __t,__p='',__j=Array.prototype.join," + "print=function(){__p+=__j.call(arguments,'');};\n" + source + 'return __p;\n';
20447    var render;
20448    try {
20449      render = new Function(argument, '_', source);
20450    } catch (e) {
20451      e.source = source;
20452      throw e;
20453    }
20454    var template = function template(data) {
20455      return render.call(this, data, _$1);
20456    };
20457
20458    // Provide the compiled source as a convenience for precompilation.
vendor: 4,259 bytes, lines 20459-20573
20459    template.source = 'function(' + argument + '){\n' + source + '}';
20460    return template;
20461  }
20462
20463  // Traverses the children of `obj` along `path`. If a child is a function, it
20464  // is invoked with its parent as context. Returns the value of the final
20465  // child, or `fallback` if any child is undefined.
20466  function result(obj, path, fallback) {
20467    path = toPath(path);
20468    var length = path.length;
20469    if (!length) {
20470      return isFunction$1(fallback) ? fallback.call(obj) : fallback;
20471    }
20472    for (var i = 0; i < length; i++) {
20473      var prop = obj == null ? void 0 : obj[path[i]];
20474      if (prop === void 0) {
20475        prop = fallback;
20476        i = length; // Ensure we don't continue iterating.
20477      }
20478      obj = isFunction$1(prop) ? prop.call(obj) : prop;
20479    }
20480    return obj;
20481  }
20482
20483  // Generate a unique integer id (unique within the entire client session).
20484  // Useful for temporary DOM ids.
20485  var idCounter = 0;
20486  function uniqueId(prefix) {
20487    var id = ++idCounter + '';
20488    return prefix ? prefix + id : id;
20489  }
20490
20491  // Start chaining a wrapped Underscore object.
20492  function chain(obj) {
20493    var instance = _$1(obj);
20494    instance._chain = true;
20495    return instance;
20496  }
20497
20498  // Internal function to execute `sourceFunc` bound to `context` with optional
20499  // `args`. Determines whether to execute a function as a constructor or as a
20500  // normal function.
20501  function executeBound(sourceFunc, boundFunc, context, callingContext, args) {
20502    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
20503    var self = baseCreate(sourceFunc.prototype);
20504    var result = sourceFunc.apply(self, args);
20505    if (isObject(result)) return result;
20506    return self;
20507  }
20508
20509  // Partially apply a function by creating a version that has had some of its
20510  // arguments pre-filled, without changing its dynamic `this` context. `_` acts
20511  // as a placeholder by default, allowing any combination of arguments to be
20512  // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
20513  var partial = restArguments(function (func, boundArgs) {
20514    var placeholder = partial.placeholder;
20515    var _bound = function bound() {
20516      var position = 0,
20517        length = boundArgs.length;
20518      var args = Array(length);
20519      for (var i = 0; i < length; i++) {
20520        args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
20521      }
20522      while (position < arguments.length) args.push(arguments[position++]);
20523      return executeBound(func, _bound, this, this, args);
20524    };
20525    return _bound;
20526  });
20527  partial.placeholder = _$1;
20528
20529  // Create a function bound to a given object (assigning `this`, and arguments,
20530  // optionally).
20531  var bind = restArguments(function (func, context, args) {
20532    if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');
20533    var bound = restArguments(function (callArgs) {
20534      return executeBound(func, bound, context, this, args.concat(callArgs));
20535    });
20536    return bound;
20537  });
20538
20539  // Internal helper for collection methods to determine whether a collection
20540  // should be iterated as an array or as an object.
20541  // Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
20542  // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
20543  var isArrayLike = createSizePropertyCheck(getLength);
20544
20545  // Internal implementation of a recursive `flatten` function.
20546  function flatten$1(input, depth, strict, output) {
20547    output = output || [];
20548    if (!depth && depth !== 0) {
20549      depth = Infinity;
20550    } else if (depth <= 0) {
20551      return output.concat(input);
20552    }
20553    var idx = output.length;
20554    for (var i = 0, length = getLength(input); i < length; i++) {
20555      var value = input[i];
20556      if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {
20557        // Flatten current level of array or arguments object.
20558        if (depth > 1) {
20559          flatten$1(value, depth - 1, strict, output);
20560          idx = output.length;
20561        } else {
20562          var j = 0,
20563            len = value.length;
20564          while (j < len) output[idx++] = value[j++];
20565        }
20566      } else if (!strict) {
20567        output[idx++] = value;
20568      }
20569    }
20570    return output;
20571  }
20572
20573  // Bind a number of an object's methods to that object. Remaining arguments
vendor: 13,218 bytes, lines 20574-20954
20574  // are the method names to be bound. Useful for ensuring that all callbacks
20575  // defined on an object belong to it.
20576  var bindAll = restArguments(function (obj, keys) {
20577    keys = flatten$1(keys, false, false);
20578    var index = keys.length;
20579    if (index < 1) throw new Error('bindAll must be passed function names');
20580    while (index--) {
20581      var key = keys[index];
20582      obj[key] = bind(obj[key], obj);
20583    }
20584    return obj;
20585  });
20586
20587  // Memoize an expensive function by storing its results.
20588  function memoize(func, hasher) {
20589    var _memoize = function memoize(key) {
20590      var cache = _memoize.cache;
20591      var address = '' + (hasher ? hasher.apply(this, arguments) : key);
20592      if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);
20593      return cache[address];
20594    };
20595    _memoize.cache = {};
20596    return _memoize;
20597  }
20598
20599  // Delays a function for the given number of milliseconds, and then calls
20600  // it with the arguments supplied.
20601  var delay = restArguments(function (func, wait, args) {
20602    return setTimeout(function () {
20603      return func.apply(null, args);
20604    }, wait);
20605  });
20606
20607  // Defers a function, scheduling it to run after the current call stack has
20608  // cleared.
20609  var defer = partial(delay, _$1, 1);
20610
20611  // Returns a function, that, when invoked, will only be triggered at most once
20612  // during a given window of time. Normally, the throttled function will run
20613  // as much as it can, without ever going more than once per `wait` duration;
20614  // but if you'd like to disable the execution on the leading edge, pass
20615  // `{leading: false}`. To disable execution on the trailing edge, ditto.
20616  function throttle(func, wait, options) {
20617    var timeout, context, args, result;
20618    var previous = 0;
20619    if (!options) options = {};
20620    var later = function later() {
20621      previous = options.leading === false ? 0 : now();
20622      timeout = null;
20623      result = func.apply(context, args);
20624      if (!timeout) context = args = null;
20625    };
20626    var throttled = function throttled() {
20627      var _now = now();
20628      if (!previous && options.leading === false) previous = _now;
20629      var remaining = wait - (_now - previous);
20630      context = this;
20631      args = arguments;
20632      if (remaining <= 0 || remaining > wait) {
20633        if (timeout) {
20634          clearTimeout(timeout);
20635          timeout = null;
20636        }
20637        previous = _now;
20638        result = func.apply(context, args);
20639        if (!timeout) context = args = null;
20640      } else if (!timeout && options.trailing !== false) {
20641        timeout = setTimeout(later, remaining);
20642      }
20643      return result;
20644    };
20645    throttled.cancel = function () {
20646      clearTimeout(timeout);
20647      previous = 0;
20648      timeout = context = args = null;
20649    };
20650    return throttled;
20651  }
20652
20653  // When a sequence of calls of the returned function ends, the argument
20654  // function is triggered. The end of a sequence is defined by the `wait`
20655  // parameter. If `immediate` is passed, the argument function will be
20656  // triggered at the beginning of the sequence instead of at the end.
20657  function debounce(func, wait, immediate) {
20658    var timeout, previous, args, result, context;
20659    var _later = function later() {
20660      var passed = now() - previous;
20661      if (wait > passed) {
20662        timeout = setTimeout(_later, wait - passed);
20663      } else {
20664        timeout = null;
20665        if (!immediate) result = func.apply(context, args);
20666        // This check is needed because `func` can recursively invoke `debounced`.
20667        if (!timeout) args = context = null;
20668      }
20669    };
20670    var debounced = restArguments(function (_args) {
20671      context = this;
20672      args = _args;
20673      previous = now();
20674      if (!timeout) {
20675        timeout = setTimeout(_later, wait);
20676        if (immediate) result = func.apply(context, args);
20677      }
20678      return result;
20679    });
20680    debounced.cancel = function () {
20681      clearTimeout(timeout);
20682      timeout = args = context = null;
20683    };
20684    return debounced;
20685  }
20686
20687  // Returns the first function passed as an argument to the second,
20688  // allowing you to adjust arguments, run code before and after, and
20689  // conditionally execute the original function.
20690  function wrap(func, wrapper) {
20691    return partial(wrapper, func);
20692  }
20693
20694  // Returns a negated version of the passed-in predicate.
20695  function negate(predicate) {
20696    return function () {
20697      return !predicate.apply(this, arguments);
20698    };
20699  }
20700
20701  // Returns a function that is the composition of a list of functions, each
20702  // consuming the return value of the function that follows.
20703  function compose() {
20704    var args = arguments;
20705    var start = args.length - 1;
20706    return function () {
20707      var i = start;
20708      var result = args[start].apply(this, arguments);
20709      while (i--) result = args[i].call(this, result);
20710      return result;
20711    };
20712  }
20713
20714  // Returns a function that will only be executed on and after the Nth call.
20715  function after(times, func) {
20716    return function () {
20717      if (--times < 1) {
20718        return func.apply(this, arguments);
20719      }
20720    };
20721  }
20722
20723  // Returns a function that will only be executed up to (but not including) the
20724  // Nth call.
20725  function before(times, func) {
20726    var memo;
20727    return function () {
20728      if (--times > 0) {
20729        memo = func.apply(this, arguments);
20730      }
20731      if (times <= 1) func = null;
20732      return memo;
20733    };
20734  }
20735
20736  // Returns a function that will be executed at most one time, no matter how
20737  // often you call it. Useful for lazy initialization.
20738  var once = partial(before, 2);
20739
20740  // Returns the first key on an object that passes a truth test.
20741  function findKey(obj, predicate, context) {
20742    predicate = cb(predicate, context);
20743    var _keys = keys(obj),
20744      key;
20745    for (var i = 0, length = _keys.length; i < length; i++) {
20746      key = _keys[i];
20747      if (predicate(obj[key], key, obj)) return key;
20748    }
20749  }
20750
20751  // Internal function to generate `_.findIndex` and `_.findLastIndex`.
20752  function createPredicateIndexFinder(dir) {
20753    return function (array, predicate, context) {
20754      predicate = cb(predicate, context);
20755      var length = getLength(array);
20756      var index = dir > 0 ? 0 : length - 1;
20757      for (; index >= 0 && index < length; index += dir) {
20758        if (predicate(array[index], index, array)) return index;
20759      }
20760      return -1;
20761    };
20762  }
20763
20764  // Returns the first index on an array-like that passes a truth test.
20765  var findIndex = createPredicateIndexFinder(1);
20766
20767  // Returns the last index on an array-like that passes a truth test.
20768  var findLastIndex = createPredicateIndexFinder(-1);
20769
20770  // Use a comparator function to figure out the smallest index at which
20771  // an object should be inserted so as to maintain order. Uses binary search.
20772  function sortedIndex(array, obj, iteratee, context) {
20773    iteratee = cb(iteratee, context, 1);
20774    var value = iteratee(obj);
20775    var low = 0,
20776      high = getLength(array);
20777    while (low < high) {
20778      var mid = Math.floor((low + high) / 2);
20779      if (iteratee(array[mid]) < value) low = mid + 1;else high = mid;
20780    }
20781    return low;
20782  }
20783
20784  // Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.
20785  function createIndexFinder(dir, predicateFind, sortedIndex) {
20786    return function (array, item, idx) {
20787      var i = 0,
20788        length = getLength(array);
20789      if (typeof idx == 'number') {
20790        if (dir > 0) {
20791          i = idx >= 0 ? idx : Math.max(idx + length, i);
20792        } else {
20793          length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
20794        }
20795      } else if (sortedIndex && idx && length) {
20796        idx = sortedIndex(array, item);
20797        return array[idx] === item ? idx : -1;
20798      }
20799      if (item !== item) {
20800        idx = predicateFind(slice.call(array, i, length), isNaN$1);
20801        return idx >= 0 ? idx + i : -1;
20802      }
20803      for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
20804        if (array[idx] === item) return idx;
20805      }
20806      return -1;
20807    };
20808  }
20809
20810  // Return the position of the first occurrence of an item in an array,
20811  // or -1 if the item is not included in the array.
20812  // If the array is large and already in sort order, pass `true`
20813  // for **isSorted** to use binary search.
20814  var indexOf = createIndexFinder(1, findIndex, sortedIndex);
20815
20816  // Return the position of the last occurrence of an item in an array,
20817  // or -1 if the item is not included in the array.
20818  var lastIndexOf = createIndexFinder(-1, findLastIndex);
20819
20820  // Return the first value which passes a truth test.
20821  function find(obj, predicate, context) {
20822    var keyFinder = isArrayLike(obj) ? findIndex : findKey;
20823    var key = keyFinder(obj, predicate, context);
20824    if (key !== void 0 && key !== -1) return obj[key];
20825  }
20826
20827  // Convenience version of a common use case of `_.find`: getting the first
20828  // object containing specific `key:value` pairs.
20829  function findWhere(obj, attrs) {
20830    return find(obj, matcher(attrs));
20831  }
20832
20833  // The cornerstone for collection functions, an `each`
20834  // implementation, aka `forEach`.
20835  // Handles raw objects in addition to array-likes. Treats all
20836  // sparse array-likes as if they were dense.
20837  function each(obj, iteratee, context) {
20838    iteratee = optimizeCb(iteratee, context);
20839    var i, length;
20840    if (isArrayLike(obj)) {
20841      for (i = 0, length = obj.length; i < length; i++) {
20842        iteratee(obj[i], i, obj);
20843      }
20844    } else {
20845      var _keys = keys(obj);
20846      for (i = 0, length = _keys.length; i < length; i++) {
20847        iteratee(obj[_keys[i]], _keys[i], obj);
20848      }
20849    }
20850    return obj;
20851  }
20852
20853  // Return the results of applying the iteratee to each element.
20854  function map(obj, iteratee, context) {
20855    iteratee = cb(iteratee, context);
20856    var _keys = !isArrayLike(obj) && keys(obj),
20857      length = (_keys || obj).length,
20858      results = Array(length);
20859    for (var index = 0; index < length; index++) {
20860      var currentKey = _keys ? _keys[index] : index;
20861      results[index] = iteratee(obj[currentKey], currentKey, obj);
20862    }
20863    return results;
20864  }
20865
20866  // Internal helper to create a reducing function, iterating left or right.
20867  function createReduce(dir) {
20868    // Wrap code that reassigns argument variables in a separate function than
20869    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
20870    var reducer = function reducer(obj, iteratee, memo, initial) {
20871      var _keys = !isArrayLike(obj) && keys(obj),
20872        length = (_keys || obj).length,
20873        index = dir > 0 ? 0 : length - 1;
20874      if (!initial) {
20875        memo = obj[_keys ? _keys[index] : index];
20876        index += dir;
20877      }
20878      for (; index >= 0 && index < length; index += dir) {
20879        var currentKey = _keys ? _keys[index] : index;
20880        memo = iteratee(memo, obj[currentKey], currentKey, obj);
20881      }
20882      return memo;
20883    };
20884    return function (obj, iteratee, memo, context) {
20885      var initial = arguments.length >= 3;
20886      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
20887    };
20888  }
20889
20890  // **Reduce** builds up a single result from a list of values, aka `inject`,
20891  // or `foldl`.
20892  var reduce = createReduce(1);
20893
20894  // The right-associative version of reduce, also known as `foldr`.
20895  var reduceRight = createReduce(-1);
20896
20897  // Return all the elements that pass a truth test.
20898  function filter(obj, predicate, context) {
20899    var results = [];
20900    predicate = cb(predicate, context);
20901    each(obj, function (value, index, list) {
20902      if (predicate(value, index, list)) results.push(value);
20903    });
20904    return results;
20905  }
20906
20907  // Return all the elements for which a truth test fails.
20908  function reject(obj, predicate, context) {
20909    return filter(obj, negate(cb(predicate)), context);
20910  }
20911
20912  // Determine whether all of the elements pass a truth test.
20913  function every(obj, predicate, context) {
20914    predicate = cb(predicate, context);
20915    var _keys = !isArrayLike(obj) && keys(obj),
20916      length = (_keys || obj).length;
20917    for (var index = 0; index < length; index++) {
20918      var currentKey = _keys ? _keys[index] : index;
20919      if (!predicate(obj[currentKey], currentKey, obj)) return false;
20920    }
20921    return true;
20922  }
20923
20924  // Determine if at least one element in the object passes a truth test.
20925  function some(obj, predicate, context) {
20926    predicate = cb(predicate, context);
20927    var _keys = !isArrayLike(obj) && keys(obj),
20928      length = (_keys || obj).length;
20929    for (var index = 0; index < length; index++) {
20930      var currentKey = _keys ? _keys[index] : index;
20931      if (predicate(obj[currentKey], currentKey, obj)) return true;
20932    }
20933    return false;
20934  }
20935
20936  // Determine if the array or object contains a given item (using `===`).
20937  function contains(obj, item, fromIndex, guard) {
20938    if (!isArrayLike(obj)) obj = values(obj);
20939    if (typeof fromIndex != 'number' || guard) fromIndex = 0;
20940    return indexOf(obj, item, fromIndex) >= 0;
20941  }
20942
20943  // Invoke a method (with arguments) on every item in a collection.
20944  var invoke = restArguments(function (obj, path, args) {
20945    var contextPath, func;
20946    if (isFunction$1(path)) {
20947      func = path;
20948    } else {
20949      path = toPath(path);
20950      contextPath = path.slice(0, -1);
20951      path = path[path.length - 1];
20952    }
20953    return map(obj, function (context) {
20954      var method = func;
vendor: 6,310 bytes, lines 20955-21144
20955      if (!method) {
20956        if (contextPath && contextPath.length) {
20957          context = deepGet(context, contextPath);
20958        }
20959        if (context == null) return void 0;
20960        method = context[path];
20961      }
20962      return method == null ? method : method.apply(context, args);
20963    });
20964  });
20965
20966  // Convenience version of a common use case of `_.map`: fetching a property.
20967  function pluck(obj, key) {
20968    return map(obj, property(key));
20969  }
20970
20971  // Convenience version of a common use case of `_.filter`: selecting only
20972  // objects containing specific `key:value` pairs.
20973  function where(obj, attrs) {
20974    return filter(obj, matcher(attrs));
20975  }
20976
20977  // Return the maximum element (or element-based computation).
20978  function max(obj, iteratee, context) {
20979    var result = -Infinity,
20980      lastComputed = -Infinity,
20981      value,
20982      computed;
20983    if (iteratee == null || typeof iteratee == 'number' && _typeof(obj[0]) != 'object' && obj != null) {
20984      obj = isArrayLike(obj) ? obj : values(obj);
20985      for (var i = 0, length = obj.length; i < length; i++) {
20986        value = obj[i];
20987        if (value != null && value > result) {
20988          result = value;
20989        }
20990      }
20991    } else {
20992      iteratee = cb(iteratee, context);
20993      each(obj, function (v, index, list) {
20994        computed = iteratee(v, index, list);
20995        if (computed > lastComputed || computed === -Infinity && result === -Infinity) {
20996          result = v;
20997          lastComputed = computed;
20998        }
20999      });
21000    }
21001    return result;
21002  }
21003
21004  // Return the minimum element (or element-based computation).
21005  function min(obj, iteratee, context) {
21006    var result = Infinity,
21007      lastComputed = Infinity,
21008      value,
21009      computed;
21010    if (iteratee == null || typeof iteratee == 'number' && _typeof(obj[0]) != 'object' && obj != null) {
21011      obj = isArrayLike(obj) ? obj : values(obj);
21012      for (var i = 0, length = obj.length; i < length; i++) {
21013        value = obj[i];
21014        if (value != null && value < result) {
21015          result = value;
21016        }
21017      }
21018    } else {
21019      iteratee = cb(iteratee, context);
21020      each(obj, function (v, index, list) {
21021        computed = iteratee(v, index, list);
21022        if (computed < lastComputed || computed === Infinity && result === Infinity) {
21023          result = v;
21024          lastComputed = computed;
21025        }
21026      });
21027    }
21028    return result;
21029  }
21030
21031  // Safely create a real, live array from anything iterable.
21032  var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
21033  function toArray(obj) {
21034    if (!obj) return [];
21035    if (isArray(obj)) return slice.call(obj);
21036    if (isString(obj)) {
21037      // Keep surrogate pair characters together.
21038      return obj.match(reStrSymbol);
21039    }
21040    if (isArrayLike(obj)) return map(obj, identity);
21041    return values(obj);
21042  }
21043
21044  // Sample **n** random values from a collection using the modern version of the
21045  // [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
21046  // If **n** is not specified, returns a single random element.
21047  // The internal `guard` argument allows it to work with `_.map`.
21048  function sample(obj, n, guard) {
21049    if (n == null || guard) {
21050      if (!isArrayLike(obj)) obj = values(obj);
21051      return obj[random(obj.length - 1)];
21052    }
21053    var sample = toArray(obj);
21054    var length = getLength(sample);
21055    n = Math.max(Math.min(n, length), 0);
21056    var last = length - 1;
21057    for (var index = 0; index < n; index++) {
21058      var rand = random(index, last);
21059      var temp = sample[index];
21060      sample[index] = sample[rand];
21061      sample[rand] = temp;
21062    }
21063    return sample.slice(0, n);
21064  }
21065
21066  // Shuffle a collection.
21067  function shuffle(obj) {
21068    return sample(obj, Infinity);
21069  }
21070
21071  // Sort the object's values by a criterion produced by an iteratee.
21072  function sortBy(obj, iteratee, context) {
21073    var index = 0;
21074    iteratee = cb(iteratee, context);
21075    return pluck(map(obj, function (value, key, list) {
21076      return {
21077        value: value,
21078        index: index++,
21079        criteria: iteratee(value, key, list)
21080      };
21081    }).sort(function (left, right) {
21082      var a = left.criteria;
21083      var b = right.criteria;
21084      if (a !== b) {
21085        if (a > b || a === void 0) return 1;
21086        if (a < b || b === void 0) return -1;
21087      }
21088      return left.index - right.index;
21089    }), 'value');
21090  }
21091
21092  // An internal function used for aggregate "group by" operations.
21093  function group(behavior, partition) {
21094    return function (obj, iteratee, context) {
21095      var result = partition ? [[], []] : {};
21096      iteratee = cb(iteratee, context);
21097      each(obj, function (value, index) {
21098        var key = iteratee(value, index, obj);
21099        behavior(result, value, key);
21100      });
21101      return result;
21102    };
21103  }
21104
21105  // Groups the object's values by a criterion. Pass either a string attribute
21106  // to group by, or a function that returns the criterion.
21107  var groupBy = group(function (result, value, key) {
21108    if (has$1(result, key)) result[key].push(value);else result[key] = [value];
21109  });
21110
21111  // Indexes the object's values by a criterion, similar to `_.groupBy`, but for
21112  // when you know that your index values will be unique.
21113  var indexBy = group(function (result, value, key) {
21114    result[key] = value;
21115  });
21116
21117  // Counts instances of an object that group by a certain criterion. Pass
21118  // either a string attribute to count by, or a function that returns the
21119  // criterion.
21120  var countBy = group(function (result, value, key) {
21121    if (has$1(result, key)) result[key]++;else result[key] = 1;
21122  });
21123
21124  // Split a collection into two arrays: one whose elements all pass the given
21125  // truth test, and one whose elements all do not pass the truth test.
21126  var partition = group(function (result, value, pass) {
21127    result[pass ? 0 : 1].push(value);
21128  }, true);
21129
21130  // Return the number of elements in a collection.
21131  function size(obj) {
21132    if (obj == null) return 0;
21133    return isArrayLike(obj) ? obj.length : keys(obj).length;
21134  }
21135
21136  // Internal `_.pick` helper function to determine whether `key` is an enumerable
21137  // property name of `obj`.
21138  function keyInObj(value, key, obj) {
21139    return key in obj;
21140  }
21141
21142  // Return a copy of the object only containing the allowed properties.
21143  var pick = restArguments(function (obj, keys) {
21144    var result = {},
vendor: 8,825 bytes, lines 21145-21414
21145      iteratee = keys[0];
21146    if (obj == null) return result;
21147    if (isFunction$1(iteratee)) {
21148      if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
21149      keys = allKeys(obj);
21150    } else {
21151      iteratee = keyInObj;
21152      keys = flatten$1(keys, false, false);
21153      obj = Object(obj);
21154    }
21155    for (var i = 0, length = keys.length; i < length; i++) {
21156      var key = keys[i];
21157      var value = obj[key];
21158      if (iteratee(value, key, obj)) result[key] = value;
21159    }
21160    return result;
21161  });
21162
21163  // Return a copy of the object without the disallowed properties.
21164  var omit = restArguments(function (obj, keys) {
21165    var iteratee = keys[0],
21166      context;
21167    if (isFunction$1(iteratee)) {
21168      iteratee = negate(iteratee);
21169      if (keys.length > 1) context = keys[1];
21170    } else {
21171      keys = map(flatten$1(keys, false, false), String);
21172      iteratee = function iteratee(value, key) {
21173        return !contains(keys, key);
21174      };
21175    }
21176    return pick(obj, iteratee, context);
21177  });
21178
21179  // Returns everything but the last entry of the array. Especially useful on
21180  // the arguments object. Passing **n** will return all the values in
21181  // the array, excluding the last N.
21182  function initial(array, n, guard) {
21183    return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
21184  }
21185
21186  // Get the first element of an array. Passing **n** will return the first N
21187  // values in the array. The **guard** check allows it to work with `_.map`.
21188  function first(array, n, guard) {
21189    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
21190    if (n == null || guard) return array[0];
21191    return initial(array, array.length - n);
21192  }
21193
21194  // Returns everything but the first entry of the `array`. Especially useful on
21195  // the `arguments` object. Passing an **n** will return the rest N values in the
21196  // `array`.
21197  function rest(array, n, guard) {
21198    return slice.call(array, n == null || guard ? 1 : n);
21199  }
21200
21201  // Get the last element of an array. Passing **n** will return the last N
21202  // values in the array.
21203  function last(array, n, guard) {
21204    if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
21205    if (n == null || guard) return array[array.length - 1];
21206    return rest(array, Math.max(0, array.length - n));
21207  }
21208
21209  // Trim out all falsy values from an array.
21210  function compact(array) {
21211    return filter(array, Boolean);
21212  }
21213
21214  // Flatten out an array, either recursively (by default), or up to `depth`.
21215  // Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.
21216  function flatten(array, depth) {
21217    return flatten$1(array, depth, false);
21218  }
21219
21220  // Take the difference between one array and a number of other arrays.
21221  // Only the elements present in just the first array will remain.
21222  var difference = restArguments(function (array, rest) {
21223    rest = flatten$1(rest, true, true);
21224    return filter(array, function (value) {
21225      return !contains(rest, value);
21226    });
21227  });
21228
21229  // Return a version of the array that does not contain the specified value(s).
21230  var without = restArguments(function (array, otherArrays) {
21231    return difference(array, otherArrays);
21232  });
21233
21234  // Produce a duplicate-free version of the array. If the array has already
21235  // been sorted, you have the option of using a faster algorithm.
21236  // The faster algorithm will not work with an iteratee if the iteratee
21237  // is not a one-to-one function, so providing an iteratee will disable
21238  // the faster algorithm.
21239  function uniq(array, isSorted, iteratee, context) {
21240    if (!isBoolean(isSorted)) {
21241      context = iteratee;
21242      iteratee = isSorted;
21243      isSorted = false;
21244    }
21245    if (iteratee != null) iteratee = cb(iteratee, context);
21246    var result = [];
21247    var seen = [];
21248    for (var i = 0, length = getLength(array); i < length; i++) {
21249      var value = array[i],
21250        computed = iteratee ? iteratee(value, i, array) : value;
21251      if (isSorted && !iteratee) {
21252        if (!i || seen !== computed) result.push(value);
21253        seen = computed;
21254      } else if (iteratee) {
21255        if (!contains(seen, computed)) {
21256          seen.push(computed);
21257          result.push(value);
21258        }
21259      } else if (!contains(result, value)) {
21260        result.push(value);
21261      }
21262    }
21263    return result;
21264  }
21265
21266  // Produce an array that contains the union: each distinct element from all of
21267  // the passed-in arrays.
21268  var union = restArguments(function (arrays) {
21269    return uniq(flatten$1(arrays, true, true));
21270  });
21271
21272  // Produce an array that contains every item shared between all the
21273  // passed-in arrays.
21274  function intersection(array) {
21275    var result = [];
21276    var argsLength = arguments.length;
21277    for (var i = 0, length = getLength(array); i < length; i++) {
21278      var item = array[i];
21279      if (contains(result, item)) continue;
21280      var j;
21281      for (j = 1; j < argsLength; j++) {
21282        if (!contains(arguments[j], item)) break;
21283      }
21284      if (j === argsLength) result.push(item);
21285    }
21286    return result;
21287  }
21288
21289  // Complement of zip. Unzip accepts an array of arrays and groups
21290  // each array's elements on shared indices.
21291  function unzip(array) {
21292    var length = array && max(array, getLength).length || 0;
21293    var result = Array(length);
21294    for (var index = 0; index < length; index++) {
21295      result[index] = pluck(array, index);
21296    }
21297    return result;
21298  }
21299
21300  // Zip together multiple lists into a single array -- elements that share
21301  // an index go together.
21302  var zip = restArguments(unzip);
21303
21304  // Converts lists into objects. Pass either a single array of `[key, value]`
21305  // pairs, or two parallel arrays of the same length -- one of keys, and one of
21306  // the corresponding values. Passing by pairs is the reverse of `_.pairs`.
21307  function object(list, values) {
21308    var result = {};
21309    for (var i = 0, length = getLength(list); i < length; i++) {
21310      if (values) {
21311        result[list[i]] = values[i];
21312      } else {
21313        result[list[i][0]] = list[i][1];
21314      }
21315    }
21316    return result;
21317  }
21318
21319  // Generate an integer Array containing an arithmetic progression. A port of
21320  // the native Python `range()` function. See
21321  // [the Python documentation](https://docs.python.org/library/functions.html#range).
21322  function range(start, stop, step) {
21323    if (stop == null) {
21324      stop = start || 0;
21325      start = 0;
21326    }
21327    if (!step) {
21328      step = stop < start ? -1 : 1;
21329    }
21330    var length = Math.max(Math.ceil((stop - start) / step), 0);
21331    var range = Array(length);
21332    for (var idx = 0; idx < length; idx++, start += step) {
21333      range[idx] = start;
21334    }
21335    return range;
21336  }
21337
21338  // Chunk a single array into multiple arrays, each containing `count` or fewer
21339  // items.
21340  function chunk(array, count) {
21341    if (count == null || count < 1) return [];
21342    var result = [];
21343    var i = 0,
21344      length = array.length;
21345    while (i < length) {
21346      result.push(slice.call(array, i, i += count));
21347    }
21348    return result;
21349  }
21350
21351  // Helper function to continue chaining intermediate results.
21352  function chainResult(instance, obj) {
21353    return instance._chain ? _$1(obj).chain() : obj;
21354  }
21355
21356  // Add your own custom functions to the Underscore object.
21357  function mixin(obj) {
21358    each(functions(obj), function (name) {
21359      var func = _$1[name] = obj[name];
21360      _$1.prototype[name] = function () {
21361        var args = [this._wrapped];
21362        push.apply(args, arguments);
21363        return chainResult(this, func.apply(_$1, args));
21364      };
21365    });
21366    return _$1;
21367  }
21368
21369  // Add all mutator `Array` functions to the wrapper.
21370  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function (name) {
21371    var method = ArrayProto[name];
21372    _$1.prototype[name] = function () {
21373      var obj = this._wrapped;
21374      if (obj != null) {
21375        method.apply(obj, arguments);
21376        if ((name === 'shift' || name === 'splice') && obj.length === 0) {
21377          delete obj[0];
21378        }
21379      }
21380      return chainResult(this, obj);
21381    };
21382  });
21383
21384  // Add all accessor `Array` functions to the wrapper.
21385  each(['concat', 'join', 'slice'], function (name) {
21386    var method = ArrayProto[name];
21387    _$1.prototype[name] = function () {
21388      var obj = this._wrapped;
21389      if (obj != null) obj = method.apply(obj, arguments);
21390      return chainResult(this, obj);
21391    };
21392  });
21393
21394  // Named Exports
21395
21396  var allExports = {
21397    __proto__: null,
21398    VERSION: VERSION,
21399    restArguments: restArguments,
21400    isObject: isObject,
21401    isNull: isNull,
21402    isUndefined: isUndefined,
21403    isBoolean: isBoolean,
21404    isElement: isElement,
21405    isString: isString,
21406    isNumber: isNumber,
21407    isDate: isDate,
21408    isRegExp: isRegExp,
21409    isError: isError,
21410    isSymbol: isSymbol,
21411    isArrayBuffer: isArrayBuffer,
21412    isDataView: isDataView$1,
21413    isArray: isArray,
21414    isFunction: isFunction$1,
21415    isArguments: isArguments$1,
21416    isFinite: isFinite$1,
21417    isNaN: isNaN$1,
21418    isTypedArray: isTypedArray$1,
21419    isEmpty: isEmpty,
21420    isMatch: isMatch,
21421    isEqual: isEqual,
21422    isMap: isMap,
21423    isWeakMap: isWeakMap,
21424    isSet: isSet,
21425    isWeakSet: isWeakSet,
21426    keys: keys,
21427    allKeys: allKeys,
21428    values: values,
21429    pairs: pairs,
21430    invert: invert,
21431    functions: functions,
21432    methods: functions,
21433    extend: extend,
21434    extendOwn: extendOwn,
21435    assign: extendOwn,
21436    defaults: defaults,
21437    create: create,
21438    clone: clone,
21439    tap: tap,
21440    get: get,
21441    has: has,
21442    mapObject: mapObject,
21443    identity: identity,
21444    constant: constant,
21445    noop: noop,
21446    toPath: toPath$1,
21447    property: property,
21448    propertyOf: propertyOf,
21449    matcher: matcher,
21450    matches: matcher,
21451    times: times,
21452    random: random,
21453    now: now,
21454    escape: _escape,
21455    unescape: _unescape,
21456    templateSettings: templateSettings,
21457    template: template,
21458    result: result,
21459    uniqueId: uniqueId,
21460    chain: chain,
21461    iteratee: iteratee,
21462    partial: partial,
21463    bind: bind,
21464    bindAll: bindAll,
21465    memoize: memoize,
21466    delay: delay,
21467    defer: defer,
21468    throttle: throttle,
21469    debounce: debounce,
21470    wrap: wrap,
21471    negate: negate,
21472    compose: compose,
21473    after: after,
21474    before: before,
21475    once: once,
21476    findKey: findKey,
21477    findIndex: findIndex,
21478    findLastIndex: findLastIndex,
21479    sortedIndex: sortedIndex,
21480    indexOf: indexOf,
21481    lastIndexOf: lastIndexOf,
21482    find: find,
21483    detect: find,
21484    findWhere: findWhere,
21485    each: each,
21486    forEach: each,
21487    map: map,
21488    collect: map,
21489    reduce: reduce,
21490    foldl: reduce,
21491    inject: reduce,
21492    reduceRight: reduceRight,
21493    foldr: reduceRight,
21494    filter: filter,
21495    select: filter,
21496    reject: reject,
21497    every: every,
21498    all: every,
21499    some: some,
21500    any: some,
21501    contains: contains,
21502    includes: contains,
21503    include: contains,
21504    invoke: invoke,
21505    pluck: pluck,
21506    where: where,
21507    max: max,
21508    min: min,
21509    shuffle: shuffle,
21510    sample: sample,
21511    sortBy: sortBy,
21512    groupBy: groupBy,
21513    indexBy: indexBy,
21514    countBy: countBy,
21515    partition: partition,
21516    toArray: toArray,
21517    size: size,
21518    pick: pick,
21519    omit: omit,
21520    first: first,
21521    head: first,
21522    take: first,
21523    initial: initial,
21524    last: last,
21525    rest: rest,
21526    tail: rest,
21527    drop: rest,
21528    compact: compact,
21529    flatten: flatten,
21530    without: without,
21531    uniq: uniq,
21532    unique: uniq,
21533    union: union,
21534    intersection: intersection,
21535    difference: difference,
21536    unzip: unzip,
21537    transpose: unzip,
21538    zip: zip,
21539    object: object,
21540    range: range,
21541    chunk: chunk,
21542    mixin: mixin,
21543    'default': _$1
21544  };
21545
21546  // Default Export
21547
21548  // Add all of the Underscore functions to the wrapper object.
21549  var _ = mixin(allExports);
21550  // Legacy Node.js API.
21551  _._ = _;
21552  return _;
21553});
21554
21555}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
21556},{}],9:[function(require,module,exports){
21557"use strict";
21558
21559function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
21560function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
21561function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
21562function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
21563function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
21564function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
21565require("slick-carousel");
21566require("devbridge-autocomplete");
21567window.globalError = ('nexansConfig' in window ? window.nexansConfig.errorMessage : '') || 'Sorry the request failed. Please try again later.';
21568
21569// Require plugins
21570var jQueryCarousels = require('./plugins/jquery.carousels-simple.js');
21571var jQueryCarouselsOverlay = require('./plugins/jquery.carousels-overlay.js');
21572var jQueryGallery = require('./plugins/jquery.carousels-gallery.js');
21573var jQueryFinance = require('./plugins/jquery.carousels-finance.js');
21574
21575// Require modules.
21576var utils = require('./modules/utils.js');
21577var grid = require('./modules/grid.js');
21578var accordion = require('./modules/accordion.js');
21579var sectorExpand = require('./modules/expand-sector.js');
21580var panelExpand = require('./modules/expand-panel.js');
21581var scrollAnchorGenerate = require('./modules/scrollAnchorGenerate.js');
21582var scrollToAnchor = require('./modules/scrollToAnchor.js');
21583var carousels = require('./modules/carousels.js');
21584var gallery = require('./modules/gallery.js');
21585var viewMore = require('./modules/view-more.js');
21586var quicklinks = require('./modules/quick-access-icons.js');
21587window.toggleIcon = require('./modules/toggleIcon.js');
21588var toggleVideo = require('./modules/toggleVideo.js');
21589var dragSlider = require('./modules/dragSlider.js');
21590var fixHeight = require('./modules/fix-height.js');
21591var MainNav = require('./modules/mainNav.js');
21592var navigationPanel = require('./modules/navigation-panel.js');
21593var changeList = require('./modules/change-list.js');
21594var fullPage = require('./modules/fullpage-slider.js');
21595var addPadding = require('./modules/addPadding.js');
21596var newsList = require('./modules/news-list.js');
21597var filterList = require('./modules/filter-subnav.js');
21598var responsiveTables = require('./modules/responsive-table.js');
21599var modal = require('./modules/modal.js');
21600var subscribeNewsletter = require('./modules/suscribe-newsletter.js');
21601var tableselect = require('./modules/tableselect.js');
21602var tabs = require('./modules/tabs.js');
21603var cookies = require('./modules/cookies.js');
21604var showAccount = require('./modules/showAccount.js');
21605var showSearch = require('./modules/showSearch.js');
21606var showSubnav = require('./modules/showSubnav.js');
21607var searchFilters = require('./modules/search-filters.js');
21608window.menuDropdowns = require('./modules/menuDropdowns.js');
21609var coverParallax = require('./modules/coverParallax.js');
21610var docLists = require('./modules/docLists.js');
21611var actionsMenu = require('./modules/actionsMenu.js');
21612var truncate = require('./modules/truncate.js');
21613var sticky = require('./modules/sticky.js');
21614var rteArray = require('./modules/rteArray.js');
21615var sharePrice = require('./modules/sharePrice.js');
21616var redirect = require('./modules/redirect.js');
21617var asyncForms = require('./modules/asyncForms.js');
21618var askMail = require('./modules/ask-mail.js');
21619var storage = require('./modules/storage.js');
21620var autocomplete = require('./modules/autocomplete.js');
21621var eshop = require('./modules/eshop.js');
21622var retailers = require('./modules/retailers.js');
21623var formValidation = require('./modules/form-validation.js');
21624var formReset = require('./modules/form-reset.js');
21625var dealerLocator = require('./modules/dealerLocator.js');
21626
21627// panels
21628var panelProduct = require('./modules/panel-products.js');
21629var panelGovernance = require('./modules/panel-governance.js');
21630var panelSolutions = require('./modules/panel-solutions.js');
21631var panelContact = require('./modules/panel-contact.js');
21632var panelComparator = require('./modules/panel-comparator.js');
21633var contactForm = require('./modules/panel-contact-form.js');
21634var contactFormSpe = require('./modules/panel-contact-spe-form.js');
21635var panelDop = require('./modules/panel-dop.js');
21636var panelNewsletter = require('./modules/panel-newsletter.js');
21637var panelLogin = require('./modules/panel-login.js');
21638var panelStock = require('./modules/panel-stock.js');
21639var panels = require('./modules/panels.js');
21640$(function ($) {
21641  // needs to be called first
21642  if ($('.js-form-validation').length) {
21643    formValidation.init();
21644  }
21645  if ($('.js-form-reset').length) {
21646    formReset.init();
21647  }
21648
21649  // Utilitaires.
21650  utils.init();
21651  carousels.init();
21652
21653  // Gallery.
21654  gallery.init();
21655
21656  // Grid.
21657  if ($('.js-dev-grid').length) {
21658    grid.init();
21659  }
21660
21661  /* Accordion */
21662  if ($('.js-accordion').length) {
21663    accordion.init();
21664  }
21665
21666  /* Expand sector */
21667  if ($('.js-expand-sector').length) {
21668    sectorExpand.init();
21669  }
21670
21671  /* scroll to */
21672  if ($('.js-scroll-anchor-generate').length) {
21673    scrollAnchorGenerate.init();
21674  }
21675
21676  /* scroll to */
21677  if ($('.js-scroll-to-trigger').length) {
21678    scrollToAnchor.init();
21679  }
21680
21681  /* panelExpand */
21682  if ($('.js-open-panel').length) {
21683    panelExpand.init();
21684  }
21685
21686  /* load data panel */
21687  if ($('.js-load-product').length) {
21688    panelProduct.init();
21689  }
21690  if ($('.js-drag-slider').length) {
21691    dragSlider.init();
21692  }
21693  if ($('.js-push-quick-access').length) {
21694    quicklinks.init();
21695  }
21696  ;
21697
21698  // fixHeight
21699  if ($('.js-fix-height').length) {
21700    fixHeight.init();
21701  }
21702  window.toggleIcon.init(storage);
21703  if ($('.box--video').length) {
21704    toggleVideo.init();
21705  }
21706  if ($('.js-gp-panel').length) {
21707    panelGovernance.init();
21708  }
21709  if ($('.js-panel-solution').length) {
21710    panelSolutions.init();
21711  }
21712  if ($('.js-panel-newsletter').length) {
21713    panelNewsletter.init();
21714    subscribeNewsletter.init();
21715  }
21716  if ($('.js-user-login-form').length) {
21717    panelLogin.init();
21718  }
21719  if ($('.js-panel-comparator').length) {
21720    panelComparator.init(storage.comparator);
21721  }
21722  if ($('.js-panel-trigger-stock').length) {
21723    panelStock.init();
21724  }
21725  if ($('.js-panel').length) {
21726    panels.init();
21727  }
21728  if ($('.js-change-list-container').length && $('.js-change-list-link').length) {
21729    changeList.init();
21730  }
21731  if ($('.js-padding').length) {
21732    addPadding.init();
21733  }
21734  if ($('.js-fullpage-slider').length) {
21735    fullPage.init();
21736  }
21737  viewMore.init();
21738  if ($('.js-news-list').length) {
21739    newsList.init();
21740  }
21741  if ($('.js-result-filters-container').length) {
21742    searchFilters.init();
21743  }
21744  if ($('.js-responsive-table').length) {
21745    responsiveTables.init();
21746  }
21747  if ($('.js-filter').length) {
21748    filterList.init();
21749  }
21750  if ($('.js-panel-contact').length && $('.js-panel-contact-spe')) {
21751    panelContact.init();
21752    contactForm.init();
21753  }
21754  if ($('.js-panel-contact-spe').length) {
21755    contactFormSpe.init();
21756  }
21757  if ($('.js-panel-dop').length) {
21758    panelDop.init();
21759  }
21760  if ($('.js-modal').length) {
21761    modal.init();
21762  }
21763  if ($('.js-tabs').length) {
21764    tabs.init();
21765  }
21766  if ($('.js-tableselect').length) {
21767    tableselect.init();
21768  }
21769  if ($('.js-cookies').length) {
21770    cookies.init();
21771  }
21772  if ($('.js-account').length) {
21773    showAccount.init();
21774  }
21775  if ($('.js-search').length) {
21776    showSearch.init();
21777  }
21778  if ($('.js-show-subnav').length) {
21779    showSubnav.init();
21780  }
21781  if ($('.js-dropdown').length) {
21782    window.menuDropdowns.init();
21783  }
21784  if ($('.js-parallax').length) {
21785    coverParallax.init();
21786  }
21787  if ($('.js-doc-list-container').length) {
21788    docLists.init();
21789  }
21790  if ($('.js-actions-menu').length) {
21791    actionsMenu.init();
21792  }
21793  if ($('.js-truncate').length) {
21794    truncate.init();
21795  }
21796  if ($('.js-sticky').length) {
21797    sticky.init();
21798  }
21799  if ($('.js-menu-panel').length) {
21800    navigationPanel.init();
21801  }
21802  if ($('div.rte-array').length) {
21803    rteArray.init();
21804  }
21805  if ($('select.js-redirect').length) {
21806    redirect.init();
21807  }
21808  asyncForms.init();
21809  if ($('.js-ask-mail').length) {
21810    askMail.init();
21811  }
21812  if ($('.js-autocomplete').length) {
21813    autocomplete.init();
21814  }
21815  if ($('.carousel__wrapper').length) {
21816    $('.carousel__wrapper').each(function () {
21817      var slickSettings = $(this).data('slick');
21818      var $this = $(this);
21819      if ($(this).hasClass('carousel__small')) {
21820        $(this).on('init breakpoint', function (event, slick, direction) {
21821          if (slick.options.slidesToShow >= slick.slideCount) {
21822            if (!$this.hasClass('no-slide')) {
21823              $this.addClass('no-slide');
21824            }
21825          } else {
21826            $this.removeClass('no-slide');
21827          }
21828        }).slick(_objectSpread(_defineProperty(_defineProperty(_defineProperty({
21829          slidesToShow: 1,
21830          slidesToScroll: 1,
21831          dots: true,
21832          infinite: true,
21833          arrows: true,
21834          fade: false,
21835          cssEase: 'linear',
21836          autoplay: true,
21837          autoplaySpeed: 5000
21838        }, "infinite", false), "speed", 600), "responsive", [{
21839          breakpoint: 850,
21840          settings: {
21841            arrows: false,
21842            dots: true,
21843            fade: false
21844          }
21845        }]), slickSettings));
21846      } else {
21847        $(this).on('init breakpoint', function (event, slick, direction) {
21848          console.log('slick.options.slidesToShow >= slick.slideCoun', slick.options.slidesToShow, slick.slideCount);
21849          if (slick.options.slidesToShow >= slick.slideCount) {
21850            if (!$this.hasClass('no-slide')) {
21851              $this.addClass('no-slide');
21852            }
21853          } else {
21854            $this.removeClass('no-slide');
21855          }
21856        }).slick(_objectSpread({
21857          slidesToShow: 1,
21858          slidesToScroll: 1,
21859          arrows: true,
21860          fade: false,
21861          cssEase: 'linear',
21862          asNavFor: '.carousel__nav',
21863          autoplay: true,
21864          autoplaySpeed: 5000,
21865          infinite: false,
21866          speed: 600,
21867          responsive: [{
21868            breakpoint: 850,
21869            settings: {
21870              arrows: false,
21871              dots: true,
21872              fade: false
21873            }
21874          }]
21875        }, slickSettings));
21876      }
21877    });
21878  }
21879  if ($('.carousel__nav').length) {
21880    $('.carousel__nav').slick({
21881      slidesToShow: 4,
21882      slidesToScroll: 1,
21883      asNavFor: '.carousel__wrapper',
21884      arrows: false,
21885      infinite: false,
21886      dots: false,
21887      centerMode: false,
21888      focusOnSelect: true,
21889      draggable: true
21890    });
21891  }
21892
21893  // Navigation
21894  new MainNav();
21895
21896  // sharePrice
21897  sharePrice.init();
21898
21899  // eshop
21900  eshop.init(asyncForms);
21901  retailers.init(asyncForms);
21902
21903  // dealerlocator
21904  dealerLocator.init();
21905  $('select.language-select').change(function () {
21906    var newLanguage = $(this).val();
21907    if (newLanguage && newLanguage != window.nexansConfig.language) {
21908      var uri = window.location.href;
21909      var domainRe = /.*:\/\/[^\/]*/i;
21910      uri = uri.replace(domainRe, "");
21911      if (uri.match(".*/" + window.nexansConfig.language + "/.*")) {
21912        uri = uri.replace("/" + window.nexansConfig.language + "/", "/" + newLanguage + "/");
21913      } else {
21914        uri = uri.substr(uri.indexOf(window.nexansConfig.contextPath) + window.nexansConfig.contextPath.length);
21915        uri = window.nexansConfig.contextPath + "/" + newLanguage + uri;
21916      }
21917      window.location.href = uri;
21918    }
21919  });
21920  $('ul.language--list a').click(function (e) {
21921    e.preventDefault();
21922    var newLanguage = $(this).data('language');
21923    if (newLanguage && newLanguage != window.nexansConfig.language) {
21924      var uri = window.location.href;
21925      var domainRe = /.*:\/\/[^\/]*/i;
21926      uri = uri.replace(domainRe, "");
21927      if (uri.match(".*/" + window.nexansConfig.language + "/.*")) {
21928        uri = uri.replace("/" + window.nexansConfig.language + "/", "/" + newLanguage + "/");
21929      } else {
21930        uri = uri.substr(uri.indexOf(window.nexansConfig.contextPath) + window.nexansConfig.contextPath.length);
21931        uri = window.nexansConfig.contextPath + "/" + newLanguage + uri;
21932      }
21933      window.location.href = uri;
21934    }
21935  });
21936  $('body:not(.editMode) div.b2b-link-list').each(function () {
21937    if ($(this).find('li').length == 0) {
21938      $(this).remove();
21939    }
21940  });
21941  $(document).trigger('uiLoaded');
21942});
21943
21944},{"./modules/accordion.js":10,"./modules/actionsMenu.js":11,"./modules/addPadding.js":12,"./modules/ask-mail.js":13,"./modules/asyncForms.js":14,"./modules/autocomplete.js":15,"./modules/carousels.js":16,"./modules/change-list.js":17,"./modules/cookie
21944s.js":18,"./modules/coverParallax.js":19,"./modules/dealerLocator.js":20,"./modules/docLists.js":21,"./modules/dragSlider.js":22,"./modules/eshop.js":23,"./modules/expand-panel.js":24,"./modules/expand-sector.js":25,"./modules/filter-subnav.js":26,"./modules/fix-height.js":27,"./modules/form-reset.js":28,"./modules/form-validation.js":29,"./modules/fullpage-slider.js":30,"./modules/gallery.js":31,"./modules/grid.js":32,"./modules/mainNav.js":33,"./modules/menuDropdowns.js":34,"./modules/modal.js":36,"./modules/navigation-panel.js":38,"./modules/news-list.js":39,"./modules/panel-comparator.js":40,"./modules/panel-contact-form.js":41,"./modules/panel-contact-spe-form.js":42,"./modules/panel-contact.js":43,"./modules/panel-dop.js":44,"./modules/panel-governance.js":45,"./modules/panel-login.js":46,"./modules/panel-newsletter.js":47,"./modules/panel-products.js":48,"./modules/panel-solutions.js":49,"./modules/panel-stock.js":50,"./modules/panels.js":51,"./modules/quick-access-icons.js":52,"./modules/redirect.js":53,"./modules/responsive-table.js":54,"./modules/retailers.js":55,"./modules/rteArray.js":56,"./modules/scrollAnchorGenerate.js":57,"./modules/scrollToAnchor.js":58,"./modules/search-filters.js":59,"./modules/sharePrice.js":60,"./modules/showAccount.js":61,"./modules/showSearch.js":62,"./modules/showSubnav.js":63,"./modules/sticky.js":64,"./modules/storage.js":65,"./modules/suscribe-newsletter.js":66,"./modules/tableselect.js":67,"./modules/tabs.js":68,"./modules/toggleIcon.js":69,"./modules/toggleVideo.js":70,"./modules/truncate.js":71,"./modules/utils.js":72,"./modules/view-more.js":73,"./plugins/jquery.carousels-finance.js":74,"./plugins/jquery.carousels-gallery.js":75,"./plugins/jquery.carousels-overlay.js":76,"./plugins/jquery.carousels-simple.js":77,"devbridge-autocomplete":1,"slick-carousel":7}],10:[function(require,module,exports){
21945"use strict";
21946
21947var accordion = {
21948  ui: {},
21949  init: function init() {
21950    this.bindUI();
21951    this.bindEvents();
21952  },
21953  bindUI: function bindUI() {
21954    this.ui.$btnExpand = $('.js-accordion-trigger');
21955  },
21956  bindEvents: function bindEvents() {
21957    this.ui.$btnExpand.on('click', $.proxy(this.expandSection, this));
21958  },
21959  expandSection: function expandSection(e) {
21960    var $wrapper = $(e.currentTarget).closest('.js-accordion-wrapper');
21961    var $content = $wrapper.find('.js-accordion-content').first();
21962    $content.stop().slideToggle();
21963    if ($(e.currentTarget).hasClass('js-accordion-trigger-hide')) {
21964      $(e.currentTarget).hide();
21965    }
21966    $wrapper.toggleClass('is-open');
21967  }
21968};
21969module.exports = accordion;
21970
21971},{}],11:[function(require,module,exports){
21972"use strict";
21973
21974var actionsMenu = {
21975  ui: {},
21976  init: function init() {
21977    this.bindUI();
21978    this.bindEvents();
21979  },
21980  bindUI: function bindUI() {
21981    this.ui.$wrapper = $('.js-actions-menu');
21982    this.ui.$trigger = $('.js-actions-details-toggle');
21983    this.ui.$content = $('.js-actions-details');
21984  },
21985  bindEvents: function bindEvents() {
21986    this.ui.$trigger.on('click', $.proxy(this.toggleDetails, this));
21987  },
21988  toggleDetails: function toggleDetails(e) {
21989    this.ui.$content.stop().slideToggle();
21990    this.ui.$trigger.toggleClass('is-open');
21991  }
21992};
21993module.exports = actionsMenu;
21994
21995},{}],12:[function(require,module,exports){
21996"use strict";
21997
21998var addPadding = {
21999  ui: {},
22000  init: function init() {
22001    this.bindUI();
22002    this.bindEvents();
22003    this.paddingHandler();
22004  },
22005  bindUI: function bindUI() {
22006    this.ui.$win = $(window);
22007    this.ui.$body = $('body');
22008    this.ui.$wrap = $('.main-wrapper');
22009    this.ui.$grid = $('.grid');
22010    this.ui.$container = $('.js-padding');
22011  },
22012  bindEvents: function bindEvents() {
22013    this.ui.$win.on('resize', $.proxy(this.paddingHandler, this));
22014  },
22015  paddingHandler: function paddingHandler() {
22016    var wrapW = this.ui.$wrap.outerWidth();
22017    var gridW = this.ui.$grid.outerWidth();
22018    var result = (wrapW - gridW) / 2;
22019    var $item = this.ui.$container.find('.js-padding-item');
22020    if (this.isMobileTablet()) {
22021      $item.css('padding', 0);
22022      return;
22023    }
22024    $.each($item, function () {
22025      var direction = $(this).data('padding');
22026      if (direction === 'left') {
22027        $(this).css('padding-left', result);
22028      } else {
22029        $(this).css('padding-right', result);
22030      }
22031    });
22032  },
22033  isMobileTablet: function isMobileTablet() {
22034    if (this.ui.$win.outerWidth() <= 1023) {
22035      return true;
22036    } else {
22037      return false;
22038    }
22039  }
22040};
22041module.exports = addPadding;
22042
22043},{}],13:[function(require,module,exports){
22044"use strict";
22045
22046function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
22047function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
22048function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
22049function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
22050function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
22051function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
22052var Modal = require('./modalAdd.js');
22053var AskMailBtn = /*#__PURE__*/function () {
22054  function AskMailBtn(el) {
22055    _classCallCheck(this, AskMailBtn);
22056    this.el = el;
22057    this.$el = $(el);
22058    this.$template = this.$el.find('.ask-mail-form');
22059    this.bind();
22060  }
22061  return _createClass(AskMailBtn, [{
22062    key: "bind",
22063    value: function bind() {
22064      var self = this;
22065      this.$el.on('click', function (e) {
22066        e.preventDefault();
22067        new Modal({
22068          content: self.$template.html(),
22069          classes: ['modal--large']
22070        });
22071      });
22072    }
22073  }]);
22074}();
22075var askMail = {
22076  init: function init() {
22077    $('.js-ask-mail').each(function () {
22078      $(this).data('askMail', new AskMailBtn(this));
22079    });
22080  }
22081};
22082module.exports = askMail;
22083
22084},{"./modalAdd.js":37}],14:[function(require,module,exports){
22085"use strict";
22086
22087function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
22088function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
22089function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
22090function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
22091function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
22092function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
22093var _require = require("./panel-contact-form"),
22094  initElements = _require.initElements;
22095function formToJson($el) {
22096  var data = $el.serializeArray();
22097  var output = {};
22098  for (var i = 0; i < data.length; i++) {
22099    if (data[i].name in output) {
22100      if (Array.isArray(output[data[i].name])) {
22101        output[data[i].name].push(data[i].value);
22102      } else {
22103        output[data[i].name] = [output[data[i].name], data[i].value];
22104      }
22105    } else {
22106      output[data[i].name] = data[i].value;
22107    }
22108  }
22109  return JSON.stringify(output);
22110}
22111var AsyncForm = /*#__PURE__*/function () {
22112  function AsyncForm(el) {
22113    _classCallCheck(this, AsyncForm);
22114    this.el = el;
22115    this.$el = $(el);
22116    this.isSubmitting = false;
22117    this.successType = this.$el.data('success-type') || 'prepend';
22118    this.failMsg = this.$el.data('fail') || window.globalError;
22119    this.overlay = '<div class="form-overlay"></div>';
22120    this.$overlay = null;
22121    this.method = this.$el.attr('method') || 'POST';
22122    this.success = null;
22123    this.sentData = null;
22124    this.alwaysDisplayMessage = false;
22125    var self = this;
22126    this.valueBuilder = function (asyncForm, submitter) {
22127      if (self.contentType === 'application/json') {
22128        return formToJson(self.$el);
22129      }
22130      return new FormData(asyncForm.el);
22131    };
22132    this.contentType = this.$el.data('content-type') || false;
22133    this.processData = false;
22134    this.onBeforeSendCheck = null;
22135    this.$submitActors = this.$el.find('[type=submit]');
22136    this.submitActor = null;
22137    this.bind();
22138  }
22139  return _createClass(AsyncForm, [{
22140    key: "bind",
22141    value: function bind() {
22142      var self = this;
22143      this.$submitActors.on('click', function () {
22144        self.submitActor = this;
22145      });
22146      this.$el.on('submit', function (e) {
22147        e.preventDefault();
22148        self.submit(e);
22149      });
22150    }
22151  }, {
22152    key: "submit",
22153    value: function submit(event) {
22154      if (null === this.submitActor) {
22155        this.submitActor = this.$submitActors[0];
22156      }
22157      if (!this.isSubmitting) {
22158        this.isSubmitting = true;
22159        this.$el.addClass('loading');
22160        this.$el.find('.message-box, .async-error-msg').remove();
22161        this.$el.find('.form-group.has-error').removeClass('has-error');
22162        var values = {};
22163        var submitter = event.submitter;
22164        if (!submitter && event.originalEvent) submitter = event.originalEvent.submitter;
22165        if (!!submitter && !!$(submitter).data('asyncForm-valueBuilder')) {
22166          values = $(submitter).data('asyncForm-valueBuilder').call(this, this, submitter);
22167        } else if (this.valueBuilder != null) {
22168          values = this.valueBuilder.call(this, this, null);
22169        }
22170        this.sentData = this.$el.serializeArray();
22171        if (this.onBeforeSendCheck === null || this.onBeforeSendCheck.call(this)) {
22172          var settings = {
22173            url: this.$el.attr('action'),
22174            type: this.method,
22175            processData: this.processData,
22176            contentType: this.contentType,
22177            data: values
22178          };
22179          if (this.$el.hasClass('js-async-form-pdf') || $(this.submitActor).hasClass('js-submit-pdf')) {
22180            settings.xhrFields = {
22181              responseType: 'blob'
22182            };
22183          }
22184          this.sentData = settings.data;
22185          $.ajax(settings).done(this.done.bind(this)).fail(this.fail.bind(this));
22186        } else {
22187          this.isSubmitting = false;
22188          this.$el.removeClass('loading');
22189        }
22190      }
22191    }
22192  }, {
22193    key: "done",
22194    value: function done(data, textStatus, jqXHR) {
22195      var _this = this;
22196      var continueSubmitting = false;
22197      var contentType = jqXHR.getResponseHeader("Content-Type");
22198      if (contentType.match(/application\/(?:pdf|vnd\.ms-excel)/)) {
22199        var blob = new Blob([data], {
22200          type: contentType
22201        });
22202        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
22203          window.navigator.msSaveOrOpenBlob(blob);
22204        } else {
22205          var contentDisposition = jqXHR.getResponseHeader("Content-Disposition");
22206          var filename = null;
22207          var reUtf = /filename\*\s*=\s*(UTF-\d['"]*)?((['"]).*?[.]$\2|[^;\n]*)?/;
22208          var matchsUtf = contentDisposition.match(reUtf);
22209          if (matchsUtf && matchsUtf.length > 2 && matchsUtf[1] == "UTF-8''") {
22210            filename = decodeURIComponent(matchsUtf[2]);
22211          }
22212          if (!filename) {
22213            var re = /filename\s*=\s*((['"]).*?[.]$\2|[^;\n]*)?/;
22214            var matchs = contentDisposition.match(re);
22215            if (matchs && matchs.length > 1) {
22216              filename = decodeURIComponent(matchs[1].replace(/^"+|"+$/g, ''));
22217            }
22218          }
22219          var link = document.createElement('a');
22220          link.href = window.URL.createObjectURL(blob);
22221          link.download = filename || this.$el.data('filename');
22222          link.click();
22223          setTimeout(function () {
22224            // For Firefox it is necessary to delay revoking the ObjectURL
22225            window.URL.revokeObjectURL(data);
22226          }, 100);
22227        }
22228      } else if (typeof data === 'string') {
22229        this.$el.html(data);
22230      } else {
22231        if ("success" in data && data.success) {
22232          var displayMessage = true;
22233          if (this.success !== null) {
22234            this.success.call(this, data, textStatus, jqXHR);
22235            displayMessage = this.alwaysDisplayMessage || false; // if specific callback, then message won't be displayed unless 'alwaysDisplayMessage'
22236          } else if ("redirect" in data && data.redirect) {
22237            if (data.redirect === 'reload') {
22238              document.location.reload();
22239            } else {
22240              document.location = data.redirect;
22241            }
22242          }
22243          if (!!displayMessage) {
22244            switch (this.successType) {
22245              case 'prepend':
22246                this.$el.prepend('<div class="message-box message-box--info">' + data.message + '</div>');
22247                break;
22248              case 'replace':
22249                this.$el.html(data.message);
22250                break;
22251              case 'append':
22252                this.$el.append('<div class="message-box message-box--info">' + data.message + '</div>');
22253                break;
22254            }
22255          }
22256        } else if ('message' in data && data.message || 'errors' in data && data.errors.length > 0) {
22257          if ('message' in data && data.message) {
22258            this.$el.prepend('<div class="message-box message-box--error">' + data.message + '</div>');
22259          }
22260          if ('errors' in data && data.errors.length > 0) {
22261            var _loop = function _loop(i) {
22262              _this.$el.find('[name="' + data.errors[i].field + '"]').each(function () {
22263                var formGroup = $(this).parents('.form-group');
22264                formGroup.addClass('has-error');
22265                if ('error' in data.errors[i]) {
22266                  formGroup.append('<div class="async-error-msg">' + data.errors[i].error + '</div>');
22267                }
22268              });
22269            };
22270            for (var i = 0; i < data.errors.length; i++) {
22271              _loop(i);
22272            }
22273          }
22274        } else {
22275          this.fail();
22276        }
22277      }
22278      if (!continueSubmitting) {
22279        this.isSubmitting = false;
22280        this.$el.removeClass('loading');
22281      }
22282    }
22283  }, {
22284    key: "fail",
22285    value: function fail(data, textStatus, jqXHR) {
22286      this.$el.prepend('<div class="message-box message-box--error">' + this.failMsg + '</div>');
22287      this.isSubmitting = false;
22288      this.$el.removeClass('loading');
22289    }
22290  }]);
22291}();
22292var asyncForms = {
22293  init: function init() {
22294    $('.js-async-form').each(function () {
22295      $(this).data('asyncForm', new AsyncForm(this));
22296    });
22297    $(document).on('async-form', function (e, el, cb) {
22298      var async = new AsyncForm(el);
22299      $(el).data('asyncForm', async);
22300      if (cb) {
22301        cb(async);
22302      }
22303    });
22304  },
22305  initElement: function initElement(el) {
22306    return new AsyncForm(el);
22307  }
22308};
22309module.exports = asyncForms;
22310
22311},{"./panel-contact-form":41}],15:[function(require,module,exports){
22312"use strict";
22313
22314function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
22315function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
22316function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
22317function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
22318function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
22319function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
22320var AutocompleteInput = /*#__PURE__*/function () {
22321  function AutocompleteInput(el) {
22322    _classCallCheck(this, AutocompleteInput);
22323    this.$el = $(el);
22324    this.settings = $.extend({
22325      url: '',
22326      min: 4
22327    }, this.$el.data());
22328    this.$el.wrap('<div class="autocomplete-container"></div>');
22329    this.$container = this.$el.parent();
22330    this.bind();
22331  }
22332  return _createClass(AutocompleteInput, [{
22333    key: "bind",
22334    value: function bind() {
22335      var self = this;
22336      this.$el.autocomplete({
22337        minChars: this.settings.min,
22338        serviceUrl: this.settings.url,
22339        formatResult: function formatResult(suggestion, currentValue) {
22340          return suggestion.data;
22341        },
22342        onSearchStart: function onSearchStart(params) {
22343          self.start();
22344        },
22345        onSearchComplete: function onSearchComplete(query, suggestions) {
22346          self.complete();
22347        }
22348      });
22349    }
22350  }, {
22351    key: "start",
22352    value: function start() {
22353      this.$container.append('<div class="loader"></div>');
22354    }
22355  }, {
22356    key: "complete",
22357    value: function complete() {
22358      this.$container.find('.loader').remove();
22359    }
22360  }]);
22361}();
22362var autocomplete = {
22363  init: function init() {
22364    $('.js-autocomplete').each(function () {
22365      new AutocompleteInput(this);
22366    });
22367  }
22368};
22369module.exports = autocomplete;
22370
22371},{}],16:[function(require,module,exports){
22372"use strict";
22373
22374(function ($) {
22375  var carousel = {
22376    init: function init() {
22377      $.each($('.js-carousel-simple'), function () {
22378        $(this).carouselSimple();
22379      });
22380      $.each($('.js-carousel-overlay'), function () {
22381        $(this).carouselOverlay();
22382      });
22383      $.each($('.js-carousel-gallery'), function () {
22384        $(this).carouselGallery();
22385      });
22386      $.each($('.js-carousel-finance'), function () {
22387        $(this).carouselFinance();
22388      });
22389    }
22390  };
22391  module.exports = carousel;
22392})(jQuery);
22393
22394},{}],17:[function(require,module,exports){
22395"use strict";
22396
22397var changeList = {
22398  ui: {},
22399  init: function init() {
22400    this.bindUI();
22401    this.bindEvents();
22402  },
22403  bindUI: function bindUI() {
22404    this.ui.$win = $(window);
22405    this.ui.$body = $('body');
22406    this.ui.$links = $('.js-change-list-link');
22407    this.ui.$lists = $('.js-change-list');
22408    this.ui.$container = $('.js-change-list-container');
22409    this.ui.$select = $('.js-change-list-select');
22410  },
22411  bindEvents: function bindEvents() {
22412    this.ui.$links.on('click', $.proxy(this.clickHandler, this));
22413    this.ui.$select.on('change', $.proxy(this.changeHandler, this));
22414  },
22415  clickHandler: function clickHandler(e) {
22416    e.preventDefault();
22417    var $el = $(e.currentTarget),
22418      data = $el.data('list'),
22419      $currentList = this.ui.$container.find('.js-change-list[data-list=' + data + ']');
22420    this.ui.$lists.removeClass('active');
22421    $currentList.addClass('active');
22422  },
22423  changeHandler: function changeHandler(e) {
22424    var $el = $(e.currentTarget),
22425      data = $el.val(),
22426      $currentList = this.ui.$container.find('.js-change-list[data-list=' + data + ']');
22427    this.ui.$lists.removeClass('active');
22428    $currentList.addClass('active');
22429  }
22430};
22431module.exports = changeList;
22432
22433},{}],18:[function(require,module,exports){
22434"use strict";
22435
22436var cookies = {
22437  ui: {},
22438  cookieName: 'cookiesAllowed',
22439  init: function init() {
22440    this.bindUI();
22441    this.bindEvents();
22442  },
22443  bindUI: function bindUI() {
22444    this.ui.$cookies = $('.js-cookies');
22445    this.ui.$accept = this.ui.$cookies.find('.js-cookies-accept');
22446    this.ui.$deny = this.ui.$cookies.find('.js-cookies-deny');
22447  },
22448  bindEvents: function bindEvents() {
22449    // If the cookies are not set, show the banner.
22450    var cookieVal = this.getCookie(this.cookieName);
22451    if (cookieVal !== 'true' && cookieVal !== 'false') {
22452      this.showBanner();
22453    }
22454
22455    // On click on the close btn, close the banner and set the cookies.
22456    this.ui.$accept.on('click', this.accept.bind(this));
22457    this.ui.$deny.on('click', this.deny.bind(this));
22458  },
22459  showBanner: function showBanner() {
22460    this.ui.$cookies.removeClass('is-hidden');
22461  },
22462  accept: function accept(e) {
22463    // Prevent default.
22464    e.preventDefault();
22465
22466    // Hide cookies.
22467    this.ui.$cookies.addClass('is-hidden');
22468    setTracking();
22469
22470    // Set the cookies.
22471    this.setCookies('true');
22472  },
22473  deny: function deny(e) {
22474    // Prevent default.
22475    e.preventDefault();
22476
22477    // Hide cookies.
22478    this.ui.$cookies.addClass('is-hidden');
22479
22480    // Set the cookies.
22481    this.setCookies('false');
22482  },
22483  setCookies: function setCookies(value) {
22484    var today = new Date(),
22485      expires = new Date();
22486
22487    // Set the expire date.
22488    expires.setTime(today.getTime() + 3600 * 1000 * 24 * 30 * 13);
22489
22490    // Write the cookie.
22491    document.cookie = this.cookieName + "=" + value + ";path=/;expires=" + expires.toGMTString();
22492  },
22493  getCookie: function getCookie(name) {
22494    var _document$cookie$matc;
22495    return ((_document$cookie$matc = document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]+)')) === null || _document$cookie$matc === void 0 ? void 0 : _document$cookie$matc.pop()) || '';
22496  }
22497};
22498module.exports = cookies;
22499
22500},{}],19:[function(require,module,exports){
22501"use strict";
22502
22503var coverParallax = {
22504  ui: {},
22505  isScrolling: false,
22506  reversed: false,
22507  lastScroll: 0,
22508  init: function init() {
22509    this.bindUI();
22510    this.bindEvents();
22511  },
22512  bindUI: function bindUI() {
22513    this.ui.$win = $(window);
22514    this.ui.$container = $('.js-parallax');
22515    this.ui.$visual = this.ui.$container.find('.js-parallax-visual');
22516  },
22517  bindEvents: function bindEvents() {
22518    var _this = this;
22519    this.ui.$win.on('scroll', function (e) {
22520      return _this.onScroll(e);
22521    });
22522    this.ui.$win.on('scroll', function (e) {
22523      return _this.getDirection(e);
22524    });
22525  },
22526  onScroll: function onScroll(e) {
22527    e.preventDefault();
22528    if (!this.isScrolling) {
22529      var scroll = $(e.currentTarget).scrollTop(),
22530        bImage = this.ui.$visual.offset().top + this.ui.$visual.outerHeight(),
22531        bBloc = this.ui.$container.offset().top + this.ui.$container.outerHeight(),
22532        tImage = this.ui.$visual.offset().top,
22533        tBloc = this.ui.$container.offset().top;
22534      var value = scroll / 10;
22535      if (!this.reversed) {
22536        if (bImage > bBloc) {
22537          this.ui.$visual.css({
22538            'transform': 'translateY(' + -value + 'px)'
22539          });
22540        }
22541      } else {
22542        if (scroll < bBloc && value != bBloc) {
22543          this.ui.$visual.css({
22544            'transform': 'translateY(' + -value + 'px)'
22545          });
22546        }
22547      }
22548    }
22549  },
22550  getDirection: function getDirection(e) {
22551    e.preventDefault();
22552    var scroll = $(e.currentTarget).scrollTop();
22553    if (scroll > this.lastScroll) {
22554      this.reversed = false;
22555    } else {
22556      this.reversed = true;
22557    }
22558    this.lastScroll = scroll;
22559  }
22560};
22561module.exports = coverParallax;
22562
22563},{}],20:[function(require,module,exports){
22564"use strict";
22565
22566var scriptLoaded = false;
22567function addScript(src) {
22568  return new Promise(function (resolve, reject) {
22569    if (!scriptLoaded) {
22570      var s = document.createElement('script');
22571      s.setAttribute('src', src);
22572      s.addEventListener('load', resolve);
22573      s.addEventListener('error', reject);
22574      document.body.appendChild(s);
22575    }
22576    scriptLoaded = true;
22577    resolve();
22578  });
22579}
22580var dealerLocator = {
22581  init: function init() {
22582    var locators = $('.js-dealer-locator-page');
22583    if (locators.length > 0) {
22584      addScript(locators.data('script')).catch(function (err) {
22585        console.error(err);
22586        locators.find('.loader-container').hide();
22587        locators.find('.message-error').show();
22588      });
22589    }
22590    $('.panel-dealer-locator').on('opened', function (e, trigger) {
22591      var $this = $(this);
22592      var $trigger = $(trigger);
22593      var $dealerLocator = $this.find('.dealer-locator');
22594      $dealerLocator.data('familyid', $trigger.data('familyid') || null);
22595      $dealerLocator.data('productid', $trigger.data('productid') || null);
22596      if ($this.data('loaded')) {
22597        $dealerLocator.trigger('refresh');
22598      } else {
22599        addScript($dealerLocator.data('script')).then(function () {
22600          $this.data('loaded', true);
22601        }).catch(function (err) {
22602          console.error(err);
22603          $this.find('.loader-container').hide();
22604          $dealerLocator.find('.message-error').show();
22605        });
22606      }
22607    });
22608  }
22609};
22610module.exports = dealerLocator;
22611
22612},{}],21:[function(require,module,exports){
22613"use strict";
22614
22615var docLists = {
22616  ui: {},
22617  init: function init() {
22618    this.bindUI();
22619    this.bindEvents();
22620  },
22621  bindUI: function bindUI() {
22622    this.ui.$container = $('.js-doc-list-container');
22623    this.ui.$select = $('.js-doc-select', this.ui.$container);
22624    this.ui.$item = $('.js-doc-list', this.ui.$container);
22625  },
22626  bindEvents: function bindEvents() {
22627    var _this = this;
22628    this.ui.$select.on('change', function (e) {
22629      return _this.onChange(e);
22630    });
22631  },
22632  onChange: function onChange(e) {
22633    e.preventDefault();
22634    var $el = $(e.currentTarget),
22635      value = $el.val(),
22636      $target = this.ui.$container.find('.js-doc-list[data-year="' + value + '"]');
22637    this.ui.$item.removeClass('active');
22638    $target.addClass('active');
22639  }
22640};
22641module.exports = docLists;
22642
22643},{}],22:[function(require,module,exports){
22644"use strict";
22645
22646var _gsap = require("gsap");
22647var _Draggable = _interopRequireDefault(require("gsap/Draggable"));
22648function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
22649var dragSlider = {
22650  ui: {},
22651  slidesLength: 0,
22652  width: 0,
22653  track: 0,
22654  init: function init() {
22655    this.bindUI();
22656    this.bindEvents();
22657    this.initSlider();
22658  },
22659  bindUI: function bindUI() {
22660    this.ui.$window = $(window);
22661    this.ui.$dragContainer = $('.js-drag-slider');
22662    this.ui.$wrapper = '';
22663    this.ui.$dragItems = '';
22664  },
22665  bindEvents: function bindEvents() {
22666
22667    // this.ui.$window.on('resize', () => this.updateTrack());
22668  },
22669  initSlider: function initSlider() {
22670    this.ui.$dragContainer.each(function (n, item) {
22671      console.log('item slider', item);
22672      $(item).find('.js-drag-wrapper').slick({
22673        slidesToShow: 3,
22674        slidesToScroll: 1,
22675        dots: false,
22676        infinite: false,
22677        arrows: true,
22678        fade: false,
22679        cssEase: 'linear',
22680        autoplay: false,
22681        speed: 400,
22682        responsive: [{
22683          breakpoint: 1024,
22684          settings: {
22685            slidesToShow: 2
22686          }
22687        }, {
22688          breakpoint: 768,
22689          settings: {
22690            slidesToShow: 1
22691          }
22692        }]
22693      });
22694      // this.ui.$wrapper = $(item).find('.js-drag-wrapper');
22695      // this.ui.$dragItems = $(item).find('.js-drag-item');
22696
22697      // this.slidesLength = this.ui.$dragItems.length;
22698
22699      // this.updateTrack();
22700    });
22701  }
22702};
22703module.exports = dragSlider;
22704
22705},{"gsap":5,"gsap/Draggable":3}],23:[function(require,module,exports){
22706"use strict";
22707
22708var _ = require('underscore');
22709var message = require('./message.js');
22710var refreshShopCount = function refreshShopCount(count) {
22711  if (count > 0) {
22712    $('.js-eshop-count').show().text(count);
22713    $('.js-eshop-count').parent().removeClass('is-disabled');
22714  } else {
22715    $('.js-eshop-count').hide();
22716    $('.js-eshop-count').parent().addClass('is-disabled');
22717  }
22718};
22719var addToCartInit = function addToCartInit(asyncForms) {
22720  var $panel = $('#panel-addtocart');
22721  var $panelLoader = $panel.find('.loader-container');
22722  var $panelError = $panel.find('.service-error');
22723  var $panelContent = $panel.find('.panel-content');
22724  var panelTemplate = _.template($('#product-addtocart-template').html());
22725  var panel = $panel.data('panel');
22726  var serviceError = function serviceError() {
22727    $panelLoader.hide();
22728    $panelError.show();
22729    $panelContent.hide();
22730  };
22731  $panel.on('opened', function (e, trigger) {
22732    $panelLoader.show();
22733    $panelError.hide();
22734    $panelContent.hide();
22735    var url = window.nexansConfig.cartServiceUrl.replace('{action}', 'add') + '/' + $(trigger).data('id');
22736    $.ajax({
22737      url: url
22738    }).done(function (data, textStatus, jqXHR) {
22739      $panelLoader.hide();
22740      $panelError.hide();
22741      $panelContent.show().empty().html(panelTemplate(data));
22742      var asyncForm = asyncForms.initElement($panelContent.find('.js-async-form').get(0));
22743      asyncForm.contentType = 'application/json';
22744      asyncForm.valueBuilder = function (self, submitter) {
22745        var values = $(self.el).serializeArray();
22746        var data = {};
22747        for (var i = 0; i < values.length; i++) {
22748          data[values[i].name] = values[i].value;
22749        }
22750        return JSON.stringify(data);
22751      };
22752      asyncForm.alwaysDisplayMessage = true;
22753      asyncForm.success = function (data, textStatus, jqXHR) {
22754        window.sessionStorage.setItem('eshop-count', data.nbItems);
22755        refreshShopCount(data.nbItems);
22756        message.add(data.message, 'info', 3000);
22757        panel.close();
22758      };
22759    }).fail(function (xhr, status, error) {
22760      serviceError();
22761    });
22762  });
22763};
22764var eshop = {
22765  init: function init(asyncForms) {
22766    /* error "ReferenceError: TableSelect is not defined" in order backlog
22767          -> est-ce redondant par rapport au module tableselect ?
22768       $('.js-tableselect').each(function(){
22769           $(this).data('tableselect', new TableSelect(this));
22770       });
22771       */
22772    if ($('.js-panel-trigger-eshop').length > 0) {
22773      $(document).on('uiLoaded', function () {
22774        eshop.addToCartInit(asyncForms);
22775      });
22776    }
22777    if (window.nexansConfig.cartServiceUrl) {
22778      var count = window.sessionStorage.getItem('eshop-count');
22779      if (!count && count !== 0) {
22780        $.ajax({
22781          url: window.nexansConfig.cartServiceUrl.replace('{action}', 'count'),
22782          type: 'GET'
22783        }).done(function (data) {
22784          count = data.nbItems;
22785          window.sessionStorage.setItem('eshop-count', count);
22786          refreshShopCount(count);
22787        });
22788      } else {
22789        refreshShopCount(count);
22790      }
22791      $(document).on('refresh-shop-count', function (e, count) {
22792        window.sessionStorage.setItem('eshop-count', count);
22793        refreshShopCount(count);
22794      });
22795    }
22796  },
22797  addToCartInit: function addToCartInit(asyncForms) {
22798    var $panel = $('#panel-addtocart');
22799    var $panelLoader = $panel.find('.loader-container');
22800    var $panelError = $panel.find('.service-error');
22801    var $panelContent = $panel.find('.panel-content');
22802    var panelTemplate = _.template($('#product-addtocart-template').html());
22803    var panel = $panel.data('panel');
22804    var serviceError = function serviceError() {
22805      $panelLoader.hide();
22806      $panelError.show();
22807      $panelContent.hide();
22808    };
22809    $panel.on('opened', function (e, trigger) {
22810      $panelLoader.show();
22811      $panelError.hide();
22812      $panelContent.hide();
22813      var url = window.nexansConfig.cartServiceUrl.replace('{action}', 'add') + '/' + $(trigger).data('id');
22814      $.ajax({
22815        url: url
22816      }).done(function (data, textStatus, jqXHR) {
22817        $panelLoader.hide();
22818        $panelError.hide();
22819        $panelContent.show().empty().html(panelTemplate(data));
22820        var asyncForm = asyncForms.initElement($panelContent.find('.js-async-form').get(0));
22821        asyncForm.contentType = 'application/json';
22822        asyncForm.valueBuilder = function (self, submitter) {
22823          var values = $(self.el).serializeArray();
22824          var data = {};
22825          for (var i = 0; i < values.length; i++) {
22826            data[values[i].name] = values[i].value;
22827          }
22828          return JSON.stringify(data);
22829        };
22830        asyncForm.alwaysDisplayMessage = true;
22831        asyncForm.success = function (data, textStatus, jqXHR) {
22832          window.sessionStorage.setItem('eshop-count', data.nbItems);
22833          refreshShopCount(data.nbItems);
22834          message.add(data.message, 'info', 3000);
22835          panel.close();
22836        };
22837      }).fail(function (xhr, status, error) {
22838        serviceError();
22839      });
22840    });
22841  }
22842};
22843module.exports = eshop;
22844
22845},{"./message.js":35,"underscore":8}],24:[function(require,module,exports){
22846"use strict";
22847
22848var panelExpand = {
22849  ui: {},
22850  init: function init() {
22851    this.bindUI();
22852    this.bindEvents();
22853  },
22854  bindUI: function bindUI() {
22855    this.ui.$win = $(window);
22856    this.ui.$body = $('body');
22857    this.ui.$btnOpen = $('.js-open-panel');
22858    this.ui.$btnClose = $('.js-close-panel');
22859    this.ui.$mask = $('.js-mask-panel');
22860    this.ui.container = $('.js-panel-container');
22861  },
22862  bindEvents: function bindEvents() {
22863    this.ui.$btnOpen.on('click', $.proxy(this.openPanel, this));
22864    this.ui.$btnClose.on('click', $.proxy(this.closePanel, this));
22865    this.ui.$mask.on('click', $.proxy(this.closePanel, this));
22866    //$(document).on('keyup', $.proxy(this.closePanel, this));
22867  },
22868  openPanel: function expandSection(e) {
22869    e.preventDefault();
22870
22871    // open modale.
22872    this.ui.$body.addClass('is-locked');
22873    this.ui.$body.addClass('is-panel-open');
22874  },
22875  closePanel: function closePanel(e) {
22876    e.preventDefault();
22877
22878    // close modale.
22879    this.ui.$body.removeClass('is-locked');
22880    this.ui.$body.removeClass('is-panel-open');
22881
22882    // close modal with keyboard esc.
22883    if (e.keyCode === 27) {
22884      this.ui.$body.removeClass('is-locked');
22885      this.ui.$body.removeClass('is-panel-open');
22886    }
22887
22888    // back to top of panel view.
22889    var ofTop = $('body').offset().top;
22890    $('.js-panel-container').scrollTop(ofTop);
22891  }
22892};
22893module.exports = panelExpand;
22894
22895},{}],25:[function(require,module,exports){
22896"use strict";
22897
22898var sectorExpand = {
22899  ui: {},
22900  init: function init() {
22901    this.bindUI();
22902    this.bindEvents();
22903  },
22904  bindUI: function bindUI() {
22905    this.ui.$win = $(window);
22906    this.ui.$body = $('body');
22907    this.ui.$btnExpand = $('.js-expand-sector');
22908  },
22909  bindEvents: function bindEvents() {
22910    this.ui.$btnExpand.on('click', $.proxy(this.scrollToPanel, this));
22911  },
22912  scrollToPanel: function scrollToPanel(e) {
22913    e.preventDefault();
22914    var self = this;
22915    var $item = $(e.currentTarget).closest('.js-sector-container');
22916
22917    // Test if section is open for apply scroll effect or not.
22918    if (!$item.hasClass('is-open')) {
22919      // Calcute position of item animate.
22920      var pos = Math.max($item.offset().top, 0);
22921
22922      // Animate scroll to section opened.
22923      $('html').animate({
22924        scrollTop: pos
22925      }, 'slow', function () {
22926        // Call expand section.
22927        // waiting callback for animate show / hide after scroll effect.
22928        self.expandSection(e);
22929      });
22930    } else {
22931      // Call expand section without scroll animation.
22932      self.expandSection(e);
22933    }
22934  },
22935  expandSection: function expandSection(e) {
22936    // Get item for open section
22937    var $item = $(e.currentTarget).closest('.js-sector-container');
22938    $item.find('.list-sector').stop().slideToggle();
22939    if ($item.hasClass('is-open')) {
22940      $item.removeClass('is-open');
22941      $(e.currentTarget).removeClass('is-open');
22942    } else {
22943      $item.addClass('is-open');
22944      $(e.currentTarget).addClass('is-open');
22945    }
22946  }
22947};
22948module.exports = sectorExpand;
22949
22950},{}],26:[function(require,module,exports){
22951"use strict";
22952
22953var _ = require('underscore');
22954var filterList = {
22955  ui: {},
22956  init: function init() {
22957    this.bindUI();
22958    this.bindEvents();
22959    this.selectedCategories = window.nexansSelectedCategories || [];
22960    this.selectedYear = window.nexansSelectedYear || null;
22961    this.selectedType = window.nexansSelectedType || null;
22962  },
22963  bindUI: function bindUI() {
22964    this.ui.$win = $(window);
22965    this.ui.$body = $('body');
22966    this.ui.$dropdownParent = $('.js-filter-dropdown-parent');
22967    this.ui.$dropdown = $('.js-filter-dropdown');
22968    this.ui.$wrapper = $('.js-filter-dropdown-content');
22969    this.ui.$content = $('.js-filter-mobile-content');
22970    this.ui.$select = $('.js-filter-select');
22971    this.ui.$showFilter = $('.js-show-filter');
22972    this.ui.$jsFilter = $('.js-filter');
22973    this.ui.$filterLinks = this.ui.$jsFilter.find('.link:not(.js-filter-dropdown)');
22974    this.ui.$selectYear = $('select.filter-year-select');
22975    this.ui.$selectType = $('select.filter-type-select');
22976  },
22977  bindEvents: function bindEvents() {
22978    var self = this;
22979    this.ui.$dropdown.on('click', $.proxy(this.showSubnav, this));
22980    this.ui.$filterLinks.on('click', $.proxy(this.clickLink, this));
22981    //this.ui.$wrapper.on('mouseleave', $.proxy(this.hideSubnav, this));
22982
22983    this.ui.$select.on('change', $.proxy(this.selectCatChange, this));
22984    this.ui.$selectYear.on('change', $.proxy(this.selectYearChange, this));
22985    this.ui.$selectType.on('change', $.proxy(this.selectTypeChange, this));
22986    this.ui.$showFilter.on('click', $.proxy(this.showFilter, this));
22987
22988    // On click everywhere, close the search.
22989    $(document).click(function (e) {
22990      if ($(e.target).closest('.js-filter-dropdown').length === 0) {
22991        self.closeFilter();
22992      }
22993    });
22994  },
22995  clickLink: function clickLink(e) {
22996    var $el = $(e.currentTarget);
22997    var cat = this.getCategoryFromUrl($el.attr('href'));
22998    if (cat !== null) {
22999      e.preventDefault();
23000      this.setCategory(cat);
23001    }
23002  },
23003  getCategoryFromUrl: function getCategoryFromUrl(url) {
23004    var match = url.match(/category=([^&]+)/);
23005    if (match && match.length > 1) {
23006      return match[1];
23007    }
23008    return null;
23009  },
23010  setCategory: function setCategory(category) {
23011    var index = this.selectedCategories.indexOf(category);
23012    if (index < 0) {
23013      this.selectedCategories.push(category);
23014    } else {
23015      this.selectedCategories.splice(index, 1);
23016    }
23017    this.goto();
23018  },
23019  closeFilter: function closeFilter() {
23020    this.ui.$dropdownParent.removeClass('is-open');
23021  },
23022  showSubnav: function showSubnav(e) {
23023    e.preventDefault();
23024    var $el = $(e.currentTarget);
23025    if (!$el.parent().hasClass('is-open')) {
23026      this.closeFilter();
23027    }
23028    $el.parent().toggleClass('is-open');
23029  },
23030  hideSubnav: function hideSubnav(e) {
23031    var $el = $(e.currentTarget);
23032    setTimeout(function () {
23033      $el.parent().removeClass('is-open');
23034      $('.js-filter-dropdown').removeClass('is-open');
23035    }, 200);
23036  },
23037  selectCatChange: function selectCatChange(e) {
23038    var val = $(e.currentTarget).val();
23039    // Check if the value is defined.
23040    if (val === 'subnav') {
23041      var selected = $('.js-filter-select option:selected'),
23042        ref = selected.data('ref');
23043      $('#' + ref).addClass('is-selected');
23044    } else {
23045      var cat = this.getCategoryFromUrl(val);
23046      if (cat !== null) {
23047        this.setCategory(cat);
23048      }
23049    }
23050  },
23051  selectYearChange: function selectYearChange(e) {
23052    var year = $(e.currentTarget).val();
23053    if (year && year.length > 0) {
23054      year = parseInt(year, 10);
23055      this.selectedYear = year;
23056    } else {
23057      this.selectedYear = null;
23058    }
23059    this.goto();
23060  },
23061  selectTypeChange: function selectTypeChange(e) {
23062    var type = $(e.currentTarget).val();
23063    if (type && type.length > 0) {
23064      this.selectedType = type;
23065    } else {
23066      this.selectedType = null;
23067    }
23068    this.goto();
23069  },
23070  goto: function goto() {
23071    var url = window.nexansFilterUrl;
23072    var parameters = [];
23073    if (this.selectedCategories && this.selectedCategories.length) {
23074      parameters.push('category=' + this.selectedCategories.join());
23075    }
23076    if (this.selectedYear) {
23077      parameters.push('year=' + this.selectedYear);
23078    }
23079    if (this.selectedType) {
23080      parameters.push('type=' + this.selectedType);
23081    }
23082    if (parameters.length > 0) {
23083      url += '?' + parameters.join('&');
23084    }
23085    window.location.href = url;
23086  },
23087  showFilter: function showFilter(e) {
23088    e.preventDefault();
23089    var $el = $(e.currentTarget);
23090    $el.closest('.filter-mobile').toggleClass('is-open');
23091  }
23092};
23093module.exports = filterList;
23094
23095},{"underscore":8}],27:[function(require,module,exports){
23096"use strict";
23097
23098var fixHeight = {
23099  ui: {},
23100  init: function init() {
23101    this.bindUI();
23102    this.bindEvents();
23103  },
23104  bindUI: function bindUI() {
23105    this.ui.$win = $(window);
23106    this.ui.$body = $('body');
23107    this.ui.$height = $('.js-fix-height');
23108    this.ui.$items = $('.js-fix-height-item');
23109  },
23110  bindEvents: function bindEvents() {
23111    var _this = this;
23112    this.ui.$win.on('load', function () {
23113      return _this.heightHandler();
23114    });
23115
23116    // Reset height when window is resized.
23117    this.ui.$win.on('resize', function () {
23118      return _this.heightHandler();
23119    });
23120  },
23121  unbindEvents: function unbindEvents() {
23122    var self = this;
23123
23124    // Reset height when window is resized.
23125    this.ui.$win.off('resize');
23126  },
23127  update: function update() {
23128    if (Object.keys(this.ui).length) {
23129      this.unbindEvents();
23130    }
23131    this.bindUI();
23132    this.bindEvents();
23133  },
23134  heightHandler: function heightHandler() {
23135    var self = this;
23136
23137    // Loop through each element and launch function.
23138    $.each(this.ui.$height, function () {
23139      self.setHeight($(this));
23140    });
23141  },
23142  setHeight: function setHeight($el) {
23143    var self = this,
23144      maxH = 0,
23145      $items = $el.find('.js-fix-height-item'),
23146      $img = $el.find('img');
23147
23148    // Reset items height.
23149    $items.outerHeight('auto');
23150
23151    // Get maxH.
23152    $.each($items, function () {
23153      var itemH = $(this).outerHeight();
23154
23155      // If item height > to maxH, reset it.
23156      if (itemH > maxH) {
23157        maxH = itemH;
23158      }
23159    });
23160
23161    // Set maxH on elements.
23162    $items.outerHeight(maxH, true);
23163  }
23164};
23165module.exports = fixHeight;
23166
23167},{}],28:[function(require,module,exports){
23168"use strict";
23169
23170var formReset = {
23171  init: function init() {
23172    $('.js-form-reset').on('click', function (e) {
23173      e.preventDefault();
23174      var form = jQuery(e.target).parents('form');
23175      form.find('input:not([type=submit]):not([type=reset]):not([type=hidden]):not([type=checkbox])').val('');
23176      form.find('select option:selected').removeAttr('selected');
23177      form.find('input[type=checkbox]:checked').removeAttr('checked');
23178    });
23179  }
23180};
23181module.exports = formReset;
23182
23183},{}],29:[function(require,module,exports){
23184"use strict";
23185
23186function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
23187function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
23188function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
23189function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
23190function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
23191function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
23192var FormValidation = /*#__PURE__*/function () {
23193  function FormValidation(el) {
23194    _classCallCheck(this, FormValidation);
23195    this.$el = $(el);
23196    el.noValidate = true;
23197    this.$inputs = this.$el.find(':input');
23198    this.bind();
23199  }
23200  return _createClass(FormValidation, [{
23201    key: "bind",
23202    value: function bind() {
23203      var self = this;
23204      this.$el.on('submit', function (e) {
23205        self.$el.find('.message__error').remove();
23206        self.$el.find('.error').removeClass('error');
23207        if (!self.checkValidation()) {
23208          e.stopImmediatePropagation();
23209          e.preventDefault();
23210        } else {
23211          self.$el.trigger('validated', e);
23212        }
23213      });
23214    }
23215  }, {
23216    key: "checkValidation",
23217    value: function checkValidation() {
23218      var check = true;
23219      var top = null;
23220      var $focus = null;
23221      this.$inputs.each(function () {
23222        if (!this.checkValidity()) {
23223          check = false;
23224          var $this = $(this);
23225          $this.parents('.form-group').addClass('error');
23226          var customMessage = $this.data('error-message');
23227          if (customMessage) {
23228            $this.parent().append('<div class="message message__error">' + customMessage + '</div>');
23229          } else if ('validationMessage' in this && this.validationMessage) {
23230            $this.parent().append('<div class="message message__error">' + this.validationMessage + '</div>');
23231          }
23232          var nTop = $this.offset().top;
23233          if (top === null || nTop < top) {
23234            top = nTop;
23235            $focus = $this;
23236          }
23237        }
23238      });
23239      if (!check && !this.isInViewport($focus)) {
23240        $(window).scrollTop(top - 50);
23241      }
23242      return check;
23243    }
23244  }, {
23245    key: "isInViewport",
23246    value: function isInViewport($e) {
23247      var elementTop = $e.offset().top;
23248      var elementBottom = elementTop + $e.outerHeight();
23249      var viewportTop = $(window).scrollTop();
23250      var viewportBottom = viewportTop + $(window).height();
23251      return elementBottom > viewportTop && elementTop < viewportBottom;
23252    }
23253  }]);
23254}();
23255var formValidation = {
23256  init: function init() {
23257    $('.js-form-validation').each(function () {
23258      new FormValidation(this);
23259    });
23260    $(document).on('async-form', function (e, el) {
23261      if ($(el).hasClass('js-form-validation')) {
23262        new FormValidation(el);
23263      }
23264    });
23265  }
23266};
23267module.exports = formValidation;
23268
23269},{}],30:[function(require,module,exports){
23270"use strict";
23271
23272var fullPage = {
23273  ui: {},
23274  throttle: true,
23275  init: function init() {
23276    this.bindUI();
23277    this.bindEvents();
23278    this.initComponents();
23279  },
23280  bindUI: function bindUI() {
23281    this.ui.$win = $(window);
23282    this.ui.$body = $('body');
23283    this.ui.$container = $('.js-fullpage-slider');
23284    this.ui.$slide = '';
23285  },
23286  bindEvents: function bindEvents() {
23287    var _this = this;
23288    this.ui.$win.on('scroll', function (e) {
23289      return _this.activeOnScroll(e);
23290    });
23291  },
23292  initComponents: function initComponents() {
23293    var _this2 = this;
23294    this.ui.$container.each(function (n, item) {
23295      _this2.ui.$slide = $(item).find('.js-fullpage-slide');
23296    });
23297  },
23298  activeOnScroll: function activeOnScroll(e) {
23299    var _this3 = this;
23300    e.preventDefault();
23301    if (this.isMobileTablet()) {
23302      return;
23303    }
23304    if (this.throttle) {
23305      this.throttle = !this.throttle;
23306      var scroll = $(e.currentTarget).scrollTop();
23307      this.ui.$slide.each(function (n, item) {
23308        var offset = $(item).offset().top,
23309          vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0),
23310          height = $(item).outerHeight(),
23311          trigger = offset - vh + height / 3; // trigger when reaching 1/3 of item's height
23312
23313        if (scroll >= trigger) {
23314          $(item).addClass('active');
23315        }
23316      });
23317    }
23318    setTimeout(function () {
23319      _this3.throttle = !_this3.throttle;
23320    }, 5);
23321  },
23322  isMobileTablet: function isMobileTablet() {
23323    if (this.ui.$win.outerWidth() <= 1024) {
23324      return true;
23325    } else {
23326      return false;
23327    }
23328  }
23329};
23330module.exports = fullPage;
23331
23332},{}],31:[function(require,module,exports){
23333"use strict";
23334
23335var zoom = require('jquery-zoom');
23336var gallery = {
23337  ui: {},
23338  countImages: 0,
23339  init: function init() {
23340    var _this = this;
23341    $(document).on('init-gallery', function (e) {
23342      _this.initGallery();
23343    });
23344    this.initGallery();
23345  },
23346  initGallery: function initGallery() {
23347    if ($('.js-gallery').length) {
23348      this.bindUI();
23349      this.bindEvents();
23350      this.initZoom();
23351      this.updateControls(0);
23352    }
23353  },
23354  bindUI: function bindUI() {
23355    this.ui.$win = $(window);
23356    this.ui.$body = $('body');
23357    this.ui.$container = $('.js-gallery');
23358    this.ui.$thumbnail = $('.js-gallery-thumbnail');
23359    this.ui.$imageWrapper = $('.js-gallery-image-wrapper');
23360    this.ui.$navPrev = $('.js-gallery-prev');
23361    this.ui.$navNext = $('.js-gallery-next');
23362    this.countImages = this.ui.$imageWrapper.find('.js-gallery-image').length;
23363  },
23364  bindEvents: function bindEvents() {
23365    var _this2 = this;
23366    this.ui.$thumbnail.on('click', function (e) {
23367      return _this2.onThumbnail(e);
23368    });
23369    this.ui.$navPrev.on('click', function (e) {
23370      return _this2.onNav('prev');
23371    });
23372    this.ui.$navNext.on('click', function (e) {
23373      return _this2.onNav('next');
23374    });
23375  },
23376  initZoom: function initZoom() {
23377    if (!this.isMobileVersion()) {
23378      var imageUrl = this.ui.$imageWrapper.find('img.is-active').attr('src');
23379      this.ui.$imageWrapper.zoom({
23380        url: imageUrl,
23381        duration: 500
23382      });
23383    }
23384  },
23385  onThumbnail: function onThumbnail(e) {
23386    e.preventDefault();
23387    var $el = $(e.currentTarget),
23388      index = $el.index();
23389    this.setImage(index);
23390  },
23391  onNav: function onNav(direction) {
23392    var $el = this.ui.$imageWrapper.find('img.is-active'),
23393      indexCurrent = $el.index(),
23394      indexToSet;
23395    if (direction == 'prev') {
23396      indexToSet = indexCurrent - 1;
23397    } else {
23398      indexToSet = indexCurrent + 1;
23399    }
23400    indexToSet = Math.min(this.countImages - 1, indexToSet);
23401    indexToSet = Math.max(0, indexToSet);
23402    this.setImage(indexToSet);
23403  },
23404  setImage: function setImage(index) {
23405    // Set active image
23406    this.ui.$imageWrapper.find('img').removeClass('is-active');
23407    this.ui.$imageWrapper.find('img').eq(index).addClass('is-active');
23408
23409    // Set zoom image
23410    if (!this.isMobileVersion()) {
23411      var imageUrl = this.ui.$imageWrapper.find('img.is-active').attr('src');
23412      this.ui.$imageWrapper.trigger('zoom.destroy');
23413      this.ui.$imageWrapper.zoom({
23414        url: imageUrl,
23415        duration: 500
23416      });
23417    }
23418
23419    // Set controls
23420    this.updateControls(index);
23421  },
23422  updateControls: function updateControls(index) {
23423    // Set active thumbnail
23424    this.ui.$thumbnail.removeClass('is-active');
23425    this.ui.$thumbnail.eq(index).addClass('is-active');
23426
23427    // Set nav
23428    if (index >= this.countImages - 1) {
23429      this.ui.$navNext.addClass('is-disabled');
23430    } else {
23431      this.ui.$navNext.removeClass('is-disabled');
23432    }
23433    if (index <= 0) {
23434      this.ui.$navPrev.addClass('is-disabled');
23435    } else {
23436      this.ui.$navPrev.removeClass('is-disabled');
23437    }
23438  },
23439  isMobileVersion: function isMobileVersion() {
23440    return !this.ui.$thumbnail.is(":visible");
23441  }
23442};
23443module.exports = gallery;
23444
23445},{"jquery-zoom":6}],32:[function(require,module,exports){
23446"use strict";
23447
23448var grid = {
23449  ui: {},
23450  init: function init() {
23451    this.bindUI();
23452    this.bindEvents();
23453  },
23454  bindUI: function bindUI() {
23455    this.ui.$grid = $('.js-dev-grid');
23456    this.ui.$btn = $('.js-dev-grid-btn');
23457  },
23458  bindEvents: function bindEvents() {
23459    this.ui.$btn.on('click', $.proxy(this.toggleGrid, this));
23460  },
23461  toggleGrid: function toggleGrid() {
23462    this.ui.$grid.toggleClass('is-hidden');
23463  }
23464};
23465module.exports = grid;
23466
23467},{}],33:[function(require,module,exports){
23468"use strict";
23469
23470function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
23471function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
23472function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
23473function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
23474function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
23475function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
23476function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
23477function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
23478function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
23479var MainNav = /*#__PURE__*/function () {
23480  function MainNav() {
23481    _classCallCheck(this, MainNav);
23482    this.isOpened = false;
23483    this.bindUi();
23484    this.openedLinks = [null, null, null];
23485    this.$deposit = $('<div></div>').appendTo(this.$mainNav).hide();
23486    this.hierarchy = this.createHierarchy(this.$mainNav.children(), 0);
23487  }
23488  return _createClass(MainNav, [{
23489    key: "bindUi",
23490    value: function bindUi() {
23491      this.$mainNav = $('.main-nav');
23492      this.$mainSubnav = $('.main-subnav');
23493      this.$menuTrigger = $('.js-menu-trigger');
23494      this.$menuClose = $('.js-menu-close');
23495      this.$header = $('header.header');
23496      this.mainSubnavs = [$('.main-subnav--level-1'), $('.main-subnav--level-2'), $('.main-subnav--level-3')];
23497      var self = this;
23498      var clickLink = function clickLink(e) {
23499        e.stopPropagation();
23500        e.preventDefault();
23501        var linkInfos = self.hierarchy[$(this).data('id')];
23502        if (linkInfos.$link.hasClass('active')) {
23503          if (linkInfos.level === 0) {
23504            self.close();
23505          } else {
23506            self.closeLink(linkInfos);
23507          }
23508        } else {
23509          self.openLink(linkInfos);
23510        }
23511      };
23512      $('.main-nav, .main-subnav').on('click', function (e) {
23513        e.stopPropagation();
23514      });
23515      this.$mainNav.on('click', 'a.expand', clickLink);
23516      this.$mainSubnav.on('click', 'a.expand', clickLink);
23517      this.$menuTrigger.on('click', function (e) {
23518        e.preventDefault();
23519        self.$header.addClass('is-opened');
23520      });
23521      this.$menuClose.on('click', function (e) {
23522        e.preventDefault();
23523        self.$header.removeClass('is-opened');
23524      });
23525      $(document).on('click', function () {
23526        self.close();
23527      });
23528      $('.js-link-to-top').on('click', function (e) {
23529        e.preventDefault();
23530        $('body, html').animate({
23531          scrollTop: 0
23532        }, 'slow');
23533      });
23534    }
23535  }, {
23536    key: "createHierarchy",
23537    value: function createHierarchy($lis, level) {
23538      var prevId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'menulink';
23539      var hierarchy = {};
23540      var self = this;
23541      var i = 0;
23542      $lis.each(function () {
23543        var $this = $(this);
23544        var id = prevId + '-' + level + '-' + i;
23545        var $a = $this.children('a');
23546        var $ul = $this.children('ul');
23547        var $highlight = $this.children('.highlight');
23548        self.$deposit.append($ul);
23549        if ($highlight.length > 0) {
23550          self.$deposit.append($highlight);
23551        }
23552        var hierarchyLi = {
23553          id: id,
23554          title: $a.html(),
23555          $link: $a,
23556          level: level,
23557          $ul: $ul,
23558          $highlight: $highlight
23559        };
23560        hierarchy[id] = hierarchyLi;
23561        if ($this.hasClass('has-children')) {
23562          $a.addClass('expand').data('id', id);
23563          $ul.addClass(id);
23564          $highlight.addClass(id);
23565          hierarchy = _objectSpread(_objectSpread({}, hierarchy), self.createHierarchy($ul.children(), level + 1, id));
23566        }
23567        i++;
23568      });
23569      return hierarchy;
23570    }
23571  }, {
23572    key: "closeLink",
23573    value: function closeLink(linkInfos, checkChildren) {
23574      linkInfos.$link.removeClass('active');
23575      linkInfos.$ul.appendTo(this.$deposit);
23576      this.mainSubnavs[linkInfos.level].find('.main-subnav--nav').empty();
23577      this.mainSubnavs[linkInfos.level].removeClass('active');
23578      if (linkInfos.$highlight.length > 0) {
23579        linkInfos.$highlight.appendTo(this.$deposit);
23580      }
23581      this.openedLinks[linkInfos.level] = null;
23582      if (!checkChildren && linkInfos.level + 1 < 3 && this.openedLinks[linkInfos.level + 1]) {
23583        this.closeLink(this.openedLinks[linkInfos.level + 1]);
23584      }
23585    }
23586  }, {
23587    key: "openLink",
23588    value: function openLink(linkInfos) {
23589      var self = this;
23590      if (!this.isOpened) {
23591        this.$mainSubnav.addClass('active');
23592        this.isOpened = true;
23593      }
23594      if (this.openedLinks[linkInfos.level]) {
23595        this.closeLink(this.openedLinks[linkInfos.level]);
23596      }
23597      this.openedLinks[linkInfos.level] = linkInfos;
23598      linkInfos.$link.addClass('active');
23599      this.mainSubnavs[linkInfos.level].addClass('active');
23600      this.mainSubnavs[linkInfos.level].find('.main-subnav--links').append(linkInfos.$ul);
23601      var $backlink = $('<a href="#"></a>').append(linkInfos.title).on('click', function (e) {
23602        e.preventDefault();
23603        self.closeLink(linkInfos);
23604      });
23605      this.mainSubnavs[linkInfos.level].find('.main-subnav--nav').html($backlink);
23606      if (linkInfos.$highlight.length > 0) {
23607        linkInfos.$highlight.appendTo(this.mainSubnavs[2].find('.main-subnav--links'));
23608      }
23609    }
23610  }, {
23611    key: "close",
23612    value: function close() {
23613      for (var i = 0; i < this.openedLinks.length; i++) {
23614        if (this.openedLinks[i]) {
23615          this.closeLink(this.openedLinks[i], true);
23616        }
23617      }
23618      this.$mainSubnav.removeClass('active');
23619      this.isOpened = false;
23620    }
23621  }]);
23622}();
23623module.exports = MainNav;
23624
23625},{}],34:[function(require,module,exports){
23626"use strict";
23627
23628function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
23629function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
23630function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
23631function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
23632function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
23633function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
23634var JSDropdown = /*#__PURE__*/function () {
23635  function JSDropdown(el, list) {
23636    _classCallCheck(this, JSDropdown);
23637    this.el = el;
23638    this.$el = $(el);
23639    this.list = list;
23640    var target = this.$el.data('target');
23641    if (target) {
23642      this.$target = $('.' + target);
23643    } else {
23644      this.$target = this.$el.parents('.simple-dropdown').find('.submenu');
23645    }
23646    this.scroll = this.$el.hasClass('js-dropdown-scroll');
23647    this.$btClose = this.$target.find('.js-close-btn');
23648    this.bind();
23649  }
23650  return _createClass(JSDropdown, [{
23651    key: "bind",
23652    value: function bind() {
23653      var self = this;
23654      this.$el.on('click', function (e) {
23655        e.preventDefault();
23656        e.stopPropagation();
23657        if (self.$el.hasClass('active')) {
23658          self.close();
23659        } else {
23660          self.open();
23661        }
23662        self.$el.blur();
23663      });
23664      this.$target.on('click', function (e) {
23665        e.stopPropagation();
23666      });
23667      if (this.$btClose.length > 0) {
23668        this.$btClose.on('click', function (e) {
23669          e.stopPropagation();
23670          self.close();
23671        });
23672      }
23673    }
23674  }, {
23675    key: "close",
23676    value: function close() {
23677      this.$el.removeClass('active');
23678      this.$target.removeClass('active');
23679    }
23680  }, {
23681    key: "open",
23682    value: function open() {
23683      this.closeOthers();
23684      this.$el.addClass('active');
23685      this.$target.addClass('active');
23686      var self = this;
23687      if (this.scroll) {
23688        $('html, body').stop().animate({
23689          scrollTop: this.$target.offset().top
23690        }, 400, function () {
23691          var $form = self.$target.find('form');
23692          if ($form.length) {
23693            $form.find('input,textarea,select').first()[0].focus();
23694          }
23695        });
23696      }
23697    }
23698  }, {
23699    key: "closeOthers",
23700    value: function closeOthers() {
23701      for (var i = 0; i < this.list.length; i++) {
23702        if (this.list[i] !== this) this.list[i].close();
23703      }
23704    }
23705  }]);
23706}();
23707var menuDropdowns = {
23708  obj: JSDropdown,
23709  list: [],
23710  init: function init() {
23711    var self = this;
23712    $('.js-dropdown').each(function () {
23713      self.list.push(new JSDropdown(this, self.list));
23714    });
23715    $('body').click(function () {
23716      for (var i = 0; i < self.list.length; i++) {
23717        self.list[i].close();
23718      }
23719    });
23720  }
23721};
23722module.exports = menuDropdowns;
23723
23724},{}],35:[function(require,module,exports){
23725"use strict";
23726
23727var message = {
23728  add: function add(text, type, timeout) {
23729    if (timeout !== false) {
23730      timeout = parseInt(timeout, 10);
23731      if (timeout < 1) {
23732        timeout = 5000;
23733      }
23734    }
23735    if (type !== 'info' && type !== 'warning' && type !== 'error') {
23736      type = 'info';
23737    }
23738    var $mess = $('<div class="quick-message quick-message--' + type + '"><button type="button" class="quick-message__close"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" class="icon icon-close" viewBox="0 0 20 20"><path fill="#000000" fill-rule="evenodd" d="M10,8.58578644 L4.34314575,2.92893219 L2.92893219,4.34314575 L8.58578644,10 L2.92893219,15.6568542 L4.34314575,17.0710678 L10,11.4142136 L15.6568542,17.0710678 L17.0710678,15.6568542 L11.4142136,10 L17.0710678,4.34314575 L15.6568542,2.92893219 L10,8.58578644 Z" /></svg></button><div class="content"></div></div>');
23739    $mess.find('.content').html(text);
23740    $('body').append($mess);
23741    if (timeout !== false) {
23742      var _timer = setTimeout(function () {
23743        $mess.fadeOut(function () {
23744          $mess.remove();
23745        });
23746      }, timeout);
23747    }
23748    $('.quick-message__close').on('click', function () {
23749      if (timeout !== false) clearTimeout(timer);
23750      $mess.remove();
23751    });
23752  }
23753};
23754module.exports = message;
23755
23756},{}],36:[function(require,module,exports){
23757"use strict";
23758
23759var modal = {
23760  ui: {},
23761  init: function init() {
23762    this.bindUI();
23763    this.bindEvents();
23764  },
23765  bindUI: function bindUI() {
23766    // Global
23767    this.ui.$win = $(window);
23768    this.ui.$body = $('body');
23769    this.ui.$document = $(document);
23770
23771    // Module
23772    this.ui.$btn = $('.js-modal-btn');
23773    this.ui.$modal = $('.js-modal');
23774    this.ui.$close = $('.js-modal-close');
23775  },
23776  bindEvents: function bindEvents() {
23777    this.ui.$btn.on('click', $.proxy(this.showModal, this));
23778    this.ui.$close.on('click', $.proxy(this.closeModal, this));
23779    // this.ui.$document.on('keyup', $.proxy(this.closeModal, this));
23780  },
23781  showModal: function showModal(e) {
23782    e.preventDefault();
23783
23784    // get ref modal.
23785    var ref = $(e.currentTarget).data('modal');
23786
23787    // Parsing all modal to get clicked by ref.
23788    $.each(this.ui.$modal, function () {
23789      // Test ref clicked.
23790      if ($(this).data('modal') == ref) {
23791        // Show modal.
23792        $(this).addClass('is-open');
23793
23794        // Lock body.
23795        $('body').addClass('is-locked');
23796      }
23797    });
23798  },
23799  closeModal: function closeModal(e) {
23800    e.preventDefault();
23801
23802    // Get wrapper of btn close.
23803    var wrapper = $(e.currentTarget).closest('.js-modal');
23804
23805    // Close modal.
23806    wrapper.removeClass('is-open');
23807
23808    // Unlock body.
23809    this.ui.$body.removeClass('is-locked');
23810
23811    // Close by keyboard.
23812    if (e.keyCode === 27) {
23813      this.ui.$modal.removeClass('is-open');
23814      this.ui.$body.removeClass('is-locked');
23815    }
23816  }
23817};
23818module.exports = modal;
23819
23820},{}],37:[function(require,module,exports){
23821"use strict";
23822
23823function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
23824function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
23825function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
23826function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
23827function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
23828function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
23829var Modal = /*#__PURE__*/function () {
23830  function Modal(params) {
23831    _classCallCheck(this, Modal);
23832    this.params = $.extend({
23833      content: '',
23834      open: true,
23835      classes: [],
23836      onClose: null
23837    }, params);
23838    this.params.classes.unshift('modal');
23839    if (this.params.open) this.open();
23840  }
23841  return _createClass(Modal, [{
23842    key: "open",
23843    value: function open() {
23844      var modal = "<div class=\"".concat(this.params.classes.join(' '), "\"><div class=\"modal--modal\"><button type=\"button\" class=\"modal__close\">Close<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" class=\"icon icon-close\" viewBox=\"0 0 20 20\"><path fill=\"#000000\" fill-rule=\"evenodd\" d=\"M10,8.58578644 L4.34314575,2.92893219 L2.92893219,4.34314575 L8.58578644,10 L2.92893219,15.6568542 L4.34314575,17.0710678 L10,11.4142136 L15.6568542,17.0710678 L17.0710678,15.6568542 L11.4142136,10 L17.0710678,4.34314575 L15.6568542,2.92893219 L10,8.58578644 Z\" /></svg></button><div class=\"modal--content\"></div></div></div></div>");
23845      this.$modal = $(modal);
23846      this.$modal.appendTo('body');
23847      this.bind();
23848      this.$modal.find('.modal--content').html(this.params.content);
23849      this.$modal.addClass('is-open');
23850    }
23851  }, {
23852    key: "close",
23853    value: function close() {
23854      this.unbind();
23855      this.$modal.remove();
23856      if (this.params.onClose) {
23857        this.params.onClose();
23858      }
23859    }
23860  }, {
23861    key: "bind",
23862    value: function bind() {
23863      $(document).on('keyup.modal', function (e) {
23864        if (e.keyCode === 27) {
23865          this.close();
23866        }
23867      }.bind(this));
23868      this.$modal.on('click', this.close.bind(this));
23869      this.$modal.find('.modal__close').on('click', this.close.bind(this));
23870      this.$modal.find('.modal--modal').on('click', function (e) {
23871        e.stopPropagation();
23872      });
23873    }
23874  }, {
23875    key: "unbind",
23876    value: function unbind() {
23877      $(document).off('keyup.modal');
23878    }
23879  }]);
23880}();
23881module.exports = Modal;
23882
23883},{}],38:[function(require,module,exports){
23884"use strict";
23885
23886var navigationPanel = {
23887  ui: {},
23888  init: function init() {
23889    this.bindUI();
23890    this.bindEvents();
23891  },
23892  bindUI: function bindUI() {
23893    this.ui.$win = $(window);
23894    this.ui.$body = $('body');
23895    this.ui.$document = $(document);
23896
23897    // Menu
23898    this.ui.$menuPanelOpenTrigger = $('.js-menu-panel-trigger');
23899    this.ui.$menuPanelWrapper = $('.js-menu-panel');
23900    this.ui.$menuPanelOverlay = $('.js-overlay');
23901    this.ui.$menuPanelCloseTrigger = $('.js-menu-panel-close');
23902
23903    // Expends
23904    this.ui.$menuPanelExpendTrigger = $('.js-menu-panel-expend-trigger');
23905    this.ui.$menuPanelBackTrigger = $('.js-menu-panel-back-trigger');
23906  },
23907  bindEvents: function bindEvents() {
23908    this.ui.$menuPanelOpenTrigger.on('click', $.proxy(this.openNavigation, this));
23909    this.ui.$menuPanelCloseTrigger.add(this.ui.$menuPanelOverlay).on('click', $.proxy(this.closeNavigation, this));
23910    this.ui.$menuPanelExpendTrigger.on('click', this.openExpend);
23911    this.ui.$menuPanelBackTrigger.on('click', this.closeExpend);
23912  },
23913  openNavigation: function openNavigation(e) {
23914    e.preventDefault();
23915    var $menuPanelWrapper = $('.js-menu-panel#' + $(e.currentTarget).attr('data-panel'));
23916    $menuPanelWrapper.addClass('is-opened');
23917    this.ui.$menuPanelOverlay.addClass('active');
23918    this.ui.$body.addClass('is-locked');
23919  },
23920  closeNavigation: function closeNavigation(e) {
23921    e.preventDefault();
23922    this.ui.$menuPanelWrapper.removeClass('is-opened');
23923    this.ui.$menuPanelOverlay.removeClass('active');
23924    this.ui.$body.removeClass('is-locked');
23925  },
23926  openExpend: function openExpend(e) {
23927    e.preventDefault();
23928    var $wrapper = $(this).hasClass('js-menu-panel-expend-wrapper') ? $(this) : $(this).closest('.js-menu-panel-expend-wrapper'),
23929      $expend = $wrapper.find('.js-menu-panel-expend').first(),
23930      $menuExpend = $expend.find('.navigation__expends');
23931    if ($expend.hasClass('is-opened')) {
23932      $expend.height(0);
23933      $expend.removeClass('is-opened');
23934    } else {
23935      $expend.addClass('is-opened');
23936      $expend.height($menuExpend.outerHeight());
23937    }
23938  },
23939  closeExpend: function closeExpend(e) {
23940    e.preventDefault();
23941    var $wrapper = $(this).closest('.js-menu-panel-expend');
23942    $wrapper.removeClass('is-opened');
23943  }
23944};
23945module.exports = navigationPanel;
23946
23947},{}],39:[function(require,module,exports){
23948"use strict";
23949
23950var _ = require('underscore');
23951var newsList = {
23952  ui: {},
23953  newsJSON: {},
23954  init: function init() {
23955    this.bindUI();
23956    this.bindEvents();
23957    this.getData();
23958  },
23959  bindUI: function bindUI() {
23960    this.ui.$win = $(window);
23961    this.ui.$body = $('body');
23962    this.ui.$urlJson = $('.js-json-url').data('json');
23963    console.log(this.ui.$urlJson);
23964  },
23965  bindEvents: function bindEvents() {
23966    //this.ui.$btnProduct.on('click', $.proxy(this.openProduct, this));
23967  },
23968  getData: function getData(e) {
23969    $.getJSON(this.ui.$urlJson, function (data) {
23970      self.newsJSON = data;
23971    }).done(function (data) {
23972      // LOAD ok
23973    });
23974  }
23975};
23976module.exports = newsList;
23977
23978},{"underscore":8}],40:[function(require,module,exports){
23979"use strict";
23980
23981function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
23982function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
23983function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
23984function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
23985function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
23986function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
23987var Comparator = /*#__PURE__*/function () {
23988  function Comparator($panel, $btnPanel, storage) {
23989    _classCallCheck(this, Comparator);
23990    this.$panel = $panel;
23991    this.$btnPanel = $btnPanel;
23992    this.$el = $('.panel-comparator__inner');
23993    this.url = $panel.data('service');
23994    this.storage = storage;
23995    this.trans = $panel.data('i18n');
23996    this.init();
23997    this.bind();
23998  }
23999  return _createClass(Comparator, [{
24000    key: "init",
24001    value: function init() {
24002      var self = this;
24003      var reqData = {
24004        site: window.nexansConfig.site,
24005        language: document.documentElement.lang,
24006        ids: this.storage.data.familyIds
24007      };
24008      $.ajax({
24009        url: self.url,
24010        type: 'get',
24011        dataType: 'json',
24012        contentType: 'application/json',
24013        data: reqData,
24014        traditional: true
24015      }).done(function (data) {
24016        self.data = data;
24017        self.render();
24018      });
24019    }
24020  }, {
24021    key: "bind",
24022    value: function bind() {
24023      this.$el.click();
24024      var self = this;
24025      this.$el.on('click', '.btn-switch', function (e) {
24026        e.preventDefault();
24027        self.$el.toggleClass('highlighted');
24028      });
24029      this.$el.on('click', '.js-remove', function (e) {
24030        e.preventDefault();
24031        self.removeRow(parseInt($(this).data('index'), 10), $(this).data('id'));
24032      });
24033    }
24034  }, {
24035    key: "removeRow",
24036    value: function removeRow(index, id) {
24037      this.data.families.splice(index, 1);
24038      this.storage.delete(parseInt(id, 10));
24039      for (var i = 0; i < this.data.features.length; i++) {
24040        this.data.features[i].values.splice(index, 1);
24041      }
24042      $('body').trigger('comparator_update', [this.storage.count, true]);
24043      this.render();
24044    }
24045  }, {
24046    key: "getImageUrl",
24047    value: function getImageUrl(imageId) {
24048      return window.nexansConfig.eserviceDamServiceUrl + '/image/' + imageId + '?site=' + window.nexansConfig.site + '&variant=264x264&scaleType=FILL';
24049    }
24050  }, {
24051    key: "render",
24052    value: function render() {
24053      var output = '<table><thead><tr>';
24054      output += '<td></td>';
24055      for (var i = 0; i < this.data.families.length; i++) {
24056        output += '<td>';
24057        output += '<div class="actions text-current-small"><button class="js-remove" data-index="' + i + '" data-id="' + this.data.families[i].id + '" type="button"><span>' + this.trans.remove + '</span><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path fill="currentColor" fill-rule="evenodd" d="M10,8.58578644 L4.34314575,2.92893219 L2.92893219,4.34314575 L8.58578644,10 L2.92893219,15.6568542 L4.34314575,17.0710678 L10,11.4142136 L15.6568542,17.0710678 L17.0710678,15.6568542 L11.4142136,10 L17.0710678,4.34314575 L15.6568542,2.92893219 L10,8.58578644 Z"/></svg></button></div>';
24058        if ('imageId' in this.data.families[i] && this.data.families[i].imageId) {
24059          output += '<img src="' + this.getImageUrl(this.data.families[i].imageId) + '" alt="' + this.data.families[i].name + '">';
24060        }
24061        output += '<h3>' + this.data.families[i].name + '</h3>';
24062      }
24063      output += '</tr></thead><tbody>';
24064      for (var _i = 0; _i < this.data.features.length; _i++) {
24065        var same = this.data.features[_i].values.every(function (val, ind, arr) {
24066          return val === arr[0];
24067        });
24068        output += '<tr class="' + (same ? 'same' : 'diff') + '">';
24069        output += '<td class="title">' + this.data.features[_i].name + '</td>';
24070        for (var j = 0; j < this.data.features[_i].values.length; j++) {
24071          if (this.data.features[_i].values[j] === '##-##') {
24072            output += '<td>' + this.trans['specific_per_product'] + '</td>';
24073          } else {
24074            output += '<td>' + this.data.features[_i].values[j] + '</td>';
24075          }
24076        }
24077        output += '</tr>';
24078      }
24079      output += '</tbody></table>';
24080      this.$panel.removeAttr('style');
24081      this.$el.html(output);
24082      this.$panel.width(this.$el.find('table').width() + 40);
24083    }
24084  }]);
24085}();
24086var panelComparator = {
24087  ui: {},
24088  init: function init(storage) {
24089    this.bindUI();
24090    this.bindEvents(storage);
24091  },
24092  bindUI: function bindUI() {
24093    this.ui.$win = $(window);
24094    this.ui.$body = $('body');
24095    this.ui.$document = $(document);
24096    this.ui.$btnProduct = $('.js-open-panel-comparator');
24097    this.ui.$panel = $('.js-panel-comparator');
24098    this.ui.$container = this.ui.$panel.find('.js-panel-container');
24099    this.ui.$mask = $('.js-overlay');
24100    this.ui.$close = this.ui.$panel.find('.js-close-panel');
24101  },
24102  bindEvents: function bindEvents(storage) {
24103    var self = this;
24104    this.ui.$btnProduct.on('click', function (e) {
24105      self.openPanel(e, storage);
24106    });
24107    this.ui.$close.on('click', $.proxy(this.closePanel, this));
24108    this.ui.$mask.on('click', $.proxy(this.closePanel, this));
24109  },
24110  /* Desktop */
24111
24112  openPanel: function openPanel(e, storage) {
24113    e.preventDefault();
24114    if (!!this.ui.$btnProduct.hasClass('is-disabled')) return;
24115    this.ui.$body.addClass('is-locked');
24116    this.ui.$panel.addClass('is-open');
24117    this.ui.$mask.addClass('active');
24118    new Comparator(this.ui.$panel, this.ui.$btnProduct, storage);
24119  },
24120  closePanel: function closePanel(e) {
24121    e.preventDefault();
24122    this.ui.$body.removeClass('is-locked');
24123    this.ui.$panel.removeClass('is-open');
24124    this.ui.$mask.removeClass('active');
24125
24126    // Close by keyboard.
24127    if (e.keyCode === 27) {
24128      this.ui.$body.removeClass('is-locked');
24129      this.ui.$panel.removeClass('is-open');
24130      this.ui.$mask.removeClass('active');
24131    }
24132  }
24133};
24134module.exports = panelComparator;
24135
24136},{}],41:[function(require,module,exports){
24137"use strict";
24138
24139var contactForm = {
24140  ui: {},
24141  topic: [],
24142  valid: false,
24143  init: function init() {
24144    this.bindUI();
24145    this.initElements();
24146    this.reCaptchaSiteKey = this.ui.$contactForm.data("recaptcha_sitekey");
24147    this.bindEvents();
24148  },
24149  bindUI: function bindUI() {
24150    this.ui.$body = $('body');
24151    this.ui.$document = $(document);
24152    this.ui.$panel = $('.js-panel-contact');
24153    this.ui.$formContainer = '';
24154    this.ui.$contactForm = '';
24155    this.ui.$validation = '';
24156    this.ui.$errorInfo = '';
24157    this.ui.$required = '';
24158    this.ui.$selectRequired = '';
24159    this.ui.$topic = '';
24160    this.ui.$requiredEmail = '';
24161    this.ui.$validationMsg = '';
24162    this.ui.$success = '';
24163    this.ui.$error = '';
24164  },
24165  initElements: function initElements() {
24166    var _this = this;
24167    this.ui.$panel.each(function (n, item) {
24168      _this.ui.$formContainer = $(item).find('.js-form');
24169      _this.ui.$contactForm = $(item).find('.js-contact-form');
24170      _this.ui.$errorInfo = $(item).find('.js-error-info');
24171      _this.ui.$required = $(item).find('.js-required');
24172      _this.ui.$selectRequired = $(item).find('.js-select-required');
24173      _this.ui.$topic = $(item).find('.js-select-topic');
24174      _this.ui.$requiredEmail = $(item).find('.js-mail-required');
24175      _this.ui.$validation = $(item).find('.js-contact-validation');
24176      _this.ui.$validationMsg = $(item).closest('.panel-contact').find('.js-validation');
24177      _this.ui.$success = $(item).closest('.panel-contact').find('.js-contact-success');
24178      _this.ui.$error = $(item).closest('.panel-contact').find('.js-contact-error');
24179    });
24180  },
24181  bindEvents: function bindEvents() {
24182    var _this2 = this;
24183    this.ui.$topic.on('change', function (e) {
24184      return _this2.topics(e);
24185    });
24186    this.ui.$required.on('keyup', function (e) {
24187      return _this2.controlChange(e);
24188    });
24189    this.ui.$selectRequired.on('change', function (e) {
24190      return _this2.controlChange(e);
24191    });
24192    this.ui.$validation.on('click', function (e) {
24193      return _this2.controlForm(e);
24194    });
24195  },
24196  topics: function topics(e) {
24197    var id = $(e.currentTarget).find(':checkbox').attr('id');
24198
24199    // Tags list
24200    if (id.length) {
24201      if (this.topic.includes(id)) {
24202        var index = this.topic.indexOf(id);
24203        if (index !== -1) this.topic.splice(index, 1);
24204      } else {
24205        // add item on array tags.
24206        this.topic.push(id);
24207      }
24208    }
24209  },
24210  controlForm: function controlForm(e) {
24211    var _this3 = this;
24212    if (this.reCaptchaSiteKey) {
24213      var response = grecaptcha.getResponse(0);
24214      if (response.length == 0) {
24215        return false;
24216      }
24217    }
24218    var ofTop = $('body').offset().top;
24219
24220    // check all input.
24221    this.ui.$required.each(function (e, item) {
24222      if ($(item).val() == '') {
24223        // Set required input.
24224        $(item).addClass('is-required');
24225
24226        // Show msg error.
24227        _this3.ui.$errorInfo.fadeIn();
24228
24229        // back to top.
24230        $(item).closest('.panel-contact').scrollTop(ofTop);
24231      } else if ($(item).hasClass('is-required') && $(item).val() != "") {
24232        $(item).removeClass('is-required');
24233      }
24234      if (_this3.ui.$selectRequired.val() == null) {
24235        $(item).addClass('is-required');
24236      }
24237    });
24238
24239    // check input mail.
24240    this.ui.$requiredEmail.each(function (n, item) {
24241      if (item.checkValidity()) {
24242        $(item).parent().removeClass('warning');
24243      } else {
24244        $(item).parent().addClass('warning');
24245      }
24246    });
24247    if (!this.ui.$required.hasClass('is-required') && !this.ui.$requiredEmail.parent().hasClass('warning')) {
24248      this.valid = true;
24249    } else {
24250      this.valid = false;
24251    }
24252    if (this.valid) {
24253      this.ui.$validation.closest('.js-form').removeClass('form-hidden').hide();
24254      this.ui.$validationMsg.addClass('form-show').show();
24255      this.postForm(e);
24256      return false;
24257    } else {
24258      return false;
24259    }
24260  },
24261  controlChange: function controlChange(e) {
24262    if ($(e.currentTarget).val() != "") {
24263      $(e.currentTarget).removeClass('is-required');
24264    }
24265    $(e.currentTarget).removeClass('is-required');
24266  },
24267  postForm: function postForm(e) {
24268    e.preventDefault();
24269    var self = this,
24270      resourceUrl = this.ui.$contactForm.find("#url").val();
24271    var requestdata = {
24272      topics: this.topic,
24273      siteId: this.ui.$contactForm.find("#site").val(),
24274      pageId: this.ui.$contactForm.find("#pageid").val(),
24275      firstName: this.ui.$contactForm.find("input[name='first-name']").val(),
24276      lastName: this.ui.$contactForm.find("input[name='last-name']").val(),
24277      email: this.ui.$contactForm.find("input[name='email']").val(),
24278      phone: this.ui.$contactForm.find("input[name='phone-number']").val(),
24279      country: this.ui.$contactForm.find("select[name='country']").val(),
24280      company: this.ui.$contactForm.find("input[name='company']").val(),
24281      address: this.ui.$contactForm.find("input[name='address']").val(),
24282      postalCode: this.ui.$contactForm.find("input[name='postal-code']").val(),
24283      city: this.ui.$contactForm.find("input[name='city']").val(),
24284      subject: this.ui.$contactForm.find("input[name='subject']").val(),
24285      message: this.ui.$contactForm.find("textarea[name='message']").val(),
24286      hCaptchaToken: this.ui.$contactForm.find("textarea[name='h-captcha-response']").val(),
24287      emailCopy: this.ui.$contactForm.find("#send-copy").prop('checked')
24288    };
24289    $.ajax({
24290      url: resourceUrl,
24291      type: 'POST',
24292      data: JSON.stringify(requestdata),
24293      contentType: "application/json; charset=utf-8",
24294      dataType: 'json',
24295      success: function success(html, status) {
24296        self.ui.$success.show();
24297      },
24298      error: function error(result, status, _error) {
24299        self.ui.$error.show();
24300      }
24301    });
24302    this.valid = false;
24303  }
24304};
24305module.exports = contactForm;
24306
24307},{}],42:[function(require,module,exports){
24308"use strict";
24309
24310var contactFormSpe = {
24311  ui: {},
24312  valid: false,
24313  init: function init() {
24314    this.bindUI();
24315    this.initElements();
24316    this.reCaptchaSiteKey = this.ui.$contactForm.data("recaptcha_sitekey");
24317    this.bindEvents();
24318  },
24319  bindUI: function bindUI() {
24320    this.ui.$body = $('body');
24321    this.ui.$document = $(document);
24322    this.ui.$panel = $('.js-panel-contact-spe');
24323    this.ui.$formContainer = '';
24324    this.ui.$contactForm = '';
24325    this.ui.$validation = '';
24326    this.ui.$errorInfo = '';
24327    this.ui.$required = '';
24328    this.ui.$selectRequired = '';
24329    this.ui.$requiredEmail = '';
24330    this.ui.$validationMsg = '';
24331    this.ui.$success = '';
24332    this.ui.$error = '';
24333  },
24334  initElements: function initElements() {
24335    var _this = this;
24336    this.ui.$panel.each(function (n, item) {
24337      _this.ui.$formContainer = $(item).find('.js-form');
24338      _this.ui.$contactForm = $(item).find('.js-contact-form');
24339      _this.ui.$errorInfo = $(item).find('.js-error-info');
24340      _this.ui.$required = $(item).find('.js-required');
24341      _this.ui.$selectRequired = $(item).find('.js-select-required');
24342      _this.ui.$requiredEmail = $(item).find('.js-mail-required');
24343      _this.ui.$validation = $(item).find('.js-contact-validation');
24344      _this.ui.$validationMsg = $(item).closest('.panel-contact').find('.js-validation');
24345      _this.ui.$success = $(item).closest('.panel-contact').find('.js-contact-success');
24346      _this.ui.$error = $(item).closest('.panel-contact').find('.js-contact-error');
24347    });
24348  },
24349  bindEvents: function bindEvents() {
24350    var _this2 = this;
24351    this.ui.$required.on('keyup', function (e) {
24352      return _this2.controlChange(e);
24353    });
24354    this.ui.$selectRequired.on('change', function (e) {
24355      return _this2.controlChange(e);
24356    });
24357    this.ui.$validation.on('click', function (e) {
24358      return _this2.controlForm(e);
24359    });
24360  },
24361  controlForm: function controlForm(e) {
24362    var _this3 = this;
24363    if (this.reCaptchaSiteKey) {
24364      var response = grecaptcha.getResponse(1);
24365      if (response.length == 0) {
24366        return false;
24367      }
24368    }
24369    var ofTop = $('body').offset().top;
24370
24371    // check all input.
24372    this.ui.$required.each(function (e, item) {
24373      if ($(item).val() == '') {
24374        // Set required input.
24375        $(item).addClass('is-required');
24376
24377        // Show msg error.
24378        _this3.ui.$errorInfo.fadeIn();
24379
24380        // back to top.
24381        $(item).closest('.panel-contact').scrollTop(ofTop);
24382      } else if ($(item).hasClass('is-required') && $(item).val() != "") {
24383        $(item).removeClass('is-required');
24384      }
24385      if (_this3.ui.$selectRequired.val() == null) {
24386        $(item).addClass('is-required');
24387      }
24388    });
24389
24390    // check input mail.
24391    this.ui.$requiredEmail.each(function (n, item) {
24392      var check = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
24393      var val = $(item).val();
24394      if (check.test(val)) {
24395        $(item).parent().removeClass('warning');
24396      } else {
24397        $(item).parent().addClass('warning');
24398      }
24399    });
24400    if (!this.ui.$required.hasClass('is-required') && !this.ui.$requiredEmail.parent().hasClass('warning')) {
24401      this.valid = true;
24402    } else {
24403      this.valid = false;
24404    }
24405    if (this.valid) {
24406      this.ui.$validation.closest('.js-form').addClass('form-hidden').hide();
24407      this.ui.$validationMsg.addClass('form-show').show();
24408      this.postForm(e);
24409      return false;
24410    } else {
24411      return false;
24412    }
24413  },
24414  controlChange: function controlChange(e) {
24415    if ($(e.currentTarget).val() != "") {
24416      $(e.currentTarget).removeClass('is-required');
24417    }
24418    $(e.currentTarget).removeClass('is-required');
24419  },
24420  postForm: function postForm(e) {
24421    e.preventDefault();
24422    var self = this,
24423      resourceUrl = this.ui.$contactForm.find("#url").val();
24424    var requestdata = {
24425      contactId: this.ui.$contactForm.find("#contactid").val(),
24426      pageId: this.ui.$contactForm.find("#pageid").val(),
24427      siteId: this.ui.$contactForm.find("#site").val(),
24428      firstName: this.ui.$contactForm.find("input[name='first-name']").val(),
24429      lastName: this.ui.$contactForm.find("input[name='last-name']").val(),
24430      email: this.ui.$contactForm.find("input[name='email']").val(),
24431      phone: this.ui.$contactForm.find("input[name='phone-number']").val(),
24432      country: this.ui.$contactForm.find("select[name='country']").val(),
24433      company: this.ui.$contactForm.find("input[name='company']").val(),
24434      address: this.ui.$contactForm.find("input[name='address']").val(),
24435      postalCode: this.ui.$contactForm.find("input[name='postal-code']").val(),
24436      city: this.ui.$contactForm.find("input[name='city']").val(),
24437      subject: this.ui.$contactForm.find("input[name='subject']").val(),
24438      message: this.ui.$contactForm.find("textarea[name='message']").val(),
24439      hCaptchaToken: this.ui.$contactForm.find("textarea[name='h-captcha-response']").val(),
24440      emailCopy: this.ui.$contactForm.find("#send-copy-spe").prop('checked')
24441    };
24442    $.ajax({
24443      url: resourceUrl,
24444      type: 'POST',
24445      data: JSON.stringify(requestdata),
24446      contentType: "application/json; charset=utf-8",
24447      dataType: 'json',
24448      success: function success(html, status) {
24449        self.ui.$success.show();
24450      },
24451      error: function error(result, status, _error) {
24452        self.ui.$error.show();
24453      }
24454    });
24455    this.valid = false;
24456  }
24457};
24458module.exports = contactFormSpe;
24459
24460},{}],43:[function(require,module,exports){
24461"use strict";
24462
24463var contactPanel = {
24464  ui: {},
24465  init: function init() {
24466    this.bindUI();
24467    this.bindEvents();
24468  },
24469  bindUI: function bindUI() {
24470    this.ui.$body = $('body');
24471    this.ui.$document = $(document);
24472    this.ui.$checkboxes = $('.js-contact-checkboxes');
24473    this.ui.$hidden = $('#contactid');
24474    this.ui.$panel = $('.js-panel-contact');
24475    this.ui.$panelSpe = $('.js-panel-contact-spe');
24476    this.ui.$trigger = $('.js-toggle-contact');
24477    this.ui.$triggerSpe = $('.js-toggle-contact-spe');
24478    this.ui.$close = $('.js-close-contact');
24479    this.ui.$closeSpe = $('.js-close-contact-spe');
24480    this.ui.$mask = $('.js-overlay');
24481    this.ui.$btnClose = $('.js-close-panel');
24482  },
24483  bindEvents: function bindEvents() {
24484    var _this = this;
24485    this.ui.$trigger.on('click', function (e) {
24486      return _this.openPanel(e);
24487    });
24488    this.ui.$close.add(this.ui.$mask).on('click', function (e) {
24489      return _this.closePanel(e);
24490    });
24491    this.ui.$btnClose.add(this.ui.$mask).on('click', function (e) {
24492      return _this.closePanel(e);
24493    });
24494    this.ui.$triggerSpe.on('click', function (e) {
24495      return _this.openPanelSpe(e);
24496    });
24497    this.ui.$closeSpe.add(this.ui.$mask).on('click', function (e) {
24498      return _this.closePanelSpe(e);
24499    });
24500    //this.ui.$document.on('keyup', (e) => this.closePanel(e));
24501  },
24502  openPanel: function openPanel(e) {
24503    e.preventDefault();
24504    var $el = $(e.currentTarget),
24505      categoryid = $el.data('categoryid'),
24506      // $checkboxes = this.ui.$checkboxes.find('input[type="checkbox"]'),
24507      $selfcheck = this.ui.$checkboxes.find('#' + categoryid);
24508    if ($selfcheck.length) {
24509      // $checkboxes.prop('checked', false);
24510      $selfcheck.prop('checked', true);
24511    }
24512    this.ui.$body.addClass('is-locked');
24513    this.ui.$panel.add(this.ui.$mask).addClass('active');
24514  },
24515  openPanelSpe: function openPanelSpe(e) {
24516    e.preventDefault();
24517    var $el = $(e.currentTarget),
24518      contactid = $el.data('contactid'),
24519      categoryid = $el.data('categoryid');
24520    if (contactid && contactid.length > 1) {
24521      this.ui.$hidden.val(contactid);
24522    }
24523    if (!this.ui.$hidden.val() || '' == this.ui.$hidden.val()) {
24524      // no specific contact -> fallback to generic panel
24525      this.openPanel(e);
24526      return;
24527    }
24528    if (categoryid && '' != categoryid) {
24529      $selfcheck = this.ui.$checkboxes.find('#' + categoryid);
24530      if ($selfcheck.length) {
24531        $selfcheck.prop('checked', true);
24532      }
24533    }
24534    this.ui.$body.addClass('is-locked');
24535    this.ui.$panelSpe.add(this.ui.$mask).addClass('active');
24536  },
24537  closePanel: function closePanel(e) {
24538    e.preventDefault();
24539    var $el = $(e.currentTarget);
24540    if ($('.js-validation').hasClass('form-show') || $('.js-form').hasClass('form-hidden')) {
24541      $('.js-validation').removeClass('form-show').hide();
24542      $('.js-form').removeClass('form-hidden').show();
24543    }
24544    this.ui.$body.removeClass('is-locked');
24545    this.ui.$panel.add(this.ui.$mask).removeClass('active');
24546
24547    // Close by keyboard.
24548    if (e.keyCode === 27) {
24549      this.ui.$panel.add(this.ui.$mask).removeClass('active');
24550      this.ui.$body.removeClass('is-locked');
24551    }
24552  },
24553  closePanelSpe: function closePanelSpe(e) {
24554    e.preventDefault();
24555    var $el = $(e.currentTarget);
24556    if ($('.js-validation').hasClass('form-show') || $('.js-form').hasClass('form-hidden')) {
24557      $('.js-validation').removeClass('form-show').hide();
24558      $('.js-form').removeClass('form-hidden').show();
24559    }
24560    this.ui.$body.removeClass('is-locked');
24561    this.ui.$panelSpe.add(this.ui.$mask).removeClass('active');
24562
24563    // Close by keyboard.
24564    if (e.keyCode === 27) {
24565      this.ui.$panelSpe.add(this.ui.$mask).removeClass('active');
24566      this.ui.$body.removeClass('is-locked');
24567    }
24568  }
24569};
24570module.exports = contactPanel;
24571
24572},{}],44:[function(require,module,exports){
24573"use strict";
24574
24575var dopPanel = {
24576  ui: {},
24577  init: function init() {
24578    this.bindUI();
24579    this.bindEvents();
24580  },
24581  bindUI: function bindUI() {
24582    this.ui.$body = $('body');
24583    this.ui.$document = $(document);
24584    this.ui.$panel = $('.js-panel-dop');
24585    this.ui.$trigger = $('.js-toggle-dop');
24586    this.ui.$close = $('.js-close-dop');
24587    this.ui.$mask = $('.js-overlay');
24588    this.ui.$btnClose = $('.js-close-panel');
24589  },
24590  bindEvents: function bindEvents() {
24591    var _this = this;
24592    this.ui.$trigger.on('click', function (e) {
24593      return _this.openPanel(e);
24594    });
24595    this.ui.$close.add(this.ui.$mask).on('click', function (e) {
24596      return _this.closePanel(e);
24597    });
24598    this.ui.$btnClose.add(this.ui.$mask).on('click', function (e) {
24599      return _this.closePanel(e);
24600    });
24601    //this.ui.$document.on('keyup', (e) => this.closePanel(e));
24602  },
24603  openPanel: function openPanel(e) {
24604    e.preventDefault();
24605    this.ui.$body.addClass('is-locked');
24606    this.ui.$panel.add(this.ui.$mask).addClass('active');
24607  },
24608  closePanel: function closePanel(e) {
24609    e.preventDefault();
24610    var $el = $(e.currentTarget);
24611    this.ui.$body.removeClass('is-locked');
24612    this.ui.$panel.add(this.ui.$mask).removeClass('active');
24613
24614    // Close by keyboard.
24615    if (e.keyCode === 27) {
24616      this.ui.$panel.add(this.ui.$mask).removeClass('active');
24617      this.ui.$body.removeClass('is-locked');
24618    }
24619  }
24620};
24621module.exports = dopPanel;
24622
24623},{}],45:[function(require,module,exports){
24624"use strict";
24625
24626var panelGovernance = {
24627  ui: {},
24628  governanceJSON: {},
24629  init: function init() {
24630    this.bindUI();
24631    this.bindEvents();
24632    this.getData();
24633  },
24634  bindUI: function bindUI() {
24635    this.ui.$win = $(window);
24636    this.ui.$body = $('body');
24637    this.ui.$overlay = $('.js-overlay');
24638    this.ui.$trigger = $('.js-gp-trigger');
24639    this.ui.$close = $('.js-gp-close');
24640    this.ui.$panel = $('.js-gp-panel');
24641    this.ui.$cover = $('.js-gp-cover');
24642    this.ui.$name = $('.js-gp-name');
24643    this.ui.$title = $('.js-gp-title');
24644    this.ui.$bio = $('.js-gp-bio');
24645  },
24646  bindEvents: function bindEvents() {
24647    this.ui.$trigger.on('click', $.proxy(this.openPanel, this));
24648    this.ui.$close.on('click', $.proxy(this.closePanel, this));
24649    this.ui.$overlay.on('click', $.proxy(this.closePanel, this));
24650  },
24651  // getData: function getData(e) {
24652  //     // TODO : Get JSON URL form data attribut
24653  //     var url = window.oojson.url;
24654  //
24655  //     $.getJSON(url, function(data) {
24656  //         self.governanceJSON = data;
24657  //     }).done(function(data) {
24658  //         // Everything is alright
24659  //     });
24660  // },
24661
24662  getData: function getData(t) {
24663    if (window.oojson.data) {
24664      self.governanceJSON = window.oojson.data;
24665    } else {
24666      var e = window.oojson.url;
24667      $.getJSON(e, function (t) {
24668        self.governanceJSON = t;
24669      }).done(function (t) {});
24670    }
24671  },
24672  openPanel: function openPanel(e) {
24673    e.preventDefault();
24674    var $el = $(e.currentTarget),
24675      id = $el.data('bio');
24676    this.ui.$overlay.addClass('active');
24677    this.ui.$panel.addClass('active');
24678    this.ui.$body.addClass('is-locked');
24679    this.fillPanel(id);
24680  },
24681  // closePanel: function closePanel(e) {
24682  //     e.preventDefault();
24683  //
24684  //     this.ui.$overlay.removeClass('active');
24685  //     this.ui.$panel.removeClass('active');
24686  //     this.ui.$body.removeClass('is-locked');
24687  // },
24688
24689  closePanel: function closePanel(e) {
24690    e.preventDefault();
24691
24692    // Close by btn close or mask.
24693    if (this.ui.$panel.hasClass('active') || $(e.currentTarget).hasClass('js-gp-mask')) {
24694      this.ui.$overlay.removeClass('active');
24695      this.ui.$panel.removeClass('active');
24696      this.ui.$body.removeClass('is-locked');
24697    }
24698    ;
24699  },
24700  fillPanel: function fillPanel(id) {
24701    this.ui.$cover.css('background-image', 'url(' + self.governanceJSON[id]["cover"] + ')');
24702    this.ui.$name.html(self.governanceJSON[id]["name"]);
24703    this.ui.$title.html(self.governanceJSON[id]["title"]);
24704    this.ui.$bio.html(self.governanceJSON[id]["bio"]);
24705  }
24706};
24707module.exports = panelGovernance;
24708
24709},{}],46:[function(require,module,exports){
24710"use strict";
24711
24712var panelLogin = {
24713  ui: {},
24714  init: function init() {
24715    this.bindUI();
24716    this.bindEvents();
24717  },
24718  bindUI: function bindUI() {
24719    this.ui.$document = $(document);
24720    var forms = $('.js-user-login-form');
24721    this.ui.$loginForm = forms.find('.js-user-sign-form');
24722    this.ui.$resetForm = forms.find('.js-user-reset-form');
24723    this.ui.$showResetForm = forms.find('.js-show-user-reset-form');
24724    this.ui.$showSignForm = forms.find('.js-show-user-sign-form');
24725    this.ui.$signInput = this.ui.$loginForm.find('.js-email-field');
24726    this.ui.$resetInput = this.ui.$resetForm.find('.js-email-field');
24727  },
24728  bindEvents: function bindEvents() {
24729    var self = this;
24730    this.ui.$showResetForm.on('click', function (e) {
24731      e.preventDefault();
24732      self.ui.$loginForm.hide();
24733      self.ui.$resetForm.show();
24734    });
24735    this.ui.$showSignForm.on('click', function (e) {
24736      e.preventDefault();
24737      self.ui.$resetForm.hide();
24738      self.ui.$loginForm.show();
24739    });
24740    this.ui.$signInput.on('input', function () {
24741      self.ui.$resetInput.val($(this).val());
24742    });
24743    this.ui.$resetInput.on('input', function () {
24744      self.ui.$signInput.val($(this).val());
24745    });
24746    this.ui.$loginForm.submit(function (e) {
24747      e.preventDefault();
24748      var data = {};
24749      var url = window.nexans_ctx + '/.rest/user/v1/authenticate';
24750      if (self.ui.$loginForm.find('button[type="submit"]').hasClass('user-login')) {
24751        // user log-in with un/pw
24752        var usernameInput = self.ui.$loginForm.find('input[name=mgnlUserId]');
24753        usernameInput.removeClass('error');
24754        var passwordInput = self.ui.$loginForm.find('input[name=mgnlUserPSWD]');
24755        passwordInput.removeClass('error');
24756        self.ui.$loginForm.find('.error-message').removeClass('error');
24757        var username = usernameInput.val();
24758        var password = passwordInput.val();
24759        if (!password) {
24760          passwordInput.addClass('error');
24761          passwordInput.focus();
24762        }
24763        if (!username) {
24764          usernameInput.addClass('error');
24765          usernameInput.focus();
24766        }
24767        if (!username || !password) {
24768          return;
24769        }
24770        data.userId = username;
24771        data.password = password;
24772        //url += '/current?mgnlUserId=' + username + '&mgnlUserPSWD=' + password;
24773        //url += '/authenticate?foo=bar';
24774        jQuery.ajax({
24775          method: "POST",
24776          url: url,
24777          data: self.ui.$loginForm.serialize(),
24778          success: function success(data) {
24779            location.reload();
24780          }
24781        }).fail(function (xhr, status, error) {
24782          console.error("Login failed with status ".concat(xhr.status));
24783          usernameInput.addClass('error').focus();
24784          passwordInput.addClass('error');
24785          self.ui.$loginForm.find('.error-message').addClass('error');
24786        });
24787      } else {
24788        // editor log-in through cms user session
24789        //url += '/authenticate?nexans-site=${window.nexans_site}';
24790        jQuery.ajax({
24791          url: url,
24792          type: 'GET',
24793          contentType: 'application/json',
24794          success: function success(data) {
24795            location.reload();
24796          }
24797        }).fail(function (xhr, status, error) {
24798          console.error("Login failed with status ".concat(xhr.status));
24799          self.ui.$loginForm.find('.error-message').addClass('error');
24800        });
24801      }
24802    });
24803  }
24804};
24805module.exports = panelLogin;
24806
24807},{}],47:[function(require,module,exports){
24808"use strict";
24809
24810var panelNewsletter = {
24811  ui: {},
24812  init: function init() {
24813    this.bindUI();
24814    this.bindEvents();
24815  },
24816  bindUI: function bindUI() {
24817    this.ui.$win = $(window);
24818    this.ui.$body = $('body');
24819    this.ui.$document = $(document);
24820    this.ui.$btnProduct = $('.js-open-panel-newsletter');
24821    this.ui.$panel = $('.js-panel-newsletter');
24822    this.ui.$container = this.ui.$panel.find('.js-panel-container');
24823    this.ui.$mask = $('.js-overlay');
24824    this.ui.$close = this.ui.$panel.find('.js-close-panel');
24825
24826    // list
24827    this.ui.entry = $('.js-list-item');
24828    //this.ui.$subEntry          = $('.js-list-subnav');
24829  },
24830  bindEvents: function bindEvents() {
24831    this.ui.$btnProduct.on('click', $.proxy(this.openPanel, this));
24832    this.ui.$close.on('click', $.proxy(this.closePanel, this));
24833    //this.ui.$document.on('keyup', $.proxy(this.closePanel, this));
24834    this.ui.$mask.on('click', $.proxy(this.closePanel, this));
24835    // this.ui.entry.on('mouseenter', $.proxy(this.showSubNav, this));
24836
24837    // nav mobile version
24838    if (this.ui.$win.outerWidth >= 767) {
24839      this.ui.entry.on('click', $.proxy(this.mobShowSubNav, this));
24840    }
24841  },
24842  /* Desktop */
24843
24844  openPanel: function openPanel(e) {
24845    e.preventDefault();
24846
24847    // this.ui.$body.addClass('is-panel-solution-open');
24848    this.ui.$body.addClass('is-locked');
24849    this.ui.$panel.addClass('is-open');
24850    this.ui.$mask.addClass('active');
24851  },
24852  closePanel: function closePanel(e) {
24853    e.preventDefault();
24854    this.ui.$body.removeClass('is-locked');
24855    this.ui.$panel.removeClass('is-open');
24856    this.ui.$mask.removeClass('active');
24857
24858    // Close by keyboard.
24859    if (e.keyCode === 27) {
24860      this.ui.$body.removeClass('is-locked');
24861      this.ui.$panel.removeClass('is-open');
24862      this.ui.$mask.removeClass('active');
24863    }
24864  },
24865  showSubNav: function showSubNav(e) {
24866    //get this
24867    var $this = $(e.currentTarget);
24868
24869    //remove all subnav.
24870    this.ui.entry.removeClass('is-open');
24871    $this.addClass('is-open');
24872  },
24873  hideSubNav: function hideSubNav(e) {
24874    setTimeout(function () {
24875      $(e.currentTarget).removeClass('is-open');
24876    }, 200);
24877  },
24878  /* Mobile nav  */
24879
24880  mobShowSubNav: function mobShowSubNav(e) {
24881    e.preventDefault();
24882    console.log(e);
24883  }
24884};
24885module.exports = panelNewsletter;
24886
24887},{}],48:[function(require,module,exports){
24888"use strict";
24889
24890var loadProductPanel = {
24891  ui: {},
24892  productJSON: {},
24893  products: [],
24894  related: [],
24895  init: function init() {
24896    this.bindUI();
24897    this.bindEvents();
24898    this.getData();
24899  },
24900  bindUI: function bindUI() {
24901    this.ui.$win = $(window);
24902    this.ui.$body = $('body');
24903    this.ui.$document = $(document);
24904    this.ui.$openSolution = $('.js-open-panel-solution');
24905    this.ui.$btnProduct = $('.js-load-product');
24906    this.ui.$panel = $('.js-panel-product');
24907    this.ui.$overlay = $('.js-overlay');
24908    this.ui.$close = this.ui.$panel.find('.js-close-panel');
24909
24910    // Panel elements
24911    this.ui.$jsonCategory = $('.js-json-category');
24912    this.ui.$jsonName = $('.js-json-name');
24913    this.ui.$jsonCover = $('.js-json-cover');
24914    this.ui.$jsonInfos = $('.js-json-infos');
24915    this.ui.$jsonUrl = $('.js-json-url');
24916    this.ui.$jsonRelated = $('.js-json-related');
24917    this.ui.$jsonCoverMobile = $('.js-json-cover-mobile');
24918  },
24919  bindEvents: function bindEvents() {
24920    var _this = this;
24921    this.ui.$btnProduct.on('click', $.proxy(this.openProduct, this));
24922    this.ui.$close.on('click', $.proxy(this.closePanel, this));
24923    this.ui.$overlay.on('click', $.proxy(this.closePanel, this));
24924    //this.ui.$document.on('keyup', $.proxy(this.closePanel, this));
24925
24926    this.ui.$openSolution.on('click', function (e) {
24927      return _this.showSolution(e);
24928    });
24929  },
24930  // getData: function getData(e) {
24931  //     var url = window.oojson.url;
24932  //
24933  //     $.getJSON(url, function(data) {
24934  //         self.productJSON = data;
24935  //     }).done(function(data) {
24936  //     });
24937  // },
24938
24939  getData: function getData(e) {
24940    if (window.oojson.data) {
24941      self.productJSON = window.oojson.data;
24942    } else {
24943      var e = window.oojson.url;
24944      $.getJSON(e, function (t) {
24945        self.productJSON = t;
24946      }).done(function (t) {});
24947    }
24948  },
24949  openProduct: function openProduct(e) {
24950    // get ID of product selected.
24951    var $el = $(e.currentTarget),
24952      id = $el.data('productid');
24953    this.clearProduct();
24954
24955    // Load product by ID.
24956    this.loadProduct(id);
24957
24958    // Open overlay.
24959    this.ui.$overlay.addClass('active');
24960    this.ui.$panel.addClass('is-open');
24961    this.ui.$body.addClass('is-locked');
24962  },
24963  showSolution: function showSolution(e) {
24964    e.preventDefault();
24965    this.ui.$panel.removeClass('is-open');
24966  },
24967  closePanel: function closePanel(e) {
24968    e.preventDefault();
24969    this.ui.$body.removeClass('is-locked');
24970    this.ui.$panel.removeClass('is-open');
24971    this.ui.$overlay.removeClass('active');
24972
24973    // Close by keyboard.
24974    if (e.keyCode === 27) {
24975      this.ui.$body.removeClass('is-locked');
24976      this.ui.$panel.removeClass('is-open');
24977      this.ui.$overlay.removeClass('active');
24978    }
24979  },
24980  clearProduct: function clearProduct() {
24981    // Clear planel product.
24982    this.ui.$jsonCategory.html('');
24983    this.ui.$jsonName.html('');
24984    this.ui.$jsonCover.attr('src', '');
24985    this.ui.$jsonCoverMobile.attr('src', '');
24986    this.ui.$jsonInfos.html('');
24987    this.ui.$jsonUrl.attr('href', '').removeClass('hidden');
24988    this.ui.$jsonRelated.html('');
24989    this.ui.$openSolution.addClass('hidden');
24990  },
24991  loadProduct: function loadProduct(id) {
24992    //  ID of product selected.
24993    var reference_id = id;
24994
24995    // Foreach all product items form JSON.
24996    for (var i = 0; i < self.productJSON.length; i++) {
24997      // Get product select by ID.
24998      if (self.productJSON[i]["id"] == reference_id) {
24999        var id = self.productJSON[i]["id"],
25000          categoryID = self.productJSON[i]["category_id"];
25001
25002        //console.log(self.productJSON[i]["name"]);
25003        this.ui.$jsonCategory.html(self.productJSON[i]["category_name"]);
25004        this.ui.$jsonName.html(self.productJSON[i]["name"]);
25005        this.ui.$jsonCover.attr('src', self.productJSON[i]["cover_large"]);
25006        this.ui.$jsonCoverMobile.attr('src', self.productJSON[i]["cover_mobile"]);
25007        this.ui.$jsonInfos.html(self.productJSON[i]["resume"]);
25008        if (self.productJSON[i]["url_product"] && self.productJSON[i]["url_product"].length) {
25009          this.ui.$jsonUrl.attr('href', self.productJSON[i]["url_product"]);
25010          this.ui.$openSolution.addClass('hidden');
25011        } else {
25012          this.ui.$jsonUrl.addClass('hidden');
25013          this.ui.$openSolution.removeClass('hidden');
25014        }
25015        this.realatedProduct(id, categoryID);
25016      }
25017    }
25018  },
25019  realatedProduct: function realatedProduct(id, categoryID) {
25020    var related = [];
25021
25022    // Search product related
25023    $.each(self.productJSON, function () {
25024      // select product with same category ID
25025      if (this.category_id == categoryID) {
25026        // escape current product with ID
25027        // push infos related in array
25028        if (this.id != id) {
25029          related.push(this);
25030        }
25031      }
25032    });
25033
25034    // Shuffle array for set random position of elements
25035    function Shuffle(o) {
25036      for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
25037      return o;
25038    }
25039    ;
25040    var arrayShuff = Shuffle(related);
25041    this.buildRelated(arrayShuff);
25042  },
25043  buildRelated: function buildRelated(related) {
25044    var nb = 0;
25045
25046    // Get infos form array
25047    $.each(related, function () {
25048      nb++;
25049
25050      // select only 2 items form Array
25051      if (nb < 3) {
25052        var relatedTpl = '<div class="panel-product__content__related--cell">' + '<div class="box box__item trailer-60">' + '<div class="box__item__cover box__item__cover--full js-related-item" data-productid="' + this.id + '">' + '<img src="' + this.cover_small + '" alt="">' + '</div>' + '<div class="box__item__info">' + this.category_name + '</div>' + '<div class="box box__item trailer-60">' + '<div class="box__item__title js-related-item" data-productid="' + this.id + '">' + this.name + '</div>' + ' </div> </div>';
25053        $('.js-json-related').append(relatedTpl);
25054      }
25055    });
25056
25057    // Get new items and bind events.
25058    this.ui.$relatedItem = this.ui.$panel.find('.js-related-item');
25059    this.ui.$relatedItem.on('click', $.proxy(this.reloadPanel, this));
25060  },
25061  reloadPanel: function reloadPanel(e) {
25062    // get ID of product selected.
25063    var $el = $(e.currentTarget),
25064      id = $el.data('productid');
25065
25066    // Clear panel
25067    this.clearProduct();
25068
25069    // Load panel width ID
25070    this.loadProduct(id);
25071
25072    // scroll animation
25073    this.ui.$panel.animate({
25074      scrollTop: $('body').offset().top
25075    }, '500');
25076  }
25077};
25078module.exports = loadProductPanel;
25079
25080},{}],49:[function(require,module,exports){
25081"use strict";
25082
25083var panelSolutions = {
25084  ui: {},
25085  init: function init() {
25086    this.bindUI();
25087    this.bindEvents();
25088  },
25089  bindUI: function bindUI() {
25090    this.ui.$win = $(window);
25091    this.ui.$body = $('body');
25092    this.ui.$document = $(document);
25093    this.ui.$btnProduct = $('.js-open-panel-solution');
25094    this.ui.$panel = $('.js-panel-solution');
25095    this.ui.$btnBack = $('.js-sub-back');
25096    this.ui.$container = this.ui.$panel.find('.js-panel-container');
25097    this.ui.$mask = $('.js-overlay');
25098    this.ui.$close = this.ui.$panel.find('.js-close-panel');
25099
25100    // list
25101    this.ui.entry = $('.js-list-item');
25102    this.ui.wrapper = $('.js-list-wrapper');
25103  },
25104  bindEvents: function bindEvents() {
25105    // Modal.
25106    this.ui.$btnProduct.on('click', $.proxy(this.openPanel, this));
25107    this.ui.$close.on('click', $.proxy(this.closePanel, this));
25108    this.ui.$mask.on('click', $.proxy(this.closePanel, this));
25109
25110    // List.
25111    this.ui.entry.on('click', $.proxy(this.showSubNav, this));
25112
25113    // Only mobile version.
25114    this.ui.$btnBack.on('click', $.proxy(this.backMobile, this));
25115  },
25116  /* Desktop */
25117
25118  openPanel: function openPanel(e) {
25119    e.preventDefault();
25120
25121    // this.ui.$body.addClass('is-panel-solution-open');
25122    this.ui.$body.addClass('is-locked');
25123    this.ui.$panel.addClass('is-open');
25124    this.ui.$mask.addClass('active');
25125  },
25126  closePanel: function closePanel(e) {
25127    e.preventDefault();
25128    this.ui.$body.removeClass('is-locked');
25129    this.ui.$panel.removeClass('is-open');
25130    this.ui.$mask.removeClass('active');
25131
25132    // Close by keyboard.
25133    if (e.keyCode === 27) {
25134      this.ui.$body.removeClass('is-locked');
25135      this.ui.$panel.removeClass('is-open');
25136      this.ui.$mask.removeClass('active');
25137    }
25138  },
25139  showSubNav: function showSubNav(e) {
25140    //  e.preventDefault();
25141
25142    //get this
25143    var $this = $(e.currentTarget);
25144
25145    //remove all subnav.
25146    this.ui.entry.removeClass('is-open');
25147    this.ui.entry.parent().removeClass('is-translate');
25148    $this.addClass('is-open');
25149    $this.parent().addClass('is-translate');
25150  },
25151  backMobile: function backMobile(e) {
25152    // e.preventDefault();
25153
25154    //get this.
25155    var $this = $(e.currentTarget);
25156    $('.js-list-wrapper').removeClass('is-translate');
25157    setTimeout(function () {
25158      $('.js-list-wrapper').removeClass('is-translate');
25159      $('.js-list-item').removeClass('is-open');
25160    }, 100);
25161  }
25162};
25163module.exports = panelSolutions;
25164
25165},{}],50:[function(require,module,exports){
25166"use strict";
25167
25168function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
25169function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
25170function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
25171function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
25172function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
25173function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
25174var StockPanel = /*#__PURE__*/function () {
25175  function StockPanel(trigger) {
25176    var _this = this;
25177    _classCallCheck(this, StockPanel);
25178    this.$trigger = $(trigger);
25179    this.$panel = $(this.$trigger.attr('href'));
25180    this.$field = $('#' + this.$trigger.data('fieldid'));
25181    this.$pager = this.$panel.find('.panel-stock-pager');
25182    this.$table = this.$panel.find('.js-table-stock');
25183    this.$tableBody = this.$panel.find('.js-table-stock tbody');
25184    this.$asyncLikeForm = this.$panel.find('.async-like-form');
25185    this.$searchForm = this.$panel.find('.js-stocks-form');
25186    this.$searchInput = this.$searchForm.find('.js-search-input');
25187    this.$serviceError = this.$panel.find('.service-error');
25188    this.initialized = false;
25189    this.searchTerm = null;
25190    $(document).on('uiLoaded', function () {
25191      _this.panel = _this.$panel.data('panel');
25192    });
25193    this.$panel.on('opened', function () {
25194      _this.init();
25195    });
25196    this.activePage = 0;
25197  }
25198  return _createClass(StockPanel, [{
25199    key: "init",
25200    value: function init() {
25201      if (!this.initialized) {
25202        this.bind();
25203        this.initialized = true;
25204      }
25205      var oldSearch = this.searchTerm;
25206      if (!this.$searchInput.val() && this.$field.val()) {
25207        this.$searchInput.val(this.$field.val());
25208      }
25209      this.searchTerm = this.$searchInput.val();
25210      if (this.searchTerm.length > 1) {
25211        if (oldSearch !== this.searchTerm) {
25212          this.loadData();
25213        }
25214      } else {
25215        this.$table.hide();
25216        this.$pager.hide();
25217      }
25218    }
25219  }, {
25220    key: "bind",
25221    value: function bind() {
25222      var _this2 = this;
25223      var self = this;
25224      this.$pager.on('click', 'a', this.pagerNav.bind(this));
25225      this.$searchForm.on('submit', function (e) {
25226        e.preventDefault();
25227        _this2.$serviceError.hide();
25228        _this2.searchTerm = _this2.$searchInput.val();
25229        _this2.activePage = 0;
25230        _this2.loadData();
25231      });
25232      this.$tableBody.on('click', 'tr', function () {
25233        self.panel.close();
25234        self.$field.val($(this).data('ref')).trigger('stock-panel-update');
25235      });
25236    }
25237  }, {
25238    key: "loadData",
25239    value: function loadData() {
25240      var _this3 = this;
25241      this.$asyncLikeForm.addClass('loading');
25242      $.ajax({
25243        url: this.$searchForm.attr('action'),
25244        data: JSON.stringify({
25245          searchTerm: this.searchTerm,
25246          currentPage: this.activePage
25247        }),
25248        method: "POST",
25249        contentType: "application/json"
25250      }).done(function (data, textStatus, jqXHR) {
25251        _this3.$asyncLikeForm.removeClass('loading');
25252        _this3.numPages = data.numPages;
25253        _this3.$table.show();
25254        if (_this3.numPages > 1) {
25255          _this3.$pager.show();
25256          _this3.populatePager();
25257        } else {
25258          _this3.$pager.hide();
25259        }
25260        if (data.items.length < 1) {
25261          _this3.emptyTable(data);
25262          _this3.$serviceError.show();
25263        } else {
25264          _this3.fillTable(data);
25265          _this3.populatePager();
25266        }
25267      }).fail(function (xhr, status, error) {
25268        _this3.$serviceError.show();
25269      });
25270    }
25271  }, {
25272    key: "emptyTable",
25273    value: function emptyTable() {
25274      this.$tableBody.empty();
25275    }
25276  }, {
25277    key: "fillTable",
25278    value: function fillTable(data) {
25279      var contents = '';
25280      for (var i = 0; i < data.items.length; i++) {
25281        contents += '<tr data-ref="' + data.items[i].nexansRef + '"><td>' + data.items[i].nexansRef + '</td><td>' + data.items[i].countryRef + '</td><td>' + data.items[i].name + '</td></tr>';
25282      }
25283      this.$tableBody.html(contents);
25284    }
25285  }, {
25286    key: "populatePager",
25287    value: function populatePager() {
25288      var items = '';
25289      var start = Math.max(0, this.activePage - 2);
25290      if (start == 1) start = 0;
25291      var end = Math.min(this.numPages - 1, this.activePage + 2);
25292      if (end == this.numPages - 2) end = this.numPages - 1;
25293      if (start > 0) {
25294        items += '<li class="pager__list-item"><a href="#0">1</a></li>';
25295        items += '<li class="pager__list-item"><span>...</span></li>';
25296      }
25297      for (var i = start; i <= end; i++) {
25298        items += '<li class="pager__list-item"><a ' + (i == this.activePage ? 'class="is-active" ' : '') + 'href="#' + i + '">' + (i + 1) + '</a></li>';
25299      }
25300      if (end < this.numPages - 2) {
25301        items += '<li class="pager__list-item"><span>...</span></li>';
25302        items += '<li class="pager__list-item"><a href="#' + (this.numPages - 1) + '">' + this.numPages + '</a></li>';
25303      }
25304      this.$pager.find('.pager__list').html(items);
25305    }
25306  }, {
25307    key: "pagerNav",
25308    value: function pagerNav(e) {
25309      e.preventDefault();
25310      var $link = $(e.currentTarget);
25311      if ($link.parent().hasClass('pager__list-item')) {
25312        this.activePage = parseInt($link.attr('href').substring(1), 10);
25313      } else {
25314        if ($link.hasClass('pager__round--left')) {
25315          this.activePage = Math.max(0, this.activePage - 1);
25316        } else if ($link.hasClass('pager__round--right')) {
25317          this.activePage = Math.min(this.numPages - 1, this.activePage + 1);
25318        }
25319      }
25320      this.refreshItems();
25321    }
25322  }, {
25323    key: "refreshItems",
25324    value: function refreshItems() {
25325      this.loadData();
25326    }
25327  }]);
25328}();
25329;
25330var stockPanel = {
25331  init: function init() {
25332    $('.js-panel-trigger-stock').each(function () {
25333      new StockPanel(this);
25334    });
25335  }
25336};
25337module.exports = stockPanel;
25338
25339},{}],51:[function(require,module,exports){
25340"use strict";
25341
25342function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
25343function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
25344function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
25345function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
25346function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
25347function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
25348var Panel = /*#__PURE__*/function () {
25349  function Panel(el, mask, body) {
25350    _classCallCheck(this, Panel);
25351    this.el = el;
25352    this.$el = $(el);
25353    this.$mask = mask;
25354    this.$body = body;
25355    this.bind();
25356  }
25357  return _createClass(Panel, [{
25358    key: "bind",
25359    value: function bind() {
25360      var self = this;
25361      $('.js-panel-trigger').each(function () {
25362        if (this.getAttribute('href').substr(1) == self.el.id) {
25363          var trigger = this;
25364          $(this).on('click', function (e) {
25365            e.preventDefault();
25366            self.open(trigger);
25367          });
25368        }
25369      });
25370      this.$el.find('.js-close-panel').on('click', function (e) {
25371        e.preventDefault();
25372        self.close();
25373      });
25374      this.$mask.on('click', function (e) {
25375        self.close();
25376      });
25377    }
25378  }, {
25379    key: "open",
25380    value: function open(trigger) {
25381      this.$body.addClass('is-locked');
25382      this.$el.addClass('active');
25383      this.$mask.addClass('active');
25384      this.$el.trigger('opened', trigger);
25385      var self = this;
25386      $(document).on('keyup.panels', function (e) {
25387        if (e.key == "Escape") {
25388          self.close();
25389        }
25390      });
25391    }
25392  }, {
25393    key: "close",
25394    value: function close() {
25395      this.$body.removeClass('is-locked');
25396      this.$el.removeClass('active');
25397      this.$mask.removeClass('active');
25398      this.$el.trigger('closed');
25399      $(document).off('keyup.panels');
25400    }
25401  }]);
25402}();
25403var panels = {
25404  init: function init() {
25405    var $mask = $('.js-overlay');
25406    var $body = $('body');
25407    $('.js-panel').each(function () {
25408      $(this).data('panel', new Panel(this, $mask, $body));
25409    });
25410  }
25411};
25412module.exports = panels;
25413
25414},{}],52:[function(require,module,exports){
25415"use strict";
25416
25417var quicklinks = {
25418  ui: {},
25419  init: function init() {
25420    this.bindUI();
25421    this.bindEvents();
25422  },
25423  bindUI: function bindUI() {
25424    this.ui.$win = $(window);
25425    this.ui.$body = $('body');
25426    this.ui.$quicklinks = $('.js-push-quick-access');
25427  },
25428  bindEvents: function bindEvents() {
25429    this.ui.$win.on('scroll', $.proxy(this.showQuicklinks, this));
25430  },
25431  showQuicklinks: function showQuicklinks(e) {
25432    var self = this;
25433    var scrollTop = this.ui.$win.scrollTop(),
25434      contentHeight = parseInt(this.ui.$body.outerHeight()),
25435      // calcul 10% of page height
25436      contentHeightCalc = parseInt(contentHeight * 10 / 100);
25437
25438    // test position of page > if +10% of page > show quick access
25439    if (scrollTop > contentHeightCalc) {
25440      self.ui.$quicklinks.addClass('is-active');
25441    } else {
25442      self.ui.$quicklinks.removeClass('is-active');
25443    }
25444  }
25445};
25446module.exports = quicklinks;
25447
25448},{}],53:[function(require,module,exports){
25449"use strict";
25450
25451var redirect = {
25452  init: function init() {
25453    $('select.js-redirect').on('change', function () {
25454      var val = $(this).val();
25455      if (val) {
25456        window.location.href = val;
25457      }
25458    });
25459  }
25460};
25461module.exports = redirect;
25462
25463},{}],54:[function(require,module,exports){
25464"use strict";
25465
25466function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
25467function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
25468function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
25469function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
25470function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
25471function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
25472var RTable = /*#__PURE__*/function () {
25473  function RTable(el) {
25474    _classCallCheck(this, RTable);
25475    this.el = el;
25476    this.$el = $(el);
25477    this.$win = $(window);
25478    this.$target = $('#' + this.$el.data('subnav'));
25479    this.appened = false;
25480    this.cols = {};
25481    this.getCols();
25482    this.refresh();
25483  }
25484  return _createClass(RTable, [{
25485    key: "getCols",
25486    value: function getCols() {
25487      var self = this;
25488      this.$el.find('[data-coltitle]').each(function () {
25489        var $this = $(this);
25490        if ($this.find('.coltitle').length) {
25491          self.cols[$this.data('coltitle')] = $this.find('.coltitle').html();
25492        } else {
25493          self.cols[$this.data('coltitle')] = $this.html();
25494        }
25495      });
25496    }
25497  }, {
25498    key: "refresh",
25499    value: function refresh() {
25500      if (this.isDesktop()) {
25501        this.remove();
25502      } else {
25503        this.append();
25504      }
25505    }
25506  }, {
25507    key: "isDesktop",
25508    value: function isDesktop() {
25509      if (this.$win.outerWidth() > 1024) {
25510        return true;
25511      } else {
25512        return false;
25513      }
25514    }
25515  }, {
25516    key: "remove",
25517    value: function remove() {
25518      this.appened = false;
25519      this.$el.find('.m-title').each(function () {
25520        $(this).removeClass('append');
25521        $(this).find('.title').remove();
25522        $(this).find('.content').contents().unwrap();
25523      });
25524    }
25525  }, {
25526    key: "append",
25527    value: function append() {
25528      this.appened = true;
25529      var self = this;
25530      this.$el.find('.m-title').each(function () {
25531        var $this = $(this);
25532        if (!$this.hasClass('append')) {
25533          var newTitle = '<div class="title">';
25534          $this.addClass('append');
25535          var col = $(this).data('col');
25536          if (col && col in self.cols) {
25537            newTitle += self.cols[$(this).data('col')];
25538          } else if (this.hasAttribute('data-title')) {
25539            newTitle += $this.data('title');
25540          }
25541          newTitle += '</div>';
25542          $this.wrapInner('<div class="content"></div>');
25543          $this.prepend(newTitle);
25544        }
25545      });
25546    }
25547  }]);
25548}();
25549var responsiveTable = {
25550  init: function init() {
25551    var rtables = [];
25552    $('.js-responsive-table').each(function () {
25553      var table = new RTable(this);
25554      $(this).data('responsivetable', table);
25555      rtables.push(table);
25556    });
25557    $(window).on('resize', function () {
25558      for (var i = 0; i < rtables.length; i++) {
25559        rtables[i].refresh();
25560      }
25561    });
25562  }
25563};
25564module.exports = responsiveTable;
25565
25566},{}],55:[function(require,module,exports){
25567"use strict";
25568
25569function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
25570function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
25571function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
25572function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
25573function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
25574function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
25575var _ = require('underscore');
25576var message = require('./message.js');
25577var userCart = null;
25578var refreshShopCount = function refreshShopCount(cart, count) {
25579  if (count > 0) {
25580    $('.js-retailers-shop-icon').removeClass('hidden');
25581    $('.js-retailers-count').text(count);
25582    var o = '<table class="table-small">';
25583    for (var i = 0; i < cart.cart.items.length; i++) {
25584      o += '<tr><td>' + cart.cart.items[i].productName + '</td>';
25585      o += '<td>' + cart.cart.items[i].factor + '</td></tr>';
25586    }
25587    o += '</table>';
25588    $('.js-retailers-infos').each(function () {
25589      $(this).html(o);
25590    });
25591  } else {
25592    $('.js-retailers-shop-icon').addClass('hidden');
25593  }
25594};
25595var CustomQuantity = /*#__PURE__*/function () {
25596  function CustomQuantity($el) {
25597    _classCallCheck(this, CustomQuantity);
25598    this.$el = $el;
25599    this.$input = $el.find('input');
25600    this.$btPlus = $el.find('.bt-plus');
25601    this.$btMinus = $el.find('.bt-minus');
25602    this.min = this.$input.attr('min') || 0;
25603    this.setValue();
25604    this.bind();
25605  }
25606  return _createClass(CustomQuantity, [{
25607    key: "setValue",
25608    value: function setValue() {
25609      this.count = parseInt(this.$input.val(), 10);
25610      if (isNaN(this.count)) this.count = 0;
25611    }
25612  }, {
25613    key: "updateValue",
25614    value: function updateValue() {
25615      this.$input.val(this.count).trigger('change');
25616    }
25617  }, {
25618    key: "bind",
25619    value: function bind() {
25620      this.$btMinus.on('click', this.minus.bind(this));
25621      this.$btPlus.on('click', this.plus.bind(this));
25622    }
25623  }, {
25624    key: "minus",
25625    value: function minus(e) {
25626      e.preventDefault();
25627      this.setValue();
25628      if (this.count > this.min) this.count--;
25629      this.updateValue();
25630    }
25631  }, {
25632    key: "plus",
25633    value: function plus(e) {
25634      e.preventDefault();
25635      this.setValue();
25636      this.count++;
25637      this.updateValue();
25638    }
25639  }]);
25640}();
25641var Cart = /*#__PURE__*/function () {
25642  function Cart() {
25643    _classCallCheck(this, Cart);
25644  }
25645  return _createClass(Cart, [{
25646    key: "init",
25647    value: function init() {
25648      var _this = this;
25649      var data = window.localStorage.getItem('retailers-cart');
25650      if (data) {
25651        this.cart = JSON.parse(data);
25652        if (!('lastCheck' in this.cart) || Date.now() - this.cart.lastCheck > 259200000) {
25653          // 3 days
25654          window.localStorage.removeItem('retailers-cart');
25655          this.cart = null;
25656          $('body').data('retailer-cart', this);
25657          $('body').trigger('retailer-cart-loaded');
25658        } else if (Date.now() - this.cart.lastCheck > 60000) {
25659          $.ajax({
25660            url: window.nexansConfig.retailerServiceUrl + '/status/' + this.cart.id,
25661            type: 'GET'
25662          }).done(function (data) {
25663            _this.cart.lastCheck = Date.now();
25664            _this.cart.items = data.items;
25665            _this.save();
25666            $('body').data('retailer-cart', _this);
25667            $('body').trigger('retailer-cart-loaded');
25668            refreshShopCount(_this, _this.cart.items.length);
25669          }).fail(function () {
25670            _this.cart = null;
25671            $('body').data('retailer-cart', _this);
25672            $('body').trigger('retailer-cart-loaded');
25673          });
25674        } else {
25675          $('body').data('retailer-cart', this);
25676          $('body').trigger('retailer-cart-loaded');
25677          refreshShopCount(this, this.cart.items.length);
25678        }
25679      } else {
25680        this.cart = null;
25681        $('body').data('retailer-cart', this);
25682        $('body').trigger('retailer-cart-loaded');
25683      }
25684    }
25685  }, {
25686    key: "loadData",
25687    value: function loadData() {
25688      var _this2 = this;
25689      return new Promise(function (resolve, reject) {
25690        $.ajax({
25691          url: window.nexansConfig.retailerServiceUrl + '/status/' + _this2.cart.id,
25692          type: 'GET'
25693        }).done(function (data) {
25694          if ('items' in data) {
25695            _this2.cart.lastCheck = Date.now();
25696            _this2.cart.items = data.items;
25697            _this2.save();
25698            refreshShopCount(_this2, _this2.cart.items.length);
25699            resolve(_this2.cart.items);
25700          } else {
25701            reject();
25702          }
25703        }).fail(function () {
25704          reject();
25705        });
25706      });
25707    }
25708  }, {
25709    key: "submitRetailers",
25710    value: function submitRetailers() {
25711      return new Promise(function (resolve, reject) {
25712        $.ajax({
25713          url: window.nexansConfig.retailerServiceUrl + '/checkRetailers',
25714          type: 'POST',
25715          contentType: "application/json; charset=utf-8",
25716          data: '{}'
25717        }).done(function (data) {
25718          resolve(data);
25719        }).fail(function () {
25720          reject();
25721        });
25722      });
25723    }
25724  }, {
25725    key: "retailerRequest",
25726    value: function retailerRequest(retailerCartId) {
25727      return new Promise(function (resolve, reject) {
25728        $.ajax({
25729          url: window.nexansConfig.retailerServiceUrl + '/submitRetailerCart',
25730          type: 'POST',
25731          contentType: "application/json; charset=utf-8",
25732          data: JSON.stringify({
25733            retailerCartId: retailerCartId
25734          })
25735        }).done(function (data) {
25736          resolve(data);
25737        }).fail(function () {
25738          reject();
25739        });
25740      });
25741    }
25742  }, {
25743    key: "initShop",
25744    value: function initShop() {
25745      var _this3 = this;
25746      return new Promise(function (resolve, reject) {
25747        var uniqId = Math.random().toString(36).substring(2, 10) + '-' + Date.now();
25748        $.ajax({
25749          url: window.nexansConfig.retailerServiceUrl + '/status/' + uniqId,
25750          type: 'GET'
25751        }).done(function (data) {
25752          _this3.cart = {
25753            id: uniqId,
25754            items: data.items,
25755            lastCheck: Date.now()
25756          };
25757          _this3.save();
25758          refreshShopCount(_this3, data.items.length);
25759          resolve();
25760        });
25761      });
25762    }
25763  }, {
25764    key: "save",
25765    value: function save() {
25766      window.localStorage.setItem('retailers-cart', JSON.stringify(this.cart));
25767    }
25768  }, {
25769    key: "updateItem",
25770    value: function updateItem(id, quantity, cb) {
25771      var _this4 = this;
25772      var update = function update() {
25773        $.ajax({
25774          url: window.nexansConfig.retailerServiceUrl + '/updateItem',
25775          type: 'POST',
25776          data: JSON.stringify({
25777            productId: id,
25778            factor: parseInt(quantity, 10)
25779          }),
25780          contentType: "application/json; charset=utf-8"
25781        }).done(function (data) {
25782          var ind = _this4.cart.items.findIndex(function (el) {
25783            return el.productId === id;
25784          });
25785          if (ind === -1) {
25786            if (quantity > 0) _this4.cart.items.push(data.cartItem);
25787          } else {
25788            if (quantity > 0) {
25789              _this4.cart.items[ind] = data.cartItem;
25790            } else {
25791              _this4.cart.items.splice(ind, 1);
25792            }
25793          }
25794          refreshShopCount(_this4, _this4.cart.items.length);
25795          _this4.save();
25796          if (cb) {
25797            cb(data);
25798          }
25799        });
25800      };
25801      if (this.cart === null) {
25802        this.initShop().then(function (data) {
25803          update();
25804        });
25805      } else {
25806        update();
25807      }
25808    }
25809  }, {
25810    key: "get_",
25811    value: function get_() {
25812      return _;
25813    }
25814  }, {
25815    key: "setTemplate",
25816    value: function setTemplate(id) {
25817      this.template = _.template($('#' + id).html());
25818    }
25819  }, {
25820    key: "setCustomQuantity",
25821    value: function setCustomQuantity(element) {
25822      return new CustomQuantity(element);
25823    }
25824  }, {
25825    key: "addMessage",
25826    value: function addMessage(msg, type, delay) {
25827      message.add(msg, type, delay);
25828    }
25829  }]);
25830}();
25831;
25832var RetailersShop = /*#__PURE__*/function () {
25833  function RetailersShop($el) {
25834    var _this5 = this;
25835    _classCallCheck(this, RetailersShop);
25836    this.$el = $el;
25837    this.$submit = this.$el.find('.js-retailer-order');
25838    this.id = parseInt(this.$submit.data('id'), 10);
25839    this.$submit.on('click', function (e) {
25840      e.preventDefault();
25841      var qtty = _this5.$el.find('.js-quantity').val();
25842      userCart.updateItem(_this5.id, qtty, function (data) {
25843        userCart.addMessage(data.message, 'info', 3000);
25844        _this5.setUpdated();
25845      });
25846    });
25847    if (userCart) {
25848      var ind = userCart.cart.items.findIndex(function (it) {
25849        return it.productId === _this5.id;
25850      });
25851      if (ind !== -1) {
25852        this.update(userCart.cart.items[ind].factor);
25853      }
25854    }
25855  }
25856  return _createClass(RetailersShop, [{
25857    key: "update",
25858    value: function update(qtty) {
25859      this.$el.find('.js-quantity').val(qtty);
25860      this.setUpdated();
25861    }
25862  }, {
25863    key: "setUpdated",
25864    value: function setUpdated() {
25865      this.$el.find('.button__text.add').hide();
25866      this.$el.find('.button__text.update').show();
25867    }
25868  }]);
25869}();
25870var retailers = {
25871  init: function init() {
25872    if ($('.js-retailers-shop-icon').length > 0) {
25873      $('body').on('retailer-cart-loaded', function () {
25874        retailers.addToCartInit();
25875      });
25876      $(document).on('uiLoaded', function () {
25877        userCart = new Cart();
25878        userCart.init();
25879      });
25880    }
25881    $('.form-retailers-shop .custom-quantity').each(function () {
25882      new CustomQuantity($(this));
25883    });
25884  },
25885  addToCartInit: function addToCartInit(asyncForms) {
25886    $('.form-retailers-shop').each(function () {
25887      new RetailersShop($(this));
25888    });
25889  }
25890};
25891module.exports = retailers;
25892
25893},{"./message.js":35,"underscore":8}],56:[function(require,module,exports){
25894"use strict";
25895
25896function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
25897function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
25898function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
25899function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
25900function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
25901function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
25902var JSTable = /*#__PURE__*/function () {
25903  function JSTable(el) {
25904    _classCallCheck(this, JSTable);
25905    this.el = el;
25906    this.ui = {
25907      $el: $(el)
25908    };
25909    this.setWidths();
25910    this.setHeaders();
25911  }
25912  return _createClass(JSTable, [{
25913    key: "setWidths",
25914    value: function setWidths() {
25915      this.ui.$el.find('table:not(.table-footnote)').each(function () {
25916        var tableWidth = $(this).prop('style')['width'];
25917        if (tableWidth) $(this).next('.table-footnote').css('width', tableWidth);
25918      });
25919    }
25920  }, {
25921    key: "setHeaders",
25922    value: function setHeaders() {
25923      this.ui.$el.find('table').each(function () {
25924        var headers = $(this).find('thead th');
25925        // add a <div> to all table body cells with the corresponding header text
25926        if (headers.length > 0) {
25927          $(this).find('tbody > tr').each(function () {
25928            $(this).find('th, td').each(function (index) {
25929              var $cell = $(this);
25930              if (!$cell.find(">:first-child").is('div')) {
25931                if (headers.length >= index) {
25932                  $cell.prepend('<div>' + headers.eq(index).html() + '</div>');
25933                }
25934              }
25935            });
25936          });
25937        }
25938      });
25939    }
25940  }]);
25941}();
25942var rteArray = {
25943  init: function init() {
25944    $('div.rte-array').each(function () {
25945      new JSTable(this);
25946    });
25947  }
25948};
25949module.exports = rteArray;
25950
25951},{}],57:[function(require,module,exports){
25952"use strict";
25953
25954var scrollAnchorGenerate = {
25955  init: function init() {
25956    $('.js-scroll-anchor-generate').each(function () {
25957      var $this = $(this);
25958      var $list = $this.find('.bloc--anchors-list');
25959      $('.js-anchor').each(function () {
25960        var li = $('<li><a href="#" data-anchor="' + this.id + '" class="js-scroll-to-trigger link link--grey bloc--anchors__item"></a></li>');
25961        li.find('a').html($(this).html());
25962        $list.append(li);
25963      });
25964    });
25965  }
25966};
25967module.exports = scrollAnchorGenerate;
25968
25969},{}],58:[function(require,module,exports){
25970"use strict";
25971
25972var scrollToAnchor = {
25973  ui: {},
25974  init: function init() {
25975    this.bindUI();
25976    this.bindEvents();
25977    this.scrollTo();
25978  },
25979  bindUI: function bindUI() {
25980    this.ui.$win = $(window);
25981    this.ui.$body = $('body');
25982    this.ui.$document = $(document);
25983    this.ui.$links = $('.js-scroll-to-trigger');
25984    this.ui.$select = $('.js-scroll-to-select');
25985    this.ui.$sticky = $('.js-sticky');
25986    this.isGenerated = $('.js-scroll-to.js-scroll-anchor-generate').length > 0;
25987  },
25988  bindEvents: function bindEvents() {
25989    this.ui.$win.on('scroll', $.proxy(this.handleStickyAnchors, this));
25990  },
25991  scrollTo: function scrollTo() {
25992    var self = this;
25993    this.ui.$links.on('click', function (e) {
25994      e.preventDefault();
25995      var $self = $(this),
25996        data = $(this).data('anchor'),
25997        $target = $('body').find('#' + data),
25998        pos = Math.max($target.offset().top, 0);
25999      if ('stickySize' in window.nexansConfig) {
26000        pos = pos - window.nexansConfig.stickySize;
26001      }
26002      $('body, html').animate({
26003        scrollTop: pos
26004      }, 'slow');
26005    });
26006    this.ui.$select.on('change', function () {
26007      var $self = $(this),
26008        value = $self.val(),
26009        $target = $('body').find('#' + value),
26010        pos = Math.max($target.offset().top, 0);
26011      $('body, html').animate({
26012        scrollTop: pos
26013      }, 'slow');
26014    });
26015  },
26016  handleStickyAnchors: function handleStickyAnchors(e) {
26017    if (this.ui.$sticky.length) {
26018      var offset = 'stickySize' in window.nexansConfig ? window.nexansConfig.stickySize : 0;
26019      var scrollPos = this.ui.$document.scrollTop() + offset + 1;
26020      var self = this;
26021      if (this.isGenerated) {
26022        var i = 0;
26023        var anchors = [];
26024        $('.js-anchor').each(function () {
26025          var top = $(this).offset().top;
26026          anchors.push({
26027            top: top
26028          });
26029          if (i > 0) anchors[i - 1].bottom = top;
26030          i++;
26031        });
26032        i = 0;
26033        $('.js-scroll-to-trigger').each(function () {
26034          var $currentAnchor = $(this);
26035          var $refElement = $('#' + $currentAnchor.attr('data-anchor'));
26036          if ($refElement.hasClass('js-anchor')) ;
26037          if (anchors[i].top <= scrollPos && (!('bottom' in anchors[i]) || anchors[i].bottom > scrollPos)) {
26038            $('.is-sticky-current').removeClass('is-sticky-current');
26039            $currentAnchor.addClass('is-sticky-current');
26040          } else {
26041            $currentAnchor.removeClass('is-sticky-current');
26042          }
26043          i++;
26044        });
26045      } else {
26046        $('.js-scroll-to-trigger').each(function () {
26047          var $currentAnchor = $(this);
26048          var $refElement = $('#' + $currentAnchor.attr('data-anchor'));
26049          if ($refElement.offset().top <= scrollPos && $refElement.offset().top + $refElement.height() > scrollPos) {
26050            $('.is-sticky-current').removeClass('is-sticky-current');
26051            $currentAnchor.addClass('is-sticky-current');
26052          } else {
26053            $currentAnchor.removeClass('is-sticky-current');
26054          }
26055        });
26056      }
26057    }
26058  }
26059};
26060module.exports = scrollToAnchor;
26061
26062},{}],59:[function(require,module,exports){
26063"use strict";
26064
26065var searchFilters = {
26066  ui: {},
26067  init: function init() {
26068    this.bindUI();
26069    this.bindEvents();
26070  },
26071  bindUI: function bindUI() {
26072    this.ui.$document = $(document);
26073    this.ui.$close = $('.js-close-filters');
26074    this.ui.$container = $('.js-result-filters-container');
26075    this.ui.$filterItem = $('.js-result-filters');
26076    this.ui.$sub = $('.js-result-filters-sub');
26077    this.ui.$select = $('.js-result-filter-select');
26078    this.ui.$subselect = $('.js-result-filter-subselect');
26079    this.ui.$tagsList = $('.js-search-tags-list');
26080    this.ui.$tags = $('.js-search-tags');
26081  },
26082  bindEvents: function bindEvents() {
26083    var _this = this;
26084    this.ui.$filterItem.on('click', function (e) {
26085      return _this.showFilters(e);
26086    });
26087    this.ui.$document.on('click', function (e) {
26088      return _this.closeFilters(e);
26089    });
26090    this.ui.$close.on('click', function (e) {
26091      return _this.onClickClose(e);
26092    });
26093    this.ui.$select.on('change', function (e) {
26094      return _this.showSubSelect(e);
26095    });
26096    this.ui.$tags.on('click', function (e) {
26097      return _this.deleteTags(e);
26098    });
26099  },
26100  showFilters: function showFilters(e) {
26101    e.preventDefault();
26102    var $el = $(e.currentTarget),
26103      data = $el.data('filter');
26104    this.ui.$filterItem.removeClass('active');
26105    $el.addClass('active');
26106    this.ui.$sub.removeClass('active');
26107    $('.js-result-filters-sub[data-filter="' + data + '"]').addClass('active');
26108  },
26109  onClickClose: function onClickClose(e) {
26110    e.preventDefault();
26111    this.ui.$sub.removeClass('active');
26112  },
26113  closeFilters: function closeFilters(e) {
26114    if ($(e.target).closest('.js-result-filters-container').length === 0) {
26115      this.ui.$sub.removeClass('active');
26116    }
26117  },
26118  showSubSelect: function showSubSelect(e) {
26119    var $el = $(e.currentTarget),
26120      val = $el.val();
26121    this.ui.$select.removeClass('active');
26122    $el.addClass('active');
26123    if (val === 'subnav') {
26124      var $selected = this.ui.$select.find('option[value="' + val + '"]'),
26125        ref = $selected.data('ref'),
26126        $target = $('#' + ref);
26127      if ($target) {
26128        $target.addClass('active');
26129      } else {
26130        this.ui.$subselect.removeClass('active');
26131      }
26132    }
26133  },
26134  deleteTags: function deleteTags(e) {
26135    e.preventDefault();
26136    var $el = $(e.currentTarget),
26137      $tags = this.ui.$tagsList.find('.js-search-tags');
26138    if ($tags.length <= 1) {
26139      $el.remove();
26140      this.ui.$tagsList.addClass('inactive');
26141    } else {
26142      $el.remove();
26143    }
26144  }
26145};
26146module.exports = searchFilters;
26147
26148},{}],60:[function(require,module,exports){
26149"use strict";
26150
26151var sharePrice = {
26152  ui: {},
26153  init: function init() {
26154    if ('nexansConfig' in window && 'sharePriceServiceUrl' in window.nexansConfig) this.updateSharePrice();
26155    this.bindUI();
26156    if (this.ui.$iframe.length > 0) {
26157      this.ui.$iframe.on('load', function () {
26158        this.checkSharePriceHeight();
26159        $(window).on('resize', this.checkSharePriceHeight.bind(this));
26160      }.bind(this));
26161      setTimeout(this.checkSharePriceReload.bind(this), 120000);
26162    }
26163  },
26164  bindUI: function bindUI() {
26165    this.ui.$iframe = $('iframe#shareprice-iframe');
26166    this.ui.$input = $('input#shareprice-auto-reload');
26167    this.ui.$spData = $('div.share-price > a > span, div.navigation__infos > p.share-price, div.navigation__infos > a > p.share-price');
26168    this.ui.$spMeta = $('div#share-price-highlight > div.push-action__meta');
26169    this.ui.$spKey = $('div#share-price-highlight > div.push-action__key');
26170  },
26171  checkSharePriceReload: function checkSharePriceReload() {
26172    if (this.ui.$input.is(':checked')) {
26173      this.ui.$iframe[0].src = this.ui.$iframe[0].src;
26174    }
26175    setTimeout(this.checkSharePriceReload.bind(this), 120000);
26176  },
26177  checkSharePriceHeight: function checkSharePriceHeight() {
26178    if (this.ui.$iframe.width() < 560) {
26179      this.ui.$iframe.height('1320px');
26180    } else {
26181      this.ui.$iframe.height('1080px');
26182    }
26183  },
26184  updateSharePrice: function updateSharePrice() {
26185    var self = this;
26186    $.getJSON(window.nexansConfig.sharePriceServiceUrl, function (jsonData) {
26187      if (jsonData) {
26188        self.ui.$spMeta.html(jsonData.place + ', ' + jsonData.date + ' ' + jsonData.time);
26189        self.ui.$spKey.html(jsonData.value + '<sup class="push-action__sup">' + jsonData.currency + '</sup>');
26190        self.ui.$spData.html(jsonData.value + jsonData.currency + ' - ' + jsonData.place + ', ' + jsonData.date + ' ' + jsonData.time);
26191      } else {
26192        self.ui.$spMeta.html('Share price<br/>temporary unavailable');
26193        self.ui.$spKey.html('');
26194        self.ui.$spData.text('temporary unavailable');
26195      }
26196    }).fail(function () {
26197      self.ui.$spMeta.html('Share price<br/>temporary unavailable');
26198      self.ui.$spKey.html('');
26199      self.ui.$spData.text('temporary unavailable');
26200    });
26201    window.setTimeout(this.updateSharePrice.bind(this), 120000);
26202  }
26203};
26204module.exports = sharePrice;
26205
26206},{}],61:[function(require,module,exports){
26207"use strict";
26208
26209var showAccount = {
26210  ui: {},
26211  init: function init() {
26212    this.bindUI();
26213    this.bindEvents();
26214    this.ui.$secondary.hide();
26215    this.onChangeMain();
26216  },
26217  bindUI: function bindUI() {
26218    this.ui.$document = $(document);
26219    this.ui.$trigger = $('.js-account-trigger');
26220    this.ui.$account = $('.js-account');
26221    this.ui.$main = $('.account__main');
26222    this.ui.$secondary = $('.account__secondary');
26223    this.ui.$mobileHeader = $('header.mobile-header');
26224    this.ui.$desktopHeader = $('header.header');
26225  },
26226  bindEvents: function bindEvents() {
26227    var _this = this;
26228    this.ui.$trigger.on('click', function (e) {
26229      return _this.onClick(e);
26230    });
26231    this.ui.$main.on('change', function (e) {
26232      return _this.onChangeMain(e);
26233    });
26234    this.ui.$account.on('click', function (e) {
26235      return e.stopPropagation();
26236    });
26237    $(document).on('click', function (e) {
26238      return _this.close();
26239    });
26240  },
26241  close: function close() {
26242    this.ui.$account.removeClass('is-open');
26243    this.ui.$trigger.removeClass('active');
26244  },
26245  onClick: function onClick(e) {
26246    e.preventDefault();
26247    e.stopPropagation();
26248    if (this.ui.$mobileHeader.is(':visible')) {
26249      this.ui.$mobileHeader.append(this.ui.$account);
26250    } else {
26251      this.ui.$desktopHeader.append(this.ui.$account);
26252    }
26253    var $el = $(e.currentTarget);
26254    $el.toggleClass('active');
26255    this.ui.$account.toggleClass('is-open');
26256  },
26257  onChangeMain: function onChangeMain() {
26258    this.ui.$secondary.hide();
26259    $('#' + this.ui.$main.attr('id') + '-' + this.ui.$main.val()).show();
26260  }
26261};
26262module.exports = showAccount;
26263
26264},{}],62:[function(require,module,exports){
26265"use strict";
26266
26267var showSearch = {
26268  ui: {},
26269  init: function init() {
26270    this.bindUI();
26271    this.bindEvents();
26272  },
26273  bindUI: function bindUI() {
26274    this.ui.$document = $(document);
26275    this.ui.$reset = $('.js-search-reset');
26276    this.ui.$trigger = $('.js-search-trigger');
26277    this.ui.$close = $('.js-search-close');
26278    this.ui.$search = $('.js-search');
26279    this.ui.$form = $('.js-search-form');
26280    this.ui.$input = $('.js-search-input');
26281    this.ui.$submit = $('.js-search-submit');
26282  },
26283  bindEvents: function bindEvents() {
26284    var _this = this;
26285    this.ui.$trigger.on('click', function (e) {
26286      return _this.onClick(e);
26287    });
26288    this.ui.$close.on('click', function (e) {
26289      return _this.onClick(e);
26290    });
26291    this.ui.$reset.on('click', function (e) {
26292      return _this.onReset(e);
26293    });
26294    this.ui.$input.on('keyup', function (e) {
26295      return _this.onChange(e);
26296    });
26297  },
26298  onClick: function onClick(e) {
26299    e.preventDefault();
26300    var $el = this.ui.$trigger;
26301    $el.toggleClass('active');
26302    this.ui.$search.toggleClass('is-open');
26303    if ($el.hasClass('active')) {
26304      this.ui.$input.focus();
26305    }
26306  },
26307  onReset: function onReset(e) {
26308    e.preventDefault();
26309    this.ui.$input.val('');
26310    this.ui.$submit.prop('disabled', true);
26311  },
26312  onChange: function onChange(e) {
26313    e.preventDefault();
26314    var $el = $(e.currentTarget),
26315      val = $el.val();
26316    if (val.length > 1) {
26317      this.ui.$submit.prop('disabled', false);
26318    } else {
26319      this.ui.$submit.prop('disabled', true);
26320    }
26321  }
26322};
26323module.exports = showSearch;
26324
26325},{}],63:[function(require,module,exports){
26326"use strict";
26327
26328function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
26329function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
26330function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
26331function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
26332function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
26333function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
26334var ShowSubnav = /*#__PURE__*/function () {
26335  function ShowSubnav(el) {
26336    _classCallCheck(this, ShowSubnav);
26337    this.el = el;
26338    this.$el = $(el);
26339    this.$target = $('#' + this.$el.data('subnav'));
26340    this.bind();
26341  }
26342  return _createClass(ShowSubnav, [{
26343    key: "bind",
26344    value: function bind() {
26345      var self = this;
26346      this.$el.click(function (e) {
26347        e.preventDefault();
26348        self.$target.toggleClass('is-opened');
26349      });
26350      this.$target.find('.js-nav-close').click(function (e) {
26351        e.preventDefault();
26352        self.$target.removeClass('is-opened');
26353      });
26354    }
26355  }]);
26356}();
26357var showSubnav = {
26358  init: function init() {
26359    $('.js-show-subnav').each(function () {
26360      new ShowSubnav(this);
26361    });
26362  }
26363};
26364module.exports = showSubnav;
26365
26366},{}],64:[function(require,module,exports){
26367"use strict";
26368
26369function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
26370function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
26371function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
26372function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
26373function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
26374function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
26375function isMobile() {
26376  return $('.mobile-header:visible').length > 0;
26377}
26378var Sticky = /*#__PURE__*/function () {
26379  function Sticky(el) {
26380    _classCallCheck(this, Sticky);
26381    this.ui = {};
26382    this.ui.$wrapper = $(el);
26383    this.ui.$window = $(window);
26384    this.ui.$document = $(document);
26385    this.name = this.ui.$wrapper.data('name');
26386    this.initSticky();
26387  }
26388  return _createClass(Sticky, [{
26389    key: "initSticky",
26390    value: function initSticky() {
26391      this.ui.$clone = $('<div class="js-sticky-clone"></div>');
26392      this.ui.$clone.insertBefore(this.ui.$wrapper);
26393      if (this.name) {
26394        this.ui.$clone.addClass(this.name);
26395      }
26396    }
26397  }, {
26398    key: "handlePosition",
26399    value: function handlePosition(offset) {
26400      var offsetTop = this.ui.$clone.offset().top - offset;
26401      if (this.ui.$document.scrollTop() >= offsetTop) {
26402        var h = this.ui.$wrapper.outerHeight(true);
26403        this.ui.$clone.height(h);
26404        this.ui.$wrapper.addClass('is-sticky').css('top', offset);
26405        window.nexansConfig.stickySize += this.ui.$wrapper.outerHeight(false);
26406        return this.ui.$wrapper.outerHeight();
26407      } else {
26408        this.ui.$wrapper.removeClass('is-sticky').css('top', 0);
26409        this.ui.$clone.height(0);
26410        return 0;
26411      }
26412    }
26413  }]);
26414}();
26415;
26416var sticky = {
26417  init: function init() {
26418    var stickies = [];
26419    var $mobileHeader = $('.mobile-header');
26420    $('.js-sticky').each(function () {
26421      stickies.push(new Sticky(this));
26422    });
26423    var checkSticky = function checkSticky() {
26424      var top = 0;
26425      window.nexansConfig.stickySize = 0;
26426      var isMobileLayout = isMobile();
26427      if (isMobileLayout) {
26428        top = $mobileHeader.outerHeight();
26429        window.nexansConfig.stickySize = top;
26430      }
26431      for (var i = 0; i < stickies.length; i++) {
26432        if (!isMobileLayout || stickies[i].name !== 'sticky-main-menu') {
26433          top += stickies[i].handlePosition(top);
26434        }
26435      }
26436    };
26437    $(window).on('scroll', checkSticky);
26438    checkSticky();
26439  }
26440};
26441module.exports = sticky;
26442
26443},{}],65:[function(require,module,exports){
26444"use strict";
26445
26446function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
26447function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
26448function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
26449function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
26450function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
26451function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
26452var Storage = /*#__PURE__*/function () {
26453  function Storage(key) {
26454    _classCallCheck(this, Storage);
26455    this.key = key;
26456    this.data = {
26457      familyIds: [],
26458      productIds: []
26459    };
26460    this.count = 0;
26461    this.notStored = false;
26462    this.load();
26463  }
26464  return _createClass(Storage, [{
26465    key: "load",
26466    value: function load() {
26467      var data = JSON.parse(window.sessionStorage.getItem(this.key));
26468      if (!data) this.notStored = true;
26469      this.data = data || this.data;
26470      this.count = this.data.familyIds.length + this.data.productIds.length;
26471      return this.data;
26472    }
26473  }, {
26474    key: "delete",
26475    value: function _delete(familyId, productId) {
26476      if (productId) {
26477        var index = this.data.productIds.indexOf(productId);
26478        if (index > -1) this.data.productIds.splice(index, 1);
26479      } else {
26480        var _index = this.data.familyIds.indexOf(familyId);
26481        if (_index > -1) this.data.familyIds.splice(_index, 1);
26482      }
26483      this.persist();
26484    }
26485  }, {
26486    key: "add",
26487    value: function add(familyId, productId) {
26488      if (productId) {
26489        this.data.productIds.push(productId);
26490      } else {
26491        this.data.familyIds.push(familyId);
26492      }
26493      ;
26494      this.persist();
26495    }
26496  }, {
26497    key: "exists",
26498    value: function exists(familyId, productId) {
26499      if (productId) {
26500        return this.data.productIds.indexOf(productId) !== -1;
26501      }
26502      return this.data.familyIds.indexOf(familyId) !== -1;
26503    }
26504  }, {
26505    key: "persist",
26506    value: function persist() {
26507      window.sessionStorage.setItem(this.key, JSON.stringify(this.data));
26508      this.count = this.data.familyIds.length + this.data.productIds.length;
26509    }
26510  }, {
26511    key: "refresh",
26512    value: function refresh(data) {
26513      this.data = {
26514        familyIds: data.familyIds || [],
26515        productIds: data.productIds || []
26516      };
26517      if ('productIds' in data) {
26518        this.data.productIds = data.productIds;
26519      }
26520      this.persist();
26521    }
26522  }]);
26523}();
26524var storage = {
26525  comparator: new Storage('nexans-comparator-families'),
26526  favorites: new Storage('nexans-favourites-list')
26527};
26528module.exports = storage;
26529
26530},{}],66:[function(require,module,exports){
26531"use strict";
26532
26533var subscribeNewsletter = {
26534  ui: {},
26535  newsJSON: {},
26536  tags: [],
26537  init: function init() {
26538    this.bindUI();
26539    this.bindEvents();
26540  },
26541  bindUI: function bindUI() {
26542    this.ui.$win = $(window);
26543    this.ui.$body = $('body');
26544    this.ui.$selectAll = $('.js-select-all');
26545    this.ui.$select = $('.js-select');
26546    this.ui.$tagsWrapper = $('.js-tags-wrapper');
26547    this.ui.$btnNext = $('.js-nl-next');
26548    this.ui.$btnPrevious = $('.js-nl-previous');
26549    this.ui.$email = $('.js-nl-email');
26550    this.ui.$validate = $('.js-nl-validate');
26551  },
26552  bindEvents: function bindEvents() {
26553    this.ui.$selectAll.on('click', $.proxy(this.selectAll, this));
26554    this.ui.$select.on('change', $.proxy(this.select, this));
26555    this.ui.$btnNext.on('click', $.proxy(this.nextPage, this));
26556    this.ui.$btnPrevious.on('click', $.proxy(this.previousPage, this));
26557    this.ui.$validate.on('click', $.proxy(this.lastPage, this));
26558    this.ui.$email.on('keyup', $.proxy(this.checkmail, this));
26559  },
26560  selectAll: function selectAll(e) {
26561    e.preventDefault();
26562    var self = this;
26563    var arrayItems = [];
26564
26565    // Cibling parent.
26566    var $parent = $(e.currentTarget).closest('.js-select-all-wrapper');
26567
26568    // Disable select all.
26569    $(e.currentTarget).addClass('is-disable');
26570
26571    // Enable btn next.
26572    this.ui.$btnNext.removeClass('is-disable');
26573
26574    // Check all checkbox of this part.
26575    $parent.find(':checkbox').prop("checked", true);
26576    $.each($parent.find(':checkbox'), function () {
26577      var id = $(this).attr('id');
26578
26579      // add tags.
26580      self.appendTag(id);
26581
26582      // add item on array tags.
26583      self.tags.push(parseInt(id));
26584    });
26585  },
26586  select: function select(e) {
26587    var self = this;
26588    var $parent = $(e.currentTarget).closest('.js-select-all-wrapper');
26589    var $btn = $parent.find('.js-select-all');
26590    var id = $(e.currentTarget).find(':checkbox').attr('id');
26591
26592    // check class disable or not.
26593    if ($btn.hasClass('is-disable')) {
26594      $btn.removeClass('is-disable');
26595    }
26596
26597    // Tags list
26598    if (self.tags.includes(parseInt(id))) {
26599      // remove item from array tags.
26600      this.removeTag(id);
26601    } else {
26602      // add item on array tags.
26603      self.tags.push(parseInt(id));
26604      this.appendTag(id);
26605    }
26606
26607    // Show or hide btn next step.
26608    if (self.tags.length > 0) {
26609      this.ui.$btnNext.removeClass('is-disable');
26610    } else {
26611      this.ui.$btnNext.addClass('is-disable');
26612    }
26613  },
26614  appendTag: function appendTag(id) {
26615    // Get name by id.
26616    var $el = $('#' + id);
26617    var name = $($el).next().children('.js-checkbox-name').html();
26618
26619    // Construct item.
26620    var html = '<a href="" class="panel-newsletter__tag js-tag-remove tag" data-nlid="' + id + '">
26620 ' + name + '<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-close" viewBox="0 0 20 20">' + '<path fill="#DB3331" fill-rule="evenodd" d="M10,8.58578644 L4.34314575,2.92893219 L2.92893219,4.34314575 L8.58578644,10 L2.92893219,15.6568542 L4.34314575,17.0710678 L10,11.4142136 L15.6568542,17.0710678 L17.0710678,15.6568542 L11.4142136,10 L17.0710678,4.34314575 L15.6568542,2.92893219 L10,8.58578644 Z"/>' + '</svg> </a>';
26621    $('.js-tags-wrapper').append(html);
26622
26623    // Bind events.
26624    this.ui.$removeTag = $('.js-tag-remove');
26625    this.ui.$removeTag.on('click', $.proxy(this.removeTagByItem, this));
26626  },
26627  removeTag: function removeTag(id) {
26628    var self = this;
26629
26630    // find item by data attr.
26631    var $item = $('*[data-nlid="' + id + '"]');
26632
26633    // remove item.
26634    $item.remove();
26635  },
26636  removeTagByItem: function removeTagByItem(e) {
26637    e.preventDefault();
26638    var self = this;
26639    var id = $(e.currentTarget).data('nlid');
26640    var $item = $('*[data-nlid="' + id + '"]');
26641
26642    // remove check.
26643    $('#' + id).prop('checked', false);
26644    var index = self.tags.indexOf(id);
26645    if (index !== -1) self.tags.splice(index, 1);
26646
26647    // remove item.
26648    $item.remove();
26649  },
26650  nextPage: function nextPage(e) {
26651    e.preventDefault();
26652    $('.js-newsletter-1').hide();
26653    $('.js-newsletter-2').show();
26654  },
26655  previousPage: function previousPage(e) {
26656    e.preventDefault();
26657    $('.js-newsletter-1').show();
26658    $('.js-newsletter-2').hide();
26659  },
26660  lastPage: function lastPage(e) {
26661    e.preventDefault();
26662    var self = this;
26663    var email = this.ui.$email.val(),
26664      itemsArray = self.tags;
26665    $.ajax({
26666      url: 'TODO UPDATE URL',
26667      type: 'POST',
26668      data: 'email=' + email + '&items=' + itemsArray,
26669      dataType: 'html',
26670      success: function success(html, statut) {
26671        $('.js-newsletter-success').show();
26672        console.log('success');
26673      },
26674      error: function error(result, statut, erreur) {
26675        $('.js-newsletter-error').show();
26676        console.log('erreur');
26677      }
26678    });
26679    $('.js-newsletter-1').hide();
26680    $('.js-newsletter-2').hide();
26681    $('.js-nl-header').hide();
26682    $('.js-newsletter-3').show();
26683  },
26684  checkmail: function checkmail() {
26685    var self = this;
26686    var val = $('.js-nl-email').val();
26687    var filter = /^([a-zA-Z0-9_.+-])+\@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/;
26688    if (!filter.test(val)) {
26689      $('.js-nl-validate').addClass('is-disable');
26690    } else {
26691      $('.js-nl-validate').removeClass('is-disable');
26692    }
26693    console.log(self.tags);
26694  }
26695};
26696module.exports = subscribeNewsletter;
26697
26698},{}],67:[function(require,module,exports){
26699"use strict";
26700
26701function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
26702function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
26703function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
26704function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
26705function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
26706function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
26707var TableSelect = /*#__PURE__*/function () {
26708  function TableSelect(el) {
26709    _classCallCheck(this, TableSelect);
26710    this.$el = $(el);
26711    this.data = this.$el.data();
26712    this.paginator = this.$el.data('paginator');
26713    this.bindUi();
26714    if (this.paginator) {
26715      this.itemsByPage = this.ui.$selectNbItems.length ? parseInt(this.ui.$selectNbItems.val(), 10) : 10;
26716      this.activePage = 0;
26717      this.pages = 0;
26718    }
26719    if (this.ui.$form.length > 0) {
26720      this.baseAction = this.ui.$form.attr('action');
26721    }
26722    this.sortActive = null;
26723    this.bind();
26724    this.initSort();
26725    this.refreshItems();
26726    this.selectChange();
26727  }
26728  return _createClass(TableSelect, [{
26729    key: "bindUi",
26730    value: function bindUi() {
26731      this.ui = {};
26732      this.ui.sortBtns = [];
26733      this.ui.$form = this.$el.parents('form');
26734      this.ui.$sortSelect = this.$el.find('.tableselect-sort-select');
26735      this.ui.$inputSelectAll = this.$el.find('.tableselect-selectall');
26736      this.ui.$count = this.$el.find('.tableselect-count');
26737      this.ui.$countTotal = this.$el.find('.tableselect-count-total');
26738      this.ui.$actions = this.$el.find('.tableselect-action');
26739      if (this.paginator) {
26740        this.ui.$pagerWrapper = this.$el.find('.tableselect-pager');
26741        this.ui.$pager = this.ui.$pagerWrapper.find('.pager__list');
26742        this.ui.$selectNbItems = 'itemsbypage' in this.data ? $(this.data.itemsbypage) : this.$el.find('.tableselect-itemsbypage');
26743      }
26744      this.bindRows();
26745    }
26746  }, {
26747    key: "bindRows",
26748    value: function bindRows(noEvent) {
26749      this.ui.$inputs = this.$el.find('.tableselect-select');
26750      if (!noEvent) this.ui.$inputs.on('change', this.selectChange.bind(this));
26751    }
26752  }, {
26753    key: "bind",
26754    value: function bind() {
26755      if (this.paginator) {
26756        this.ui.$pagerWrapper.on('click', 'a', this.pagerNav.bind(this));
26757        if (this.ui.$selectNbItems.length) this.ui.$selectNbItems.on('change', function () {
26758          this.itemsByPage = parseInt(this.ui.$selectNbItems.val(), 10);
26759          this.activePage = 0;
26760          this.refreshItems();
26761        }.bind(this));
26762      }
26763      this.ui.$inputSelectAll.on('change', this.selectAllChange.bind(this));
26764      var self = this;
26765      this.ui.$actions.each(function () {
26766        var $action = $(this);
26767        if (this.hasAttribute('data-url')) {
26768          $action.on('click', function (e) {
26769            self.ui.$form.attr('action', $action.data('url'));
26770          });
26771        } else {
26772          $action.on('click', function (e) {
26773            self.ui.$form.attr('action', self.baseAction);
26774          });
26775        }
26776      });
26777    }
26778  }, {
26779    key: "initSort",
26780    value: function initSort() {
26781      var self = this;
26782      this.$el.find('.tableselect-sort').each(function () {
26783        var $this = $(this);
26784        var $bt = $('<button type="button"></button>');
26785        var sortBy = $this.data('sortby');
26786        var sortType = $this.data('sorttype') || 'string';
26787        var defaultDir = $this.data('direction');
26788        $bt.on('click', function () {
26789          var $thisbt = $(this);
26790          var direction = $thisbt.data('direction');
26791          if (!direction && defaultDir) {
26792            direction = defaultDir;
26793            if (direction == 'desc') {
26794              $thisbt.addClass('desc');
26795            }
26796          } else if (!$thisbt.hasClass('is-active') && direction) {} else if (!direction || direction == 'desc' || !$thisbt.hasClass('is-active')) {
26797            direction = 'asc';
26798            $thisbt.removeClass('desc');
26799          } else {
26800            direction = 'desc';
26801            $thisbt.addClass('desc');
26802          }
26803          $thisbt.data('direction', direction);
26804          self.$el.find('.tableselect-sort button').removeClass('is-active');
26805          self.sort(parseInt($this.data('col'), 10) - 1, sortBy, direction, sortType);
26806          $thisbt.addClass('is-active');
26807          if (self.ui.$sortSelect.length) {
26808            self.ui.$sortSelect.find('option:first-child').prop('selected', true);
26809          }
26810        });
26811        self.ui.sortBtns.push($bt);
26812        if ($this.hasClass('is-active')) {
26813          $this.removeClass('is-active');
26814          $bt.trigger('click');
26815        }
26816        $this.wrapInner($bt);
26817      });
26818      if (this.ui.$sortSelect.length) {
26819        this.ui.$sortSelect.on('change', function (e) {
26820          var $option = $(this).find('option:selected');
26821          if ($option[0].hasAttribute('data-col')) {
26822            var sortBy = $option.data('sortby');
26823            var sortType = $option.data('sorttype') || 'string';
26824            self.sort(parseInt($option.data('col'), 10) - 1, sortBy, $option.data('direction'), sortType);
26825            self.$el.find('.tableselect-sort button').removeClass('is-active');
26826          }
26827        });
26828      }
26829    }
26830  }, {
26831    key: "sort",
26832    value: function sort(col, sortBy, direction, sortType) {
26833      this.sortActive = {
26834        col: col,
26835        sortBy: sortBy,
26836        direction: direction
26837      };
26838      var getCellValue = function getCellValue(row) {
26839        var val;
26840        if (sortBy) {
26841          val = $(row).children('td').eq(col).attr(sortBy);
26842        } else {
26843          val = $(row).children('td').eq(col).text();
26844        }
26845        if (sortType == 'number') val = Number(val);
26846        return val;
26847      };
26848      var rows = this.$el.find('tbody tr').not('.no-sort').toArray().sort(function (a, b) {
26849        var valA = getCellValue(a),
26850          valB = getCellValue(b);
26851        return sortType == 'number' ? valA > valB : valA.toString().localeCompare(valB);
26852      });
26853      // this.asc = !this.asc
26854      if (direction == 'desc') {
26855        rows = rows.reverse();
26856      }
26857      var tbody = this.$el.find('tbody');
26858      for (var i = 0; i < rows.length; i++) {
26859        tbody.append(rows[i]);
26860      }
26861      this.refreshItems();
26862    }
26863  }, {
26864    key: "refreshItems",
26865    value: function refreshItems() {
26866      var $elements = this.$el.find('tbody tr:not(.no-pagination)');
26867      this.ui.$countTotal.text($elements.length);
26868      if (this.paginator) {
26869        $elements.hide();
26870        if ($elements.length > this.itemsByPage) {
26871          this.ui.$pagerWrapper.show();
26872          this.populatePager($elements.length);
26873          var start = this.activePage * this.itemsByPage;
26874          $elements = $elements.slice(start, start + this.itemsByPage);
26875        } else {
26876          this.ui.$pagerWrapper.hide();
26877        }
26878        $elements.show();
26879      }
26880      this.selectChange();
26881    }
26882  }, {
26883    key: "pagerNav",
26884    value: function pagerNav(e) {
26885      e.preventDefault();
26886      var $link = $(e.currentTarget);
26887      if ($link.parent().hasClass('pager__list-item')) {
26888        this.activePage = parseInt($link.attr('href').substring(1), 10);
26889      } else {
26890        if ($link.hasClass('pager__round--left')) {
26891          this.activePage = Math.max(0, this.activePage - 1);
26892        } else if ($link.hasClass('pager__round--right')) {
26893          this.activePage = Math.min(this.pages - 1, this.activePage + 1);
26894        }
26895      }
26896      this.refreshItems();
26897    }
26898  }, {
26899    key: "populatePager",
26900    value: function populatePager(total) {
26901      this.pages = Math.ceil(total / this.itemsByPage);
26902      var items = '';
26903      var start = Math.max(0, this.activePage - 2);
26904      if (start == 1) start = 0;
26905      var end = Math.min(this.pages - 1, this.activePage + 2);
26906      if (end == this.pages - 2) end = this.pages - 1;
26907      if (start > 0) {
26908        items += '<li class="pager__list-item"><a href="#0">1</a></li>';
26909        items += '<li class="pager__list-item"><span>...</span></li>';
26910      }
26911      for (var i = start; i <= end; i++) {
26912        items += '<li class="pager__list-item"><a ' + (i == this.activePage ? 'class="is-active" ' : '') + 'href="#' + i + '">' + (i + 1) + '</a></li>';
26913      }
26914      if (end < this.pages - 2) {
26915        items += '<li class="pager__list-item"><span>...</span></li>';
26916        items += '<li class="pager__list-item"><a href="#' + (this.pages - 1) + '">' + this.pages + '</a></li>';
26917      }
26918      this.ui.$pager.html(items);
26919    }
26920  }, {
26921    key: "selectAllChange",
26922    value: function selectAllChange() {
26923      var selected = this.ui.$inputSelectAll.prop('checked');
26924      var $els = this.ui.$inputs;
26925      if (this.paginator) {
26926        var start = this.activePage * this.itemsByPage;
26927        $els = $els.slice(start, start + this.itemsByPage);
26928      }
26929      $els.each(function () {
26930        $(this).prop('checked', selected);
26931      });
26932      this.selectChange();
26933    }
26934  }, {
26935    key: "selectChange",
26936    value: function selectChange() {
26937      if (this.paginator) {
26938        var start = this.activePage * this.itemsByPage;
26939        var $els = this.ui.$inputs.slice(start, start + this.itemsByPage);
26940        var selected = true;
26941        $els.each(function () {
26942          selected = selected && $(this).prop('checked');
26943        });
26944        this.ui.$inputSelectAll.prop('checked', selected);
26945      }
26946      var total = this.count();
26947      if (total > 0) {
26948        this.ui.$actions.removeClass('button--disabled');
26949        this.ui.$actions.prop('disabled', false);
26950      } else {
26951        this.ui.$actions.addClass('button--disabled');
26952        this.ui.$actions.prop('disabled', true);
26953      }
26954    }
26955  }, {
26956    key: "count",
26957    value: function count() {
26958      var total = 0;
26959      this.ui.$inputs.each(function () {
26960        if ($(this).prop('checked')) total++;
26961      });
26962      this.ui.$count.text(total);
26963      return total;
26964    }
26965  }]);
26966}();
26967var ts = {
26968  init: function init() {
26969    $('.js-tableselect').each(function () {
26970      $(this).data('tableselect', new TableSelect(this));
26971    });
26972  }
26973};
26974module.exports = ts;
26975
26976},{}],68:[function(require,module,exports){
26977"use strict";
26978
26979var tabs = {
26980  ui: {},
26981  init: function init() {
26982    this.bindUI();
26983    this.bindEvents();
26984  },
26985  bindUI: function bindUI() {
26986    this.ui.$win = $(window);
26987    this.ui.$body = $('body');
26988    this.ui.$tabs = $('.js-tabs');
26989  },
26990  bindEvents: function bindEvents() {
26991    this.ui.$tabs.on('click', $.proxy(this.showTab, this));
26992  },
26993  showTab: function showTab(e) {
26994    e.preventDefault();
26995    var dest = $(e.target).attr('href');
26996    $(e.target).closest('.js-tabs').find('.js-tabs-item').removeClass('is-active');
26997    $(e.target).parent().addClass('is-active');
26998
26999    //  hide active tabs.
27000    $(e.target).closest('.js-tabs').find('.js-tabs-content').removeClass('is-active');
27001
27002    // show active tabs.
27003    $(e.target).closest('.js-tabs').find(dest).addClass('is-active');
27004  }
27005};
27006module.exports = tabs;
27007
27008},{}],69:[function(require,module,exports){
27009"use strict";
27010
27011function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
27012function _possibleConstructorReturn(t, e) { if (e && ("object" == _typeof(e) || "function" == typeof e)) return e; if (void 0 !== e) throw new TypeError("Derived constructors may only return object or undefined"); return _assertThisInitialized(t); }
27013function _assertThisInitialized(e) { if (void 0 === e) throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); return e; }
27014function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
27015function _getPrototypeOf(t) { return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) { return t.__proto__ || Object.getPrototypeOf(t); }, _getPrototypeOf(t); }
27016function _inherits(t, e) { if ("function" != typeof e && null !== e) throw new TypeError("Super expression must either be null or a function");
27016 t.prototype = Object.create(e && e.prototype, { constructor: { value: t, writable: !0, configurable: !0 } }), Object.defineProperty(t, "prototype", { writable: !1 }), e && _setPrototypeOf(t, e); }
27017function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) { return t.__proto__ = e, t; }, _setPrototypeOf(t, e); }
27018function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
27019function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
27020function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
27021function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
27022function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
27023function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
27024var btns = [];
27025var BtnOpen = /*#__PURE__*/function () {
27026  function BtnOpen($el, storage) {
27027    _classCallCheck(this, BtnOpen);
27028    this.storage = storage;
27029    this.counter = $el;
27030    this.count = 0;
27031    this.btn = $el.parents('.button--icon');
27032    this.btns = [];
27033  }
27034  return _createClass(BtnOpen, [{
27035    key: "initCount",
27036    value: function initCount() {
27037      this.setCounter(this.storage.count);
27038    }
27039  }, {
27040    key: "setCounter",
27041    value: function setCounter(count) {
27042      if (count < 1) {
27043        this.counter.hide();
27044      } else {
27045        this.counter.show();
27046      }
27047      this.count = count;
27048      this.counter.text(count);
27049      this.onUpdate();
27050    }
27051  }, {
27052    key: "refreshAll",
27053    value: function refreshAll() {
27054      this.btns.forEach(function (btn) {
27055        return btn.refresh();
27056      });
27057    }
27058  }, {
27059    key: "onUpdate",
27060    value: function onUpdate() {}
27061  }]);
27062}();
27063var CompBtn = /*#__PURE__*/function (_BtnOpen) {
27064  function CompBtn() {
27065    _classCallCheck(this, CompBtn);
27066    return _callSuper(this, CompBtn, arguments);
27067  }
27068  _inherits(CompBtn, _BtnOpen);
27069  return _createClass(CompBtn, [{
27070    key: "onUpdate",
27071    value: function onUpdate() {
27072      if (this.count < 2) {
27073        this.btn.addClass('is-disabled');
27074      } else {
27075        this.btn.removeClass('is-disabled');
27076      }
27077      if (this.count > 3) {
27078        this.btns.forEach(function (btn) {
27079          return btn.disable();
27080        });
27081      } else {
27082        this.btns.forEach(function (btn) {
27083          return btn.enable();
27084        });
27085      }
27086    }
27087  }]);
27088}(BtnOpen);
27089var FavBtn = /*#__PURE__*/function (_BtnOpen2) {
27090  function FavBtn() {
27091    _classCallCheck(this, FavBtn);
27092    return _callSuper(this, FavBtn, arguments);
27093  }
27094  _inherits(FavBtn, _BtnOpen2);
27095  return _createClass(FavBtn, [{
27096    key: "onUpdate",
27097    value: function onUpdate() {
27098      if (this.count < 1) {
27099        this.btn.addClass('is-disabled');
27100      } else {
27101        this.btn.removeClass('is-disabled');
27102      }
27103    }
27104  }]);
27105}(BtnOpen);
27106var ToggleBtn = /*#__PURE__*/function () {
27107  function ToggleBtn(el) {
27108    _classCallCheck(this, ToggleBtn);
27109    this.el = el;
27110    this.$el = $(el);
27111    this.$title = this.$el.find('.title');
27112    this.txtActive = this.$title.data('active');
27113    this.txtInactive = this.$title.data('inactive');
27114    try {
27115      this.data = this.$el.data('data');
27116    } catch (e) {
27117      return;
27118    }
27119    this.disabled = false;
27120    this.type = this.data.type;
27121    this.familyId = 'familyId' in this.data ? parseInt(this.data.familyId, 10) : 0;
27122    this.productId = 'productId' in this.data ? parseInt(this.data.productId, 10) : 0;
27123    this.counter = null;
27124    this.storage = null;
27125    this.bindEvents();
27126  }
27127  return _createClass(ToggleBtn, [{
27128    key: "init",
27129    value: function init() {
27130      this.active = this.storage.exists(this.familyId, this.productId);
27131      this.setActive(this.active);
27132      this.setTitle();
27133    }
27134  }, {
27135    key: "bindEvents",
27136    value: function bindEvents() {
27137      this.$el.on('click', this.toggleIcon.bind(this));
27138    }
27139  }, {
27140    key: "toggleIcon",
27141    value: function toggleIcon(e) {
27142      e.preventDefault();
27143      if (this.disabled) {
27144        return;
27145      }
27146      if (this.active) {
27147        this.$el.removeClass('is-selected');
27148      } else {
27149        this.$el.addClass('is-selected');
27150      }
27151      if (this.active) {
27152        this.storage.delete(this.familyId, this.productId);
27153      } else {
27154        this.storage.add(this.familyId, this.productId);
27155      }
27156      this.active = !this.active;
27157      if (this.data.type == 'comparator') {
27158        this.comparatorToggled();
27159      } else {
27160        this.favoritesToggled();
27161      }
27162      this.$el.blur();
27163      this.setTitle();
27164    }
27165  }, {
27166    key: "refresh",
27167    value: function refresh() {
27168      var active = this.storage.exists(this.familyId, this.productId);
27169      if (active !== this.active) {
27170        this.active = active;
27171        this.setActive(active);
27172      }
27173    }
27174  }, {
27175    key: "comparatorToggled",
27176    value: function comparatorToggled() {
27177      this.counter.setCounter(this.storage.count);
27178    }
27179  }, {
27180    key: "favoritesToggled",
27181    value: function favoritesToggled() {
27182      var _this = this;
27183      var data = {
27184        familyIds: [],
27185        productIds: []
27186      };
27187      if (this.productId) {
27188        data.productIds.push(this.productId);
27189      } else {
27190        data.familyIds.push(this.familyId);
27191      }
27192      $.ajax({
27193        url: window.nexansConfig.favoritesServiceUrl.replace('{action}', this.active ? 'add' : 'remove'),
27194        type: 'POST',
27195        contentType: "application/json; charset=utf-8",
27196        data: JSON.stringify(data)
27197      }).done(function (data) {
27198        _this.storage.refresh(data);
27199        _this.counter.setCounter(data.nbItems);
27200      });
27201    }
27202  }, {
27203    key: "setTitle",
27204    value: function setTitle() {
27205      this.$title.text(this.active ? this.txtActive : this.txtInactive);
27206    }
27207  }, {
27208    key: "setActive",
27209    value: function setActive(active) {
27210      if (active) {
27211        this.$el.addClass('is-selected');
27212        this.enable();
27213      } else {
27214        this.$el.removeClass('is-selected');
27215      }
27216    }
27217  }, {
27218    key: "enable",
27219    value: function enable() {
27220      this.disabled = false;
27221      this.$el.removeClass('is-disabled');
27222    }
27223  }, {
27224    key: "disable",
27225    value: function disable() {
27226      if (!this.active) {
27227        this.disabled = true;
27228        this.$el.addClass('is-disabled');
27229      }
27230    }
27231  }]);
27232}();
27233var toggleIcon = {
27234  init: function init(storage, elements) {
27235    var firstLoad = false;
27236    var favBtn, compBtn;
27237    if (!elements) {
27238      elements = $('.js-toggle-icon');
27239      firstLoad = true;
27240    }
27241    if (firstLoad && $('.js-favorite-count').length) {
27242      favBtn = new FavBtn($('.js-favorite-count'), storage.favorites);
27243      favBtn.initCount();
27244      var resetCount = function resetCount() {
27245        $.ajax({
27246          url: window.nexansConfig.favoritesServiceUrl.replace('{action}', 'count'),
27247          type: 'GET'
27248        }).done(function (data) {
27249          storage.favorites.refresh(data);
27250          favBtn.setCounter(data.nbItems);
27251          favBtn.refreshAll();
27252        });
27253      };
27254      if (storage.favorites.notStored) {
27255        resetCount();
27256      } else {
27257        favBtn.initCount();
27258      }
27259      $('body').on('favourites_update', function (e, count) {
27260        if (typeof count !== 'undefined') {
27261          favBtn.setCounter(count);
27262        } else {
27263          resetCount();
27264        }
27265      });
27266    }
27267    if (firstLoad && $('.js-comparator-count').length) {
27268      compBtn = new CompBtn($('.js-comparator-count'), storage.comparator);
27269      compBtn.initCount();
27270      $('body').on('comparator_update', function (e, count, refresh) {
27271        compBtn.setCounter(count);
27272        if (refresh) compBtn.refreshAll();
27273      });
27274    }
27275    elements.each(function () {
27276      var bt = new ToggleBtn(this);
27277      if (bt.type === 'comparator') {
27278        bt.counter = compBtn;
27279        bt.storage = storage.comparator;
27280        compBtn.btns.push(bt);
27281      } else {
27282        bt.counter = favBtn;
27283        bt.storage = storage.favorites;
27284        favBtn.btns.push(bt);
27285      }
27286      bt.init();
27287    });
27288  }
27289};
27290module.exports = toggleIcon;
27291
27292},{}],70:[function(require,module,exports){
27293"use strict";
27294
27295var toggleVideo = {
27296  ui: {},
27297  init: function init() {
27298    this.bindUI();
27299    this.bindEvents();
27300  },
27301  bindUI: function bindUI() {
27302    this.ui.$window = $(window);
27303    this.ui.$toggle = $('.js-toggle-video');
27304  },
27305  bindEvents: function bindEvents() {
27306    this.ui.$toggle.on('click', this.showVideo);
27307  },
27308  showVideo: function showVideo(e) {
27309    $(e.currentTarget).addClass('is-play');
27310    var $self = $(this),
27311      $overlay = $self.closest('.js-video-overlay');
27312    $overlay.addClass('is-invisible');
27313  }
27314};
27315module.exports = toggleVideo;
27316
27317},{}],71:[function(require,module,exports){
27318"use strict";
27319
27320var truncate = {
27321  ui: {},
27322  truncateHeight: 245,
27323  init: function init() {
27324    this.bindUI();
27325    this.bindEvents();
27326  },
27327  bindUI: function bindUI() {
27328    this.ui.$win = $(window);
27329    this.ui.$mobileIndicator = $('.js-is-mobile');
27330    this.ui.$wrapper = $('.js-truncate');
27331    this.ui.$content = $('.js-truncate-content');
27332    this.ui.$trigger = $('.js-truncate-trigger');
27333  },
27334  bindEvents: function bindEvents() {
27335    var _this = this;
27336    this.ui.$trigger.on('click', $.proxy(this.showMore, this));
27337    this.ui.$win.on('load', function () {
27338      return _this.heightHandler();
27339    });
27340    this.ui.$win.on('resize', function () {
27341      return _this.heightHandler();
27342    });
27343  },
27344  heightHandler: function heightHandler() {
27345    if (this.ui.$content.prop('scrollHeight') >= this.truncateHeight) {
27346      this.ui.$wrapper.addClass('is-truncated');
27347    } else {
27348      this.ui.$wrapper.removeClass('is-truncated');
27349    }
27350  },
27351  showMore: function showMore(e) {
27352    e.preventDefault();
27353    this.ui.$content.stop().show();
27354    this.ui.$wrapper.toggleClass('is-open');
27355  }
27356};
27357module.exports = truncate;
27358
27359},{}],72:[function(require,module,exports){
27360"use strict";
27361
27362var utils = {
27363  ui: {},
27364  init: function init() {
27365    this.bindUI();
27366    this.bindEvents();
27367  },
27368  bindUI: function bindUI() {
27369    this.ui.$win = $(window);
27370    this.ui.$body = $('body');
27371  },
27372  bindEvents: function bindEvents() {
27373    var self = this;
27374
27375    // Events for scroll.
27376    this.ui.$win.on('scroll', this.throttle(function (event) {
27377      self.ui.$body.trigger('page:scrollDebounced', self.ui.$win.scrollTop());
27378    }, 10));
27379    this.ui.$win.on('scroll', function (event) {
27380      self.ui.$body.trigger('page:scroll', self.ui.$win.scrollTop());
27381    });
27382  },
27383  throttle: function throttle(callback, limit) {
27384    var wait = false; // Initially, we're not waiting
27385    return function () {
27386      // We return a
27387      if (!wait) {
27388        callback.call(); // Execute users function
27389        wait = true; // Prevent future invocations
27390        setTimeout(function () {
27391          // After a period of time
27392          wait = false; // And allow future invocations
27393        }, limit);
27394      }
27395    };
27396  }
27397};
27398module.exports = utils;
27399
27400},{}],73:[function(require,module,exports){
27401"use strict";
27402
27403var viewMore = {
27404  ui: {},
27405  init: function init() {
27406    this.bindUI();
27407    this.bindEvents();
27408    this.ui.$moreWrapper.each(function () {
27409      var $this = $(this);
27410      if ($this.hasClass('is-opened')) {
27411        $this.find('.js-view-more').trigger('click');
27412      }
27413    });
27414  },
27415  bindUI: function bindUI() {
27416    this.ui.$win = $(window);
27417    this.ui.$body = $('body');
27418    this.ui.$btnMore = $('.js-view-more');
27419    this.ui.$btnMoreList = $('.js-view-more-list');
27420    this.ui.$btnMoreButton = $('.js-view-more-button');
27421    this.ui.$moreWrapper = $('.js-view-more-wrapper');
27422    this.ui.$moreContent = $('.js-view-more-content');
27423  },
27424  bindEvents: function bindEvents() {
27425    this.ui.$btnMore.on('click', $.proxy(this.showMore, this));
27426    this.ui.$btnMoreButton.on('click', $.proxy(this.showMoreButton, this));
27427    this.ui.$btnMoreList.on('click', $.proxy(this.showMoreList, this));
27428  },
27429  showMore: function showMore(e) {
27430    e.preventDefault();
27431    var $item = $(e.currentTarget).closest('.js-view-more-wrapper');
27432    var $items = $item.find(this.ui.$moreContent);
27433    if (!$(e.currentTarget).hasClass('is-less')) {
27434      $($items).fadeIn();
27435      $item.addClass('is-opened');
27436    } else {
27437      $($items).hide();
27438      $item.removeClass('is-opened');
27439    }
27440    $(e.currentTarget).toggleClass('is-less');
27441  },
27442  showMoreButton: function showMoreButton(e) {
27443    e.preventDefault();
27444    var $item = $(e.currentTarget).closest('.js-view-more-wrapper');
27445    var $this = $item.find(this.ui.$moreContent);
27446    $($this).fadeIn();
27447    $(e.currentTarget).addClass('is-hidden');
27448  },
27449  showMoreList: function showMoreList(e) {
27450    e.preventDefault();
27451    var $item = $(e.currentTarget).closest('.js-view-more-wrapper');
27452    var $items = $item.find(this.ui.$moreContent);
27453    if (!$(e.currentTarget).hasClass('is-less')) {
27454      $($items).fadeIn();
27455    } else {
27456      $($items).hide();
27457    }
27458
27459    //$(e.currentTarget).addClass('is-hidden');
27460
27461    $(e.currentTarget).toggleClass('is-less');
27462  }
27463};
27464module.exports = viewMore;
27465
27466},{}],74:[function(require,module,exports){
27467"use strict";
27468
27469// Plugin Carousel.
27470
27471(function ($) {
27472  $.fn.carouselFinance = function (options) {
27473    // Create defaults parameters in case we don't pass any argument.
27474    var defaults = {};
27475
27476    // Merge the defaults and the options arguments.
27477    var options = $.extend(defaults, options);
27478
27479    // Launch the carousel function.
27480    return this.each(function (index, element) {
27481      var carousel = {
27482        ui: {},
27483        itemActive: 0,
27484        slidesLength: 0,
27485        counterCurrent: 0,
27486        currentCaption: "",
27487        touchVariables: {
27488          "posXStart": 0,
27489          "posAlreadyScrolled": 0,
27490          "posXMove": 0,
27491          "toScrollTouch": 0,
27492          "delta": 0,
27493          "goTranslate": 0
27494        },
27495        init: function init() {
27496          this.bindUI();
27497          this.bindEvents();
27498          this.initSlider();
27499        },
27500        bindUI: function bindUI() {
27501          this.ui.$win = $(window);
27502          this.ui.$container = element;
27503          this.ui.$slider = $('.js-carousel-finance-slider', this.ui.$container);
27504          this.ui.$wrapper = $('.js-carousel-finance-wrapper', this.ui.$container);
27505          this.ui.$slide = $('.js-carousel-finance-slide', this.ui.$container);
27506          this.ui.$captions = $('.js-carousel-finance-captions li', this.ui.$container);
27507          this.ui.$counter = $('.js-carousel-finance-counter', this.ui.$container);
27508          this.ui.$total = $('.js-carousel-finance-total', this.ui.$container);
27509          this.ui.$cover = $('.js-carousel-finance-cover', this.ui.$container);
27510          this.ui.$prev = $('.js-carousel-finance-prev', this.ui.$container);
27511          this.ui.$next = $('.js-carousel-finance-next', this.ui.$container);
27512        },
27513        bindEvents: function bindEvents() {
27514          this.ui.$next.on('click', $.proxy(this.onNext, this));
27515          this.ui.$prev.on('click', $.proxy(this.onPrev, this));
27516          this.ui.$slide.on('touchstart', $.proxy(this.dragStart, this));
27517          this.ui.$slide.on('touchmove', $.proxy(this.dragMove, this));
27518          this.ui.$slide.on('touchend', $.proxy(this.dragEnd, this));
27519          this.ui.$win.on('resize', $.proxy(this.setSize, this));
27520        },
27521        initSlider: function initSlider() {
27522          // Setting up the slides length
27523          this.slidesLength = this.ui.$slide.length;
27524
27525          //Build Counter
27526          this.updateCounter();
27527
27528          // Hide prev button on load
27529          this.fadeBtn();
27530          this.showCover(this.itemActive + 1);
27531          this.setSize();
27532        },
27533        setSize: function setSize() {
27534          var widthTotal = 0;
27535          var widthItem = 0;
27536          widthItem = $('.carousel-finance__item-wrapper').outerWidth() - 40;
27537          $.each(this.ui.$slide, function () {
27538            widthTotal += $('.js-carousel-finance-slide').outerWidth();
27539          });
27540          $('.js-carousel-finance-slide').width(widthItem);
27541          $('.js-carousel-finance-wrapper').width(widthTotal);
27542          this.translateTo();
27543        },
27544        updateCounter: function buildCounter() {
27545          // Setting up the counter to match the current active slide
27546          this.ui.$counter.text(this.itemActive + 1);
27547
27548          // Setting up the counter total to match the slides length
27549          this.ui.$total.text(this.slidesLength);
27550        },
27551        translateTo: function translateTo() {
27552          var translate = 0;
27553          for (var i = 0; i < this.itemActive; i++) {
27554            translate -= Math.round($(this.ui.$slide[i]).outerWidth());
27555          }
27556          this.ui.$wrapper.css({
27557            "transform": "translateX(" + translate + "px)"
27558          });
27559          this.fadeBtn();
27560        },
27561        showCover: function showCover(id) {
27562          $('.js-carousel-finance-cover').removeClass('is-active');
27563          var $currentList = $('.js-carousel-finance').find('.js-carousel-finance-cover[data-cover=' + id + ']');
27564          $currentList.addClass('is-active');
27565        },
27566        onNext: function onNext(e) {
27567          if (this.itemActive == this.slidesLength - 1) {
27568            return;
27569          }
27570          this.itemActive++;
27571          this.updateCounter();
27572          this.translateTo();
27573          this.showCover(this.itemActive + 1);
27574        },
27575        onPrev: function onPrev(e) {
27576          if (this.itemActive == 0) {
27577            return;
27578          }
27579          this.itemActive--;
27580          this.updateCounter();
27581          this.translateTo();
27582          this.showCover(this.itemActive + 1);
27583        },
27584        dragStart: function dragStart(e) {
27585          this.touchVariables.posXStart = e.originalEvent.touches[0].pageX;
27586        },
27587        dragMove: function dragMove(e) {
27588          this.touchVariables.posXMove = e.originalEvent.touches[0].pageX;
27589          this.touchVariables.delta = this.touchVariables.posXMove - this.touchVariables.posXStart;
27590        },
27591        dragEnd: function dragEnd() {
27592          if (this.touchVariables.delta > 0) {
27593            this.onPrev();
27594          } else if (this.touchVariables.delta < 0) {
27595            this.onNext();
27596          }
27597          this.touchVariables.delta = 0;
27598        },
27599        fadeBtn: function fadeBtn() {
27600          if (this.itemActive == 0) {
27601            this.ui.$next.removeClass('is-fade');
27602            this.ui.$prev.addClass('is-fade');
27603          } else if (this.ui.$slide.length - 1 == this.itemActive) {
27604            this.ui.$next.addClass('is-fade');
27605            this.ui.$prev.removeClass('is-fade');
27606          } else {
27607            this.ui.$next.removeClass('is-fade');
27608            this.ui.$prev.removeClass('is-fade');
27609          }
27610        }
27611      };
27612
27613      // Intialize the carousel.
27614      carousel.init();
27615    });
27616  };
27617})(jQuery);
27618
27619},{}],75:[function(require,module,exports){
27620"use strict";
27621
27622// Plugin Carousel.
27623
27624(function ($) {
27625  $.fn.carouselGallery = function (options) {
27626    // Create defaults parameters in case we don't pass any argument.
27627    var defaults = {};
27628
27629    // Merge the defaults and the options arguments.
27630    var options = $.extend(defaults, options);
27631
27632    // Launch the carousel function.
27633    return this.each(function (index, element) {
27634      var carousel = {
27635        ui: {},
27636        itemActive: 0,
27637        slidesLength: 0,
27638        counterCurrent: 0,
27639        currentCaption: "",
27640        touchVariables: {
27641          "posXStart": 0,
27642          "posAlreadyScrolled": 0,
27643          "posXMove": 0,
27644          "toScrollTouch": 0,
27645          "delta": 0,
27646          "goTranslate": 0
27647        },
27648        init: function init() {
27649          this.bindUI();
27650          this.bindEvents();
27651          this.initSlider();
27652        },
27653        bindUI: function bindUI() {
27654          this.ui.$win = $(window);
27655          this.ui.$container = element;
27656          this.ui.$slider = $('.js-carousel-gallery-slider', this.ui.$container);
27657          this.ui.$wrapper = $('.js-carousel-gallery-wrapper', this.ui.$container);
27658          this.ui.$slide = $('.js-carousel-gallery-slide', this.ui.$container);
27659          this.ui.$captions = $('.js-carousel-gallery-legend', this.ui.$container);
27660          this.ui.$counter = $('.js-carousel-gallery-captions .slide-id', this.ui.$container);
27661          this.ui.$total = $('.js-carousel-gallery-captions .slide-total', this.ui.$container);
27662          this.ui.$prev = $('.js-carousel-gallery-prev', this.ui.$container);
27663          this.ui.$next = $('.js-carousel-gallery-next', this.ui.$container);
27664          this.ui.$galleryItem = $('.js-gallery-item');
27665          this.ui.$gallertModal = $('.js-modal');
27666          this.ui.$closeModal = $('.js-modal .js-modal-close');
27667        },
27668        bindEvents: function bindEvents() {
27669          this.ui.$next.on('click', $.proxy(this.onNext, this));
27670          this.ui.$prev.on('click', $.proxy(this.onPrev, this));
27671          this.ui.$slide.on('touchstart', $.proxy(this.dragStart, this));
27672          this.ui.$slide.on('touchmove', $.proxy(this.dragMove, this));
27673          this.ui.$slide.on('touchend', $.proxy(this.dragEnd, this));
27674          this.ui.$galleryItem.on('click', $.proxy(this.loadSlider, this));
27675          this.ui.$closeModal.on('click', $.proxy(this.resetSlider, this));
27676        },
27677        initSlider: function initSlider() {
27678          // Setting up the slides length
27679          this.slidesLength = this.ui.$slide.length;
27680
27681          //Build Counter
27682          this.updateCounter();
27683
27684          //Build Captions
27685          this.updateCaptions();
27686
27687          // Hide prev button on load
27688          this.fadeBtn();
27689        },
27690        updateCounter: function buildCounter() {
27691          // Setting up the counter to match the current active slide
27692          this.ui.$counter.text(this.itemActive + 1);
27693
27694          // Setting up the counter total to match the slides length
27695          this.ui.$total.text(this.slidesLength);
27696        },
27697        updateCaptions: function buildCaptions() {
27698          // Retrieve the active slide's data-caption and set the correct caption
27699          this.currentCaption = this.ui.$wrapper.find('.js-carousel-gallery-slide').eq(this.itemActive).data('caption');
27700          this.ui.$captions.text(this.currentCaption);
27701        },
27702        translateTo: function translateTo() {
27703          var translate = 0;
27704          for (var i = 0; i < this.itemActive; i++) {
27705            translate -= Math.round($(this.ui.$slide[i]).outerWidth());
27706          }
27707          this.ui.$wrapper.css({
27708            "transform": "translateX(" + translate + "px)"
27709          });
27710          this.fadeBtn();
27711        },
27712        onNext: function onNext(e) {
27713          if (this.itemActive == this.slidesLength - 1) {
27714            return;
27715          }
27716          this.itemActive++;
27717          this.updateCounter();
27718          this.updateCaptions();
27719          this.translateTo();
27720        },
27721        onPrev: function onPrev(e) {
27722          if (this.itemActive == 0) {
27723            return;
27724          }
27725          this.itemActive--;
27726          this.updateCounter();
27727          this.updateCaptions();
27728          this.translateTo();
27729        },
27730        dragStart: function dragStart(e) {
27731          this.touchVariables.posXStart = e.originalEvent.touches[0].pageX;
27732        },
27733        dragMove: function dragMove(e) {
27734          this.touchVariables.posXMove = e.originalEvent.touches[0].pageX;
27735          this.touchVariables.delta = this.touchVariables.posXMove - this.touchVariables.posXStart;
27736        },
27737        dragEnd: function dragEnd() {
27738          if (this.touchVariables.delta > 0) {
27739            this.onPrev();
27740          } else if (this.touchVariables.delta < 0) {
27741            this.onNext();
27742          }
27743          this.touchVariables.delta = 0;
27744        },
27745        fadeBtn: function fadeBtn() {
27746          if (this.itemActive == 0) {
27747            this.ui.$next.removeClass('is-fade');
27748            this.ui.$prev.addClass('is-fade');
27749          } else if (this.ui.$slide.length - 1 == this.itemActive) {
27750            this.ui.$next.addClass('is-fade');
27751            this.ui.$prev.removeClass('is-fade');
27752          } else {
27753            this.ui.$next.removeClass('is-fade');
27754            this.ui.$prev.removeClass('is-fade');
27755          }
27756        },
27757        loadSlider: function loadSlider(e) {
27758          var $el = $(e.currentTarget),
27759            ref = $el.data('ref'),
27760            modal = $el.data('modal'),
27761            index = 0;
27762
27763          // find modal active.
27764          $.each(this.ui.$gallertModal, function () {
27765            if (modal = $(this).data('modal')) {
27766              // find list of slide.
27767              var wrapper = $(this).find('.js-carousel-gallery-wrapper');
27768
27769              // get index of slide.
27770              var itemByRef = $(this).find("[data-ref='" + ref + "']");
27771              index = itemByRef.index() + 1;
27772            }
27773          });
27774
27775          // test if item sup 1
27776          if (index > 1) {
27777            for (var i = 1; i < index; i++) {
27778              this.ui.$next.trigger("click");
27779            }
27780          } else if (index = 1) {}
27781        },
27782        resetSlider: function resetSlider(e) {
27783          e.preventDefault();
27784          setTimeout(function () {
27785            var translate = 0;
27786            $('.js-carousel-gallery-wrapper').css({
27787              "transform": "translateX(" + translate + "px)"
27788            });
27789            this.itemActive = 0;
27790            this.counterCurrent = 0;
27791            this.currentCaption = "";
27792          }, 200);
27793        }
27794      };
27795
27796      // Intialize the carousel.
27797      carousel.init();
27798    });
27799  };
27800})(jQuery);
27801
27802},{}],76:[function(require,module,exports){
27803"use strict";
27804
27805// Plugin Carousel.
27806
27807(function ($) {
27808  $.fn.carouselOverlay = function (options) {
27809    // Create defaults parameters in case we don't pass any argument.
27810    var defaults = {};
27811
27812    // Merge the defaults and the options arguments.
27813    var options = $.extend(defaults, options);
27814
27815    // Launch the carousel function.
27816    return this.each(function (index, element) {
27817      var carousel = {
27818        ui: {},
27819        itemActive: 0,
27820        slidesLength: 0,
27821        counterCurrent: 0,
27822        currentCaption: "",
27823        touchVariables: {
27824          "posXStart": 0,
27825          "posAlreadyScrolled": 0,
27826          "posXMove": 0,
27827          "toScrollTouch": 0,
27828          "delta": 0,
27829          "goTranslate": 0
27830        },
27831        init: function init() {
27832          this.bindUI();
27833          this.bindEvents();
27834          this.initSlider();
27835        },
27836        bindUI: function bindUI() {
27837          this.ui.$win = $(window);
27838          this.ui.$body = $('body');
27839          this.ui.$container = element;
27840          this.ui.$slider = $('.js-carousel-overlay-slider', this.ui.$container);
27841          this.ui.$wrapper = $('.js-carousel-overlay-wrapper', this.ui.$container);
27842          this.ui.$slide = $('.js-carousel-overlay-slide', this.ui.$container);
27843          this.ui.$captions = $('.js-carousel-overlay-legend', this.ui.$container);
27844          this.ui.$counter = $('.js-carousel-overlay-captions .slide-id', this.ui.$container);
27845          this.ui.$total = $('.js-carousel-overlay-captions .slide-total', this.ui.$container);
27846          this.ui.$prev = $('.js-carousel-overlay-prev', this.ui.$container);
27847          this.ui.$next = $('.js-carousel-overlay-next', this.ui.$container);
27848          this.ui.$btnOpen = $('.js-carousel-open');
27849          this.ui.$btnClose = $('.js-close-panel');
27850          this.ui.container = $('.js-carousel-overlay');
27851        },
27852        bindEvents: function bindEvents() {
27853          this.ui.$next.on('click', $.proxy(this.onNext, this));
27854          this.ui.$prev.on('click', $.proxy(this.onPrev, this));
27855          this.ui.$slide.on('touchstart', $.proxy(this.dragStart, this));
27856          this.ui.$slide.on('touchmove', $.proxy(this.dragMove, this));
27857          this.ui.$slide.on('touchend', $.proxy(this.dragEnd, this));
27858          this.ui.$btnOpen.on('click', $.proxy(this.openCarousel, this));
27859          this.ui.$btnClose.on('click', $.proxy(this.closeCarousel, this));
27860          $(document).on('keyup', $.proxy(this.closeCarousel, this));
27861        },
27862        initSlider: function initSlider() {
27863          // Setting up the slides length
27864          this.slidesLength = this.ui.$slide.length;
27865
27866          //Build Counter
27867          this.updateCounter();
27868
27869          //Build Captions
27870          this.updateCaptions();
27871
27872          // Hide prev button on load
27873          this.fadeBtn();
27874        },
27875        updateCounter: function buildCounter() {
27876          // Setting up the counter to match the current active slide
27877          this.ui.$counter.text(this.itemActive + 1);
27878
27879          // Setting up the counter total to match the slides length
27880          this.ui.$total.text(this.slidesLength);
27881        },
27882        updateCaptions: function buildCaptions() {
27883          // Retrieve the active slide's data-caption and set the correct caption
27884          this.currentCaption = this.ui.$wrapper.find('.js-carousel-overlay-slide').eq(this.itemActive).data('caption');
27885          this.ui.$captions.text(this.currentCaption);
27886        },
27887        translateTo: function translateTo() {
27888          var translate = 0;
27889          for (var i = 0; i < this.itemActive; i++) {
27890            translate -= Math.round($(this.ui.$slide[i]).outerWidth());
27891          }
27892          this.ui.$wrapper.css({
27893            "-webkit-transform": "translateX(" + translate + "px)",
27894            "-moz-transform": "translateX(" + translate + "px)",
27895            "-ms-transform": "translateX(" + translate + "px)",
27896            "-o-transform": "translateX(" + translate + "px)",
27897            "transform": "translateX(" + translate + "px)"
27898          });
27899          this.fadeBtn();
27900        },
27901        translateToItem: function translateToItem(itemId) {
27902          console.log(itemId);
27903        },
27904        onNext: function onNext(e) {
27905          if (this.itemActive == this.slidesLength - 1) {
27906            return;
27907          }
27908          this.itemActive++;
27909          this.updateCounter();
27910          this.updateCaptions();
27911          this.translateTo();
27912        },
27913        onPrev: function onPrev(e) {
27914          if (this.itemActive == 0) {
27915            return;
27916          }
27917          this.itemActive--;
27918          this.updateCounter();
27919          this.updateCaptions();
27920          this.translateTo();
27921        },
27922        dragStart: function dragStart(e) {
27923          this.touchVariables.posXStart = e.originalEvent.touches[0].pageX;
27924        },
27925        dragMove: function dragMove(e) {
27926          this.touchVariables.posXMove = e.originalEvent.touches[0].pageX;
27927          this.touchVariables.delta = this.touchVariables.posXMove - this.touchVariables.posXStart;
27928        },
27929        dragEnd: function dragEnd() {
27930          if (this.touchVariables.delta > 0) {
27931            this.onPrev();
27932          } else if (this.touchVariables.delta < 0) {
27933            this.onNext();
27934          }
27935          this.touchVariables.delta = 0;
27936        },
27937        fadeBtn: function fadeBtn() {
27938          if (this.itemActive == 0) {
27939            this.ui.$next.removeClass('is-fade');
27940            this.ui.$prev.addClass('is-fade');
27941          } else if (this.ui.$slide.length - 1 == this.itemActive) {
27942            this.ui.$next.addClass('is-fade');
27943            this.ui.$prev.removeClass('is-fade');
27944          } else {
27945            this.ui.$next.removeClass('is-fade');
27946            this.ui.$prev.removeClass('is-fade');
27947          }
27948        },
27949        openCarousel: function openCarousel(e) {
27950          // open modale.
27951          this.ui.$body.addClass('is-locked');
27952          this.ui.container.addClass('is-open');
27953
27954          // Get ref Id click
27955          var dataImage = $(e.currentTarget).find('img').data('ref');
27956          this.translateToItem(dataImage);
27957        },
27958        closeCarousel: function closeCarousel(e) {
27959          e.preventDefault();
27960
27961          // close modale. 
27962          this.ui.$body.removeClass('is-locked');
27963          this.ui.container.removeClass('is-open');
27964
27965          // close modal with keyboard esc.
27966          if (e.keyCode == 27) {
27967            this.ui.$body.removeClass('is-locked');
27968            this.ui.container.removeClass('is-open');
27969          }
27970        }
27971      };
27972
27973      // Intialize the carousel.
27974      carousel.init();
27975    });
27976  };
27977})(jQuery);
27978
27979},{}],77:[function(require,module,exports){
27980"use strict";
27981
27982// Plugin Carousel.
27983
27984(function ($) {
27985  $.fn.carouselSimple = function (options) {
27986    // Create defaults parameters in case we don't pass any argument.
27987    var defaults = {};
27988
27989    // Merge the defaults and the options arguments.
27990    var options = $.extend(defaults, options);
27991
27992    // Launch the carousel function.
27993    return this.each(function (index, element) {
27994      var carousel = {
27995        ui: {},
27996        itemActive: 0,
27997        slidesLength: 0,
27998        counterCurrent: 0,
27999        currentCaption: "",
28000        touchVariables: {
28001          "posXStart": 0,
28002          "posAlreadyScrolled": 0,
28003          "posXMove": 0,
28004          "toScrollTouch": 0,
28005          "delta": 0,
28006          "goTranslate": 0
28007        },
28008        init: function init() {
28009          this.bindUI();
28010          this.bindEvents();
28011          this.initSlider();
28012        },
28013        bindUI: function bindUI() {
28014          this.ui.$win = $(window);
28015          this.ui.$container = element;
28016          this.ui.$slider = $('.js-carousel-simple-slider', this.ui.$container);
28017          this.ui.$wrapper = $('.js-carousel-simple-wrapper', this.ui.$container);
28018          this.ui.$slide = $('.js-carousel-simple-slide', this.ui.$container);
28019          this.ui.$captions = $('.js-carousel-simple-captions li', this.ui.$container);
28020          this.ui.$counter = $('.js-carousel-simple-captions .slide-id', this.ui.$container);
28021          this.ui.$total = $('.js-carousel-simple-captions .slide-total', this.ui.$container);
28022          this.ui.$prev = $('.js-carousel-simple-prev', this.ui.$container);
28023          this.ui.$next = $('.js-carousel-simple-next', this.ui.$container);
28024        },
28025        bindEvents: function bindEvents() {
28026          this.ui.$next.on('click', $.proxy(this.onNext, this));
28027          this.ui.$prev.on('click', $.proxy(this.onPrev, this));
28028          this.ui.$slide.on('touchstart', $.proxy(this.dragStart, this));
28029          this.ui.$slide.on('touchmove', $.proxy(this.dragMove, this));
28030          this.ui.$slide.on('touchend', $.proxy(this.dragEnd, this));
28031        },
28032        initSlider: function initSlider() {
28033          // Setting up the slides length
28034          this.slidesLength = this.ui.$slide.length;
28035
28036          //Build Counter
28037          this.updateCounter();
28038
28039          //Build Captions
28040          this.updateCaptions();
28041
28042          // Hide prev button on load
28043          this.fadeBtn();
28044        },
28045        updateCounter: function buildCounter() {
28046          // Setting up the counter to match the current active slide
28047          this.ui.$counter.text(this.itemActive + 1);
28048
28049          // Setting up the counter total to match the slides length
28050          this.ui.$total.text(this.slidesLength);
28051        },
28052        updateCaptions: function buildCaptions() {
28053          // Retrieve the active slide's data-caption and set the correct caption
28054          this.currentCaption = this.ui.$wrapper.find('.js-carousel-simple-slide').eq(this.itemActive).data('caption');
28055          this.ui.$captions.text(this.currentCaption);
28056        },
28057        translateTo: function translateTo() {
28058          var translate = 0;
28059          for (var i = 0; i < this.itemActive; i++) {
28060            translate -= Math.round($(this.ui.$slide[i]).outerWidth());
28061          }
28062          this.ui.$wrapper.css({
28063            "-webkit-transform": "translateX(" + translate + "px)",
28064            "-moz-transform": "translateX(" + translate + "px)",
28065            "-ms-transform": "translateX(" + translate + "px)",
28066            "-o-transform": "translateX(" + translate + "px)",
28067            "transform": "translateX(" + translate + "px)"
28068          });
28069          this.fadeBtn();
28070        },
28071        onNext: function onNext(e) {
28072          if (this.itemActive == this.slidesLength - 1) {
28073            return;
28074          }
28075          this.itemActive++;
28076          this.updateCounter();
28077          this.updateCaptions();
28078          this.translateTo();
28079        },
28080        onPrev: function onPrev(e) {
28081          if (this.itemActive == 0) {
28082            return;
28083          }
28084          this.itemActive--;
28085          this.updateCounter();
28086          this.updateCaptions();
28087          this.translateTo();
28088        },
28089        dragStart: function dragStart(e) {
28090          this.touchVariables.posXStart = e.originalEvent.touches[0].pageX;
28091        },
28092        dragMove: function dragMove(e) {
28093          this.touchVariables.posXMove = e.originalEvent.touches[0].pageX;
28094          this.touchVariables.delta = this.touchVariables.posXMove - this.touchVariables.posXStart;
28095        },
28096        dragEnd: function dragEnd() {
28097          if (this.touchVariables.delta > 0) {
28098            this.onPrev();
28099          } else if (this.touchVariables.delta < 0) {
28100            this.onNext();
28101          }
28102          this.touchVariables.delta = 0;
28103        },
28104        fadeBtn: function fadeBtn() {
28105          if (this.itemActive == 0) {
28106            this.ui.$next.removeClass('is-fade');
28107            this.ui.$prev.addClass('is-fade');
28108          } else if (this.ui.$slide.length - 1 == this.itemActive) {
28109            this.ui.$next.addClass('is-fade');
28110            this.ui.$prev.removeClass('is-fade');
28111          } else {
28112            this.ui.$next.removeClass('is-fade');
28113            this.ui.$prev.removeClass('is-fade');
28114          }
28115        }
28116      };
28117
28118      // Intialize the carousel.
28119      carousel.init();
28120    });
28121  };
28122})(jQuery);
28123
28124},{}]},{},[9]);

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.