PageSourceSearch

https://www.dolomiticontemporanee.net/wp-content/themes/uncode/library/js/plugins.js?ver=1399287713

js dolomiticontemporanee.net collected 2026-09-24 20:29:01 UTC 1,481,599 bytes, 44,832 lines download raw bytes

vendor: 4,970 bytes, lines 1-161
1/* ----------------------------------------------------------
2 * Plugins
3 * ---------------------------------------------------------- */
4
5(function (global, factory) {
6  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
7  typeof define === 'function' && define.amd ? define(['exports'], factory) :
8  (global = global || self, factory(global.window = global.window || {}));
9}(this, (function (exports) { 'use strict';
10
11  function _inheritsLoose(subClass, superClass) {
12    subClass.prototype = Object.create(superClass.prototype);
13    subClass.prototype.constructor = subClass;
14    subClass.__proto__ = superClass;
15  }
16
17  function _assertThisInitialized(self) {
18    if (self === void 0) {
19      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
20    }
21
22    return self;
23  }
24
25  /*!
26   * GSAP 3.12.5
27   * https://gsap.com
28   *
29   * @license Copyright 2008-2024, GreenSock. All rights reserved.
30   * Subject to the terms at https://gsap.com/standard-license or for
31   * Club GSAP members, the agreement issued with that membership.
32   * @author: Jack Doyle, [email protected]
33  */
34  var _config = {
35    autoSleep: 120,
36    force3D: "auto",
37    nullTargetWarn: 1,
38    units: {
39      lineHeight: ""
40    }
41  },
42      _defaults = {
43    duration: .5,
44    overwrite: false,
45    delay: 0
46  },
47      _suppressOverwrites,
48      _reverting,
49      _context,
50      _bigNum = 1e8,
51      _tinyNum = 1 / _bigNum,
52      _2PI = Math.PI * 2,
53      _HALF_PI = _2PI / 4,
54      _gsID = 0,
55      _sqrt = Math.sqrt,
56      _cos = Math.cos,
57      _sin = Math.sin,
58      _isString = function _isString(value) {
59    return typeof value === "string";
60  },
61      _isFunction = function _isFunction(value) {
62    return typeof value === "function";
63  },
64      _isNumber = function _isNumber(value) {
65    return typeof value === "number";
66  },
67      _isUndefined = function _isUndefined(value) {
68    return typeof value === "undefined";
69  },
70      _isObject = function _isObject(value) {
71    return typeof value === "object";
72  },
73      _isNotFalse = function _isNotFalse(value) {
74    return value !== false;
75  },
76      _windowExists = function _windowExists() {
77    return typeof window !== "undefined";
78  },
79      _isFuncOrString = function _isFuncOrString(value) {
80    return _isFunction(value) || _isString(value);
81  },
82      _isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView || function () {},
83      _isArray = Array.isArray,
84      _strictNumExp = /(?:-?\.?\d|\.)+/gi,
85      _numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g,
86      _numWithUnitExp = /[-+=.]*\d+[.e-]*\d*[a-z%]*/g,
87      _complexStringNumExp = /[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi,
88      _relExp = /[+-]=-?[.\d]+/,
89      _delimitedValueExp = /[^,'"\[\]\s]+/gi,
90      _unitExp = /^[+\-=e\s\d]*\d+[.\d]*([a-z]*|%)\s*$/i,
91      _globalTimeline,
92      _win,
93      _coreInitted,
94      _doc,
95      _globals = {},
96      _installScope = {},
97      _coreReady,
98      _install = function _install(scope) {
99    return (_installScope = _merge(scope, _globals)) && gsap;
100  },
101      _missingPlugin = function _missingPlugin(property, value) {
102    return console.warn("Invalid property", property, "set to", value, "Missing plugin? gsap.registerPlugin()");
103  },
104      _warn = function _warn(message, suppress) {
105    return !suppress && console.warn(message);
106  },
107      _addGlobal = function _addGlobal(name, obj) {
108    return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals;
109  },
110      _emptyFunc = function _emptyFunc() {
111    return 0;
112  },
113      _startAtRevertConfig = {
114    suppressEvents: true,
115    isStart: true,
116    kill: false
117  },
118      _revertConfigNoKill = {
119    suppressEvents: true,
120    kill: false
121  },
122      _revertConfig = {
123    suppressEvents: true
124  },
125      _reservedProps = {},
126      _lazyTweens = [],
127      _lazyLookup = {},
128      _lastRenderedFrame,
129      _plugins = {},
130      _effects = {},
131      _nextGCFrame = 30,
132      _harnessPlugins = [],
133      _callbackNames = "",
134      _harness = function _harness(targets) {
135    var target = targets[0],
136        harnessPlugin,
137        i;
138    _isObject(target) || _isFunction(target) || (targets = [targets]);
139
140    if (!(harnessPlugin = (target._gsap || {}).harness)) {
141      i = _harnessPlugins.length;
142
143      while (i-- && !_harnessPlugins[i].targetTest(target)) {}
144
145      harnessPlugin = _harnessPlugins[i];
146    }
147
148    i = targets.length;
149
150    while (i--) {
151      targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1);
152    }
153
154    return targets;
155  },
156      _getCache = function _getCache(target) {
157    return target._gsap || _harness(toArray(target))[0]._gsap;
158  },
159      _getProperty = function _getProperty(target, property, v) {
160    return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v;
161  },
vendor: 6,338 bytes, lines 162-371
162      _forEachName = function _forEachName(names, func) {
163    return (names = names.split(",")).forEach(func) || names;
164  },
165      _round = function _round(value) {
166    return Math.round(value * 100000) / 100000 || 0;
167  },
168      _roundPrecise = function _roundPrecise(value) {
169    return Math.round(value * 10000000) / 10000000 || 0;
170  },
171      _parseRelative = function _parseRelative(start, value) {
172    var operator = value.charAt(0),
173        end = parseFloat(value.substr(2));
174    start = parseFloat(start);
175    return operator === "+" ? start + end : operator === "-" ? start - end : operator === "*" ? start * end : start / end;
176  },
177      _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) {
178    var l = toFind.length,
179        i = 0;
180
181    for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {}
182
183    return i < l;
184  },
185      _lazyRender = function _lazyRender() {
186    var l = _lazyTweens.length,
187        a = _lazyTweens.slice(0),
188        i,
189        tween;
190
191    _lazyLookup = {};
192    _lazyTweens.length = 0;
193
194    for (i = 0; i < l; i++) {
195      tween = a[i];
196      tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0);
197    }
198  },
199      _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) {
200    _lazyTweens.length && !_reverting && _lazyRender();
201    animation.render(time, suppressEvents, force || _reverting && time < 0 && (animation._initted || animation._startAt));
202    _lazyTweens.length && !_reverting && _lazyRender();
203  },
204      _numericIfPossible = function _numericIfPossible(value) {
205    var n = parseFloat(value);
206    return (n || n === 0) && (value + "").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value;
207  },
208      _passThrough = function _passThrough(p) {
209    return p;
210  },
211      _setDefaults = function _setDefaults(obj, defaults) {
212    for (var p in defaults) {
213      p in obj || (obj[p] = defaults[p]);
214    }
215
216    return obj;
217  },
218      _setKeyframeDefaults = function _setKeyframeDefaults(excludeDuration) {
219    return function (obj, defaults) {
220      for (var p in defaults) {
221        p in obj || p === "duration" && excludeDuration || p === "ease" || (obj[p] = defaults[p]);
222      }
223    };
224  },
225      _merge = function _merge(base, toMerge) {
226    for (var p in toMerge) {
227      base[p] = toMerge[p];
228    }
229
230    return base;
231  },
232      _mergeDeep = function _mergeDeep(base, toMerge) {
233    for (var p in toMerge) {
234      p !== "__proto__" && p !== "constructor" && p !== "prototype" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]);
235    }
236
237    return base;
238  },
239      _copyExcluding = function _copyExcluding(obj, excluding) {
240    var copy = {},
241        p;
242
243    for (p in obj) {
244      p in excluding || (copy[p] = obj[p]);
245    }
246
247    return copy;
248  },
249      _inheritDefaults = function _inheritDefaults(vars) {
250    var parent = vars.parent || _globalTimeline,
251        func = vars.keyframes ? _setKeyframeDefaults(_isArray(vars.keyframes)) : _setDefaults;
252
253    if (_isNotFalse(vars.inherit)) {
254      while (parent) {
255        func(vars, parent.vars.defaults);
256        parent = parent.parent || parent._dp;
257      }
258    }
259
260    return vars;
261  },
262      _arraysMatch = function _arraysMatch(a1, a2) {
263    var i = a1.length,
264        match = i === a2.length;
265
266    while (match && i-- && a1[i] === a2[i]) {}
267
268    return i < 0;
269  },
270      _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) {
271    if (firstProp === void 0) {
272      firstProp = "_first";
273    }
274
275    if (lastProp === void 0) {
276      lastProp = "_last";
277    }
278
279    var prev = parent[lastProp],
280        t;
281
282    if (sortBy) {
283      t = child[sortBy];
284
285      while (prev && prev[sortBy] > t) {
286        prev = prev._prev;
287      }
288    }
289
290    if (prev) {
291      child._next = prev._next;
292      prev._next = child;
293    } else {
294      child._next = parent[firstProp];
295      parent[firstProp] = child;
296    }
297
298    if (child._next) {
299      child._next._prev = child;
300    } else {
301      parent[lastProp] = child;
302    }
303
304    child._prev = prev;
305    child.parent = child._dp = parent;
306    return child;
307  },
308      _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) {
309    if (firstProp === void 0) {
310      firstProp = "_first";
311    }
312
313    if (lastProp === void 0) {
314      lastProp = "_last";
315    }
316
317    var prev = child._prev,
318        next = child._next;
319
320    if (prev) {
321      prev._next = next;
322    } else if (parent[firstProp] === child) {
323      parent[firstProp] = next;
324    }
325
326    if (next) {
327      next._prev = prev;
328    } else if (parent[lastProp] === child) {
329      parent[lastProp] = prev;
330    }
331
332    child._next = child._prev = child.parent = null;
333  },
334      _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) {
335    child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove && child.parent.remove(child);
336    child._act = 0;
337  },
338      _uncache = function _uncache(animation, child) {
339    if (animation && (!child || child._end > animation._dur || child._start < 0)) {
340      var a = animation;
341
342      while (a) {
343        a._dirty = 1;
344        a = a.parent;
345      }
346    }
347
348    return animation;
349  },
350      _recacheAncestors = function _recacheAncestors(animation) {
351    var parent = animation.parent;
352
353    while (parent && parent.parent) {
354      parent._dirty = 1;
355      parent.totalDuration();
356      parent = parent.parent;
357    }
358
359    return animation;
360  },
361      _rewindStartAt = function _rewindStartAt(tween, totalTime, suppressEvents, force) {
362    return tween._startAt && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween.vars.immediateRender && !tween.vars.autoRevert || tween._startAt.render(totalTime, true, force));
363  },
364      _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) {
365    return !animation || animation._ts && _hasNoPausedAncestors(animation.parent);
366  },
367      _elapsedCycleDuration = function _elapsedCycleDuration(animation) {
368    return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0;
369  },
370      _animationCycle = function _animationCycle(tTime, cycleDuration) {
371    var whole = Math.floor(tTime /= cycleDuration
vendor: 17,487 bytes, lines 371-839
371);
372    return tTime && whole === tTime ? whole - 1 : whole;
373  },
374      _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) {
375    return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur);
376  },
377      _setEnd = function _setEnd(animation) {
378    return animation._end = _roundPrecise(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0));
379  },
380      _alignPlayhead = function _alignPlayhead(animation, totalTime) {
381    var parent = animation._dp;
382
383    if (parent && parent.smoothChildTiming && animation._ts) {
384      animation._start = _roundPrecise(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts));
385
386      _setEnd(animation);
387
388      parent._dirty || _uncache(parent, animation);
389    }
390
391    return animation;
392  },
393      _postAddChecks = function _postAddChecks(timeline, child) {
394    var t;
395
396    if (child._time || !child._dur && child._initted || child._start < timeline._time && (child._dur || !child.add)) {
397      t = _parentToChildTotalTime(timeline.rawTime(), child);
398
399      if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) {
400        child.render(t, true);
401      }
402    }
403
404    if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) {
405      if (timeline._dur < timeline.duration()) {
406        t = timeline;
407
408        while (t._dp) {
409          t.rawTime() >= 0 && t.totalTime(t._tTime);
410          t = t._dp;
411        }
412      }
413
414      timeline._zTime = -_tinyNum;
415    }
416  },
417      _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) {
418    child.parent && _removeFromParent(child);
419    child._start = _roundPrecise((_isNumber(position) ? position : position || timeline !== _globalTimeline ? _parsePosition(timeline, position, child) : timeline._time) + child._delay);
420    child._end = _roundPrecise(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0));
421
422    _addLinkedListItem(timeline, child, "_first", "_last", timeline._sort ? "_start" : 0);
423
424    _isFromOrFromStart(child) || (timeline._recent = child);
425    skipChecks || _postAddChecks(timeline, child);
426    timeline._ts < 0 && _alignPlayhead(timeline, timeline._tTime);
427    return timeline;
428  },
429      _scrollTrigger = function _scrollTrigger(animation, trigger) {
430    return (_globals.ScrollTrigger || _missingPlugin("scrollTrigger", trigger)) && _globals.ScrollTrigger.create(trigger, animation);
431  },
432      _attemptInitTween = function _attemptInitTween(tween, time, force, suppressEvents, tTime) {
433    _initTween(tween, time, tTime);
434
435    if (!tween._initted) {
436      return 1;
437    }
438
439    if (!force && tween._pt && !_reverting && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) {
440      _lazyTweens.push(tween);
441
442      tween._lazy = [tTime, suppressEvents];
443      return 1;
444    }
445  },
446      _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) {
447    var parent = _ref.parent;
448    return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent));
449  },
450      _isFromOrFromStart = function _isFromOrFromStart(_ref2) {
451    var data = _ref2.data;
452    return data === "isFromStart" || data === "isStart";
453  },
454      _renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) {
455    var prevRatio = tween.ratio,
456        ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) && !(!tween._initted && _isFromOrFromStart(tween)) || (tween._ts < 0 || tween._dp._ts < 0) && !_isFromOrFromStart(tween)) ? 0 : 1,
457        repeatDelay = tween._rDelay,
458        tTime = 0,
459        pt,
460        iteration,
461        prevIteration;
462
463    if (repeatDelay && tween._repeat) {
464      tTime = _clamp(0, tween._tDur, totalTime);
465      iteration = _animationCycle(tTime, repeatDelay);
466      tween._yoyo && iteration & 1 && (ratio = 1 - ratio);
467
468      if (iteration !== _animationCycle(tween._tTime, repeatDelay)) {
469        prevRatio = 1 - ratio;
470        tween.vars.repeatRefresh && tween._initted && tween.invalidate();
471      }
472    }
473
474    if (ratio !== prevRatio || _reverting || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) {
475      if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents, tTime)) {
476        return;
477      }
478
479      prevIteration = tween._zTime;
480      tween._zTime = totalTime || (suppressEvents ? _tinyNum : 0);
481      suppressEvents || (suppressEvents = totalTime && !prevIteration);
482      tween.ratio = ratio;
483      tween._from && (ratio = 1 - ratio);
484      tween._time = 0;
485      tween._tTime = tTime;
486      pt = tween._pt;
487
488      while (pt) {
489        pt.r(ratio, pt.d);
490        pt = pt._next;
491      }
492
493      totalTime < 0 && _rewindStartAt(tween, totalTime, suppressEvents, true);
494      tween._onUpdate && !suppressEvents && _callback(tween, "onUpdate");
495      tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, "onRepeat");
496
497      if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) {
498        ratio && _removeFromParent(tween, 1);
499
500        if (!suppressEvents && !_reverting) {
501          _callback(tween, ratio ? "onComplete" : "onReverseComplete", true);
502
503          tween._prom && tween._prom();
504        }
505      }
506    } else if (!tween._zTime) {
507      tween._zTime = totalTime;
508    }
509  },
510      _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) {
511    var child;
512
513    if (time > prevTime) {
514      child = animation._first;
515
516      while (child && child._start <= time) {
517        if (child.data === "isPause" && child._start > prevTime) {
518          return child;
519        }
520
521        child = child._next;
522      }
523    } else {
524      child = animation._last;
525
526      while (child && child._start >= time) {
527        if (child.data === "isPause" && child._start < prevTime) {
528          return child;
529        }
530
531        child = child._prev;
532      }
533    }
534  },
535      _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) {
536    var repeat = animation._repeat,
537        dur = _roundPrecise(duration) || 0,
538        totalProgress = animation._tTime / animation._tDur;
539    totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur);
540    animation._dur = dur;
541    animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _roundPrecise(dur * (repeat + 1) + animation._rDelay * repeat);
542    totalProgress > 0 && !leavePlayhead && _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress);
543    animation.parent && _setEnd(animation);
544    skipUncache || _uncache(animation.parent, animation);
545    return animation;
546  },
547      _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) {
548    return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur);
549  },
550      _zeroPosition = {
551    _start: 0,
552    endTime: _emptyFunc,
553    totalDuration: _emptyFunc
554  },
555      _parsePosition = function _parsePosition(animation, position, percentAnimation) {
556    var labels = animation.labels,
557        recent = animation._recent || _zeroPosition,
558        clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur,
559        i,
560        offset,
561        isPercent;
562
563    if (_isString(position) && (isNaN(position) || position in labels)) {
564      offset = position.charAt(0);
565      isPercent = position.substr(-1) === "%";
566      i = position.indexOf("=");
567
568      if (offset === "<" || offset === ">") {
569        i >= 0 && (position = position.replace(/=/, ""));
570        return (offset === "<" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0) * (isPercent ? (i < 0 ? recent : percentAnimation).totalDuration() / 100 : 1);
571      }
572
573      if (i < 0) {
574        position in labels || (labels[position] = clippedDuration);
575        return labels[position];
576      }
577
578      offset = parseFloat(position.charAt(i - 1) + position.substr(i + 1));
579
580      if (isPercent && percentAnimation) {
581        offset = offset / 100 * (_isArray(percentAnimation) ? percentAnimation[0] : percentAnimation).totalDuration();
582      }
583
584      return i > 1 ? _parsePosition(animation, position.substr(0, i - 1), percentAnimation) + offset : clippedDuration + offset;
585    }
586
587    return position == null ? clippedDuration : +position;
588  },
589      _createTweenType = function _createTweenType(type, params, timeline) {
590    var isLegacy = _isNumber(params[1]),
591        varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1),
592        vars = params[varsIndex],
593        irVars,
594        parent;
595
596    isLegacy && (vars.duration = params[1]);
597    vars.parent = timeline;
598
599    if (type) {
600      irVars = vars;
601      parent = timeline;
602
603      while (parent && !("immediateRender" in irVars)) {
604        irVars = parent.vars.defaults || {};
605        parent = _isNotFalse(parent.vars.inherit) && parent.parent;
606      }
607
608      vars.immediateRender = _isNotFalse(irVars.immediateRender);
609      type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1];
610    }
611
612    return new Tween(params[0], vars, params[varsIndex + 1]);
613  },
614      _conditionalReturn = function _conditionalReturn(value, func) {
615    return value || value === 0 ? func(value) : func;
616  },
617      _clamp = function _clamp(min, max, value) {
618    return value < min ? min : value > max ? max : value;
619  },
620      getUnit = function getUnit(value, v) {
621    return !_isString(value) || !(v = _unitExp.exec(value)) ? "" : v[1];
622  },
623      clamp = function clamp(min, max, value) {
624    return _conditionalReturn(value, function (v) {
625      return _clamp(min, max, v);
626    });
627  },
628      _slice = [].slice,
629      _isArrayLike = function _isArrayLike(value, nonEmpty) {
630    return value && _isObject(value) && "length" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win;
631  },
632      _flatten = function _flatten(ar, leaveStrings, accumulator) {
633    if (accumulator === void 0) {
634      accumulator = [];
635    }
636
637    return ar.forEach(function (value) {
638      var _accumulator;
639
640      return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value);
641    }) || accumulator;
642  },
643      toArray = function toArray(value, scope, leaveStrings) {
644    return _context && !scope && _context.selector ? _context.selector(value) : _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call((scope || _doc).querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : [];
645  },
646      selector = function selector(value) {
647    value = toArray(value)[0] || _warn("Invalid scope") || {};
648    return function (v) {
649      var el = value.current || value.nativeElement || value;
650      return toArray(v, el.querySelectorAll ? el : el === value ? _warn("Invalid scope") || _doc.createElement("div") : value);
651    };
652  },
653      shuffle = function shuffle(a) {
654    return a.sort(function () {
655      return .5 - Math.random();
656    });
657  },
658      distribute = function distribute(v) {
659    if (_isFunction(v)) {
660      return v;
661    }
662
663    var vars = _isObject(v) ? v : {
664      each: v
665    },
666        ease = _parseEase(vars.ease),
667        from = vars.from || 0,
668        base = parseFloat(vars.base) || 0,
669        cache = {},
670        isDecimal = from > 0 && from < 1,
671        ratios = isNaN(from) || isDecimal,
672        axis = vars.axis,
673        ratioX = from,
674        ratioY = from;
675
676    if (_isString(from)) {
677      ratioX = ratioY = {
678        center: .5,
679        edges: .5,
680        end: 1
681      }[from] || 0;
682    } else if (!isDecimal && ratios) {
683      ratioX = from[0];
684      ratioY = from[1];
685    }
686
687    return function (i, target, a) {
688      var l = (a || vars).length,
689          distances = cache[l],
690          originX,
691          originY,
692          x,
693          y,
694          d,
695          j,
696          max,
697          min,
698          wrapAt;
699
700      if (!distances) {
701        wrapAt = vars.grid === "auto" ? 0 : (vars.grid || [1, _bigNum])[1];
702
703        if (!wrapAt) {
704          max = -_bigNum;
705
706          while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {}
707
708          wrapAt < l && wrapAt--;
709        }
710
711        distances = cache[l] = [];
712        originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt;
713        originY = wrapAt === _bigNum ? 0 : ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0;
714        max = 0;
715        min = _bigNum;
716
717        for (j = 0; j < l; j++) {
718          x = j % wrapAt - originX;
719          y = originY - (j / wrapAt | 0);
720          distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === "y" ? y : x);
721          d > max && (max = d);
722          d < min && (min = d);
723        }
724
725        from === "random" && shuffle(distances);
726        distances.max = max - min;
727        distances.min = min;
728        distances.v = l = (parseFloat(vars.amount) || parseFloat(vars.each) * (wrapAt > l ? l - 1 : !axis ? Math.max(wrapAt, l / wrapAt) : axis === "y" ? l / wrapAt : wrapAt) || 0) * (from === "edges" ? -1 : 1);
729        distances.b = l < 0 ? base - l : base;
730        distances.u = getUnit(vars.amount || vars.each) || 0;
731        ease = ease && l < 0 ? _invertEase(ease) : ease;
732      }
733
734      l = (distances[i] - distances.min) / distances.max || 0;
735      return _roundPrecise(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u;
736    };
737  },
738      _roundModifier = function _roundModifier(v) {
739    var p = Math.pow(10, ((v + "").split(".")[1] || "").length);
740    return function (raw) {
741      var n = _roundPrecise(Math.round(parseFloat(raw) / v) * v * p);
742
743      return (n - n % 1) / p + (_isNumber(raw) ? 0 : getUnit(raw));
744    };
745  },
746      snap = function snap(snapTo, value) {
747    var isArray = _isArray(snapTo),
748        radius,
749        is2D;
750
751    if (!isArray && _isObject(snapTo)) {
752      radius = isArray = snapTo.radius || _bigNum;
753
754      if (snapTo.values) {
755        snapTo = toArray(snapTo.values);
756
757        if (is2D = !_isNumber(snapTo[0])) {
758          radius *= radius;
759        }
760      } else {
761        snapTo = _roundModifier(snapTo.increment);
762      }
763    }
764
765    return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) {
766      is2D = snapTo(raw);
767      return Math.abs(is2D - raw) <= radius ? is2D : raw;
768    } : function (raw) {
769      var x = parseFloat(is2D ? raw.x : raw),
770          y = parseFloat(is2D ? raw.y : 0),
771          min = _bigNum,
772          closest = 0,
773          i = snapTo.length,
774          dx,
775          dy;
776
777      while (i--) {
778        if (is2D) {
779          dx = snapTo[i].x - x;
780          dy = snapTo[i].y - y;
781          dx = dx * dx + dy * dy;
782        } else {
783          dx = Math.abs(snapTo[i] - x);
784        }
785
786        if (dx < min) {
787          min = dx;
788          closest = i;
789        }
790      }
791
792      closest = !radius || min <= radius ? snapTo[closest] : raw;
793      return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw);
794    });
795  },
796      random = function random(min, max, roundingIncrement, returnFunction) {
797    return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () {
798      return _isArray(min) ? min[~~(Math.random() * min.length)] : (roundingIncrement = roundingIncrement || 1e-5) && (returnFunction = roundingIncrement < 1 ? Math.pow(10, (roundingIncrement + "").length - 2) : 1) && Math.floor(Math.round((min - roundingIncrement / 2 + Math.random() * (max - min + roundingIncrement * .99)) / roundingIncrement) * roundingIncrement * returnFunction) / returnFunction;
799    });
800  },
801      pipe = function pipe() {
802    for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) {
803      functions[_key] = arguments[_key];
804    }
805
806    return function (value) {
807      return functions.reduce(function (v, f) {
808        return f(v);
809      }, value);
810    };
811  },
812      unitize = function unitize(func, unit) {
813    return function (value) {
814      return func(parseFloat(value)) + (unit || getUnit(value));
815    };
816  },
817      normalize = function normalize(min, max, value) {
818    return mapRange(min, max, 0, 1, value);
819  },
820      _wrapArray = function _wrapArray(a, wrapper, value) {
821    return _conditionalReturn(value, function (index) {
822      return a[~~wrapper(index)];
823    });
824  },
825      wrap = function wrap(min, max, value) {
826    var range = max - min;
827    return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) {
828      return (range + (value - min) % range) % range + min;
829    });
830  },
831      wrapYoyo = function wrapYoyo(min, max, value) {
832    var range = max - min,
833        total = range * 2;
834    return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) {
835      value = (total + (value - min) % total) % total || 0;
836      return min + (value > range ? total - value : value);
837    });
838  },
839      _replaceRandom = function _replaceRandom(
vendor: 531 bytes, lines 839-855
839value) {
840    var prev = 0,
841        s = "",
842        i,
843        nums,
844        end,
845        isArray;
846
847    while (~(i = value.indexOf("random(", prev))) {
848      end = value.indexOf(")", i);
849      isArray = value.charAt(i + 7) === "[";
850      nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp);
851      s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5);
852      prev = end + 1;
853    }
854
855    return s + value.substr(prev, value.length - prev
vendor: 14,290 bytes, lines 855-1371
855);
856  },
857      mapRange = function mapRange(inMin, inMax, outMin, outMax, value) {
858    var inRange = inMax - inMin,
859        outRange = outMax - outMin;
860    return _conditionalReturn(value, function (value) {
861      return outMin + ((value - inMin) / inRange * outRange || 0);
862    });
863  },
864      interpolate = function interpolate(start, end, progress, mutate) {
865    var func = isNaN(start + end) ? 0 : function (p) {
866      return (1 - p) * start + p * end;
867    };
868
869    if (!func) {
870      var isString = _isString(start),
871          master = {},
872          p,
873          i,
874          interpolators,
875          l,
876          il;
877
878      progress === true && (mutate = 1) && (progress = null);
879
880      if (isString) {
881        start = {
882          p: start
883        };
884        end = {
885          p: end
886        };
887      } else if (_isArray(start) && !_isArray(end)) {
888        interpolators = [];
889        l = start.length;
890        il = l - 2;
891
892        for (i = 1; i < l; i++) {
893          interpolators.push(interpolate(start[i - 1], start[i]));
894        }
895
896        l--;
897
898        func = function func(p) {
899          p *= l;
900          var i = Math.min(il, ~~p);
901          return interpolators[i](p - i);
902        };
903
904        progress = end;
905      } else if (!mutate) {
906        start = _merge(_isArray(start) ? [] : {}, start);
907      }
908
909      if (!interpolators) {
910        for (p in end) {
911          _addPropTween.call(master, start, p, "get", end[p]);
912        }
913
914        func = function func(p) {
915          return _renderPropTweens(p, master) || (isString ? start.p : start);
916        };
917      }
918    }
919
920    return _conditionalReturn(progress, func);
921  },
922      _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) {
923    var labels = timeline.labels,
924        min = _bigNum,
925        p,
926        distance,
927        label;
928
929    for (p in labels) {
930      distance = labels[p] - fromTime;
931
932      if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) {
933        label = p;
934        min = distance;
935      }
936    }
937
938    return label;
939  },
940      _callback = function _callback(animation, type, executeLazyFirst) {
941    var v = animation.vars,
942        callback = v[type],
943        prevContext = _context,
944        context = animation._ctx,
945        params,
946        scope,
947        result;
948
949    if (!callback) {
950      return;
951    }
952
953    params = v[type + "Params"];
954    scope = v.callbackScope || animation;
955    executeLazyFirst && _lazyTweens.length && _lazyRender();
956    context && (_context = context);
957    result = params ? callback.apply(scope, params) : callback.call(scope);
958    _context = prevContext;
959    return result;
960  },
961      _interrupt = function _interrupt(animation) {
962    _removeFromParent(animation);
963
964    animation.scrollTrigger && animation.scrollTrigger.kill(!!_reverting);
965    animation.progress() < 1 && _callback(animation, "onInterrupt");
966    return animation;
967  },
968      _quickTween,
969      _registerPluginQueue = [],
970      _createPlugin = function _createPlugin(config) {
971    if (!config) return;
972    config = !config.name && config["default"] || config;
973
974    if (_windowExists() || config.headless) {
975      var name = config.name,
976          isFunc = _isFunction(config),
977          Plugin = name && !isFunc && config.init ? function () {
978        this._props = [];
979      } : config,
980          instanceDefaults = {
981        init: _emptyFunc,
982        render: _renderPropTweens,
983        add: _addPropTween,
984        kill: _killPropTweensOf,
985        modifier: _addPluginModifier,
986        rawVars: 0
987      },
988          statics = {
989        targetTest: 0,
990        get: 0,
991        getSetter: _getSetter,
992        aliases: {},
993        register: 0
994      };
995
996      _wake();
997
998      if (config !== Plugin) {
999        if (_plugins[name]) {
1000          return;
1001        }
1002
1003        _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics));
1004
1005        _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics)));
1006
1007        _plugins[Plugin.prop = name] = Plugin;
1008
1009        if (config.targetTest) {
1010          _harnessPlugins.push(Plugin);
1011
1012          _reservedProps[name] = 1;
1013        }
1014
1015        name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin";
1016      }
1017
1018      _addGlobal(name, Plugin);
1019
1020      config.register && config.register(gsap, Plugin, PropTween);
1021    } else {
1022      _registerPluginQueue.push(config);
1023    }
1024  },
1025      _255 = 255,
1026      _colorLookup = {
1027    aqua: [0, _255, _255],
1028    lime: [0, _255, 0],
1029    silver: [192, 192, 192],
1030    black: [0, 0, 0],
1031    maroon: [128, 0, 0],
1032    teal: [0, 128, 128],
1033    blue: [0, 0, _255],
1034    navy: [0, 0, 128],
1035    white: [_255, _255, _255],
1036    olive: [128, 128, 0],
1037    yellow: [_255, _255, 0],
1038    orange: [_255, 165, 0],
1039    gray: [128, 128, 128],
1040    purple: [128, 0, 128],
1041    green: [0, 128, 0],
1042    red: [_255, 0, 0],
1043    pink: [_255, 192, 203],
1044    cyan: [0, _255, _255],
1045    transparent: [_255, _255, _255, 0]
1046  },
1047      _hue = function _hue(h, m1, m2) {
1048    h += h < 0 ? 1 : h > 1 ? -1 : 0;
1049    return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < .5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * _255 + .5 | 0;
1050  },
1051      splitColor = function splitColor(v, toHSL, forceAlpha) {
1052    var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0,
1053        r,
1054        g,
1055        b,
1056        h,
1057        s,
1058        l,
1059        max,
1060        min,
1061        d,
1062        wasHSL;
1063
1064    if (!a) {
1065      if (v.substr(-1) === ",") {
1066        v = v.substr(0, v.length - 1);
1067      }
1068
1069      if (_colorLookup[v]) {
1070        a = _colorLookup[v];
1071      } else if (v.charAt(0) === "#") {
1072        if (v.length < 6) {
1073          r = v.charAt(1);
1074          g = v.charAt(2);
1075          b = v.charAt(3);
1076          v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : "");
1077        }
1078
1079        if (v.length === 9) {
1080          a = parseInt(v.substr(1, 6), 16);
1081          return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255];
1082        }
1083
1084        v = parseInt(v.substr(1), 16);
1085        a = [v >> 16, v >> 8 & _255, v & _255];
1086      } else if (v.substr(0, 3) === "hsl") {
1087        a = wasHSL = v.match(_strictNumExp);
1088
1089        if (!toHSL) {
1090          h = +a[0] % 360 / 360;
1091          s = +a[1] / 100;
1092          l = +a[2] / 100;
1093          g = l <= .5 ? l * (s + 1) : l + s - l * s;
1094          r = l * 2 - g;
1095          a.length > 3 && (a[3] *= 1);
1096          a[0] = _hue(h + 1 / 3, r, g);
1097          a[1] = _hue(h, r, g);
1098          a[2] = _hue(h - 1 / 3, r, g);
1099        } else if (~v.indexOf("=")) {
1100          a = v.match(_numExp);
1101          forceAlpha && a.length < 4 && (a[3] = 1);
1102          return a;
1103        }
1104      } else {
1105        a = v.match(_strictNumExp) || _colorLookup.transparent;
1106      }
1107
1108      a = a.map(Number);
1109    }
1110
1111    if (toHSL && !wasHSL) {
1112      r = a[0] / _255;
1113      g = a[1] / _255;
1114      b = a[2] / _255;
1115      max = Math.max(r, g, b);
1116      min = Math.min(r, g, b);
1117      l = (max + min) / 2;
1118
1119      if (max === min) {
1120        h = s = 0;
1121      } else {
1122        d = max - min;
1123        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1124        h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
1125        h *= 60;
1126      }
1127
1128      a[0] = ~~(h + .5);
1129      a[1] = ~~(s * 100 + .5);
1130      a[2] = ~~(l * 100 + .5);
1131    }
1132
1133    forceAlpha && a.length < 4 && (a[3] = 1);
1134    return a;
1135  },
1136      _colorOrderData = function _colorOrderData(v) {
1137    var values = [],
1138        c = [],
1139        i = -1;
1140    v.split(_colorExp).forEach(function (v) {
1141      var a = v.match(_numWithUnitExp) || [];
1142      values.push.apply(values, a);
1143      c.push(i += a.length + 1);
1144    });
1145    values.c = c;
1146    return values;
1147  },
1148      _formatColors = function _formatColors(s, toHSL, orderMatchData) {
1149    var result = "",
1150        colors = (s + result).match(_colorExp),
1151        type = toHSL ? "hsla(" : "rgba(",
1152        i = 0,
1153        c,
1154        shell,
1155        d,
1156        l;
1157
1158    if (!colors) {
1159      return s;
1160    }
1161
1162    colors = colors.map(function (color) {
1163      return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")";
1164    });
1165
1166    if (orderMatchData) {
1167      d = _colorOrderData(s);
1168      c = orderMatchData.c;
1169
1170      if (c.join(result) !== d.c.join(result)) {
1171        shell = s.replace(_colorExp, "1").split(_numWithUnitExp);
1172        l = shell.length - 1;
1173
1174        for (; i < l; i++) {
1175          result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift());
1176        }
1177      }
1178    }
1179
1180    if (!shell) {
1181      shell = s.split(_colorExp);
1182      l = shell.length - 1;
1183
1184      for (; i < l; i++) {
1185        result += shell[i] + colors[i];
1186      }
1187    }
1188
1189    return result + shell[l];
1190  },
1191      _colorExp = function () {
1192    var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b",
1193        p;
1194
1195    for (p in _colorLookup) {
1196      s += "|" + p + "\\b";
1197    }
1198
1199    return new RegExp(s + ")", "gi");
1200  }(),
1201      _hslExp = /hsl[a]?\(/,
1202      _colorStringFilter = function _colorStringFilter(a) {
1203    var combined = a.join(" "),
1204        toHSL;
1205    _colorExp.lastIndex = 0;
1206
1207    if (_colorExp.test(combined)) {
1208      toHSL = _hslExp.test(combined);
1209      a[1] = _formatColors(a[1], toHSL);
1210      a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1]));
1211      return true;
1212    }
1213  },
1214      _tickerActive,
1215      _ticker = function () {
1216    var _getTime = Date.now,
1217        _lagThreshold = 500,
1218        _adjustedLag = 33,
1219        _startTime = _getTime(),
1220        _lastUpdate = _startTime,
1221        _gap = 1000 / 240,
1222        _nextTime = _gap,
1223        _listeners = [],
1224        _id,
1225        _req,
1226        _raf,
1227        _self,
1228        _delta,
1229        _i,
1230        _tick = function _tick(v) {
1231      var elapsed = _getTime() - _lastUpdate,
1232          manual = v === true,
1233          overlap,
1234          dispatch,
1235          time,
1236          frame;
1237
1238      (elapsed > _lagThreshold || elapsed < 0) && (_startTime += elapsed - _adjustedLag);
1239      _lastUpdate += elapsed;
1240      time = _lastUpdate - _startTime;
1241      overlap = time - _nextTime;
1242
1243      if (overlap > 0 || manual) {
1244        frame = ++_self.frame;
1245        _delta = time - _self.time * 1000;
1246        _self.time = time = time / 1000;
1247        _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap);
1248        dispatch = 1;
1249      }
1250
1251      manual || (_id = _req(_tick));
1252
1253      if (dispatch) {
1254        for (_i = 0; _i < _listeners.length; _i++) {
1255          _listeners[_i](time, _delta, frame, v);
1256        }
1257      }
1258    };
1259
1260    _self = {
1261      time: 0,
1262      frame: 0,
1263      tick: function tick() {
1264        _tick(true);
1265      },
1266      deltaRatio: function deltaRatio(fps) {
1267        return _delta / (1000 / (fps || 60));
1268      },
1269      wake: function wake() {
1270        if (_coreReady) {
1271          if (!_coreInitted && _windowExists()) {
1272            _win = _coreInitted = window;
1273            _doc = _win.document || {};
1274            _globals.gsap = gsap;
1275            (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version);
1276
1277            _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {});
1278
1279            _registerPluginQueue.forEach(_createPlugin);
1280          }
1281
1282          _raf = typeof requestAnimationFrame !== "undefined" && requestAnimationFrame;
1283          _id && _self.sleep();
1284
1285          _req = _raf || function (f) {
1286            return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0);
1287          };
1288
1289          _tickerActive = 1;
1290
1291          _tick(2);
1292        }
1293      },
1294      sleep: function sleep() {
1295        (_raf ? cancelAnimationFrame : clearTimeout)(_id);
1296        _tickerActive = 0;
1297        _req = _emptyFunc;
1298      },
1299      lagSmoothing: function lagSmoothing(threshold, adjustedLag) {
1300        _lagThreshold = threshold || Infinity;
1301        _adjustedLag = Math.min(adjustedLag || 33, _lagThreshold);
1302      },
1303      fps: function fps(_fps) {
1304        _gap = 1000 / (_fps || 240);
1305        _nextTime = _self.time * 1000 + _gap;
1306      },
1307      add: function add(callback, once, prioritize) {
1308        var func = once ? function (t, d, f, v) {
1309          callback(t, d, f, v);
1310
1311          _self.remove(func);
1312        } : callback;
1313
1314        _self.remove(callback);
1315
1316        _listeners[prioritize ? "unshift" : "push"](func);
1317
1318        _wake();
1319
1320        return func;
1321      },
1322      remove: function remove(callback, i) {
1323        ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--;
1324      },
1325      _listeners: _listeners
1326    };
1327    return _self;
1328  }(),
1329      _wake = function _wake() {
1330    return !_tickerActive && _ticker.wake();
1331  },
1332      _easeMap = {},
1333      _customEaseExp = /^[\d.\-M][\d.\-,\s]/,
1334      _quotesExp = /["']/g,
1335      _parseObjectInString = function _parseObjectInString(value) {
1336    var obj = {},
1337        split = value.substr(1, value.length - 3).split(":"),
1338        key = split[0],
1339        i = 1,
1340        l = split.length,
1341        index,
1342        val,
1343        parsedVal;
1344
1345    for (; i < l; i++) {
1346      val = split[i];
1347      index = i !== l - 1 ? val.lastIndexOf(",") : val.length;
1348      parsedVal = val.substr(0, index);
1349      obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal;
1350      key = val.substr(index + 1).trim();
1351    }
1352
1353    return obj;
1354  },
1355      _valueInParentheses = function _valueInParentheses(value) {
1356    var open = value.indexOf("(") + 1,
1357        close = value.indexOf(")"),
1358        nested = value.indexOf("(", open);
1359    return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close);
1360  },
1361      _configEaseFromString = function _configEaseFromString(name) {
1362    var split = (name + "").split("("),
1363        ease = _easeMap[split[0]];
1364    return ease && split.length > 1 && ease.config ? ease.config.apply(null, ~name.indexOf("{") ? [_parseObjectInString(split[1])] : _valueInParentheses(name).split(",").map(_numericIfPossible)) : _easeMap._CE && _customEaseExp.test(name) ? _easeMap._CE("", name) : ease;
1365  },
1366      _invertEase = function _invertEase(ease) {
1367    return function (p) {
1368      return 1 - ease(1 - p);
1369    };
1370  },
1371      _p
1371ropagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) {
1372    var child = timeline._first,
1373        ease;
1374
1375    while (child) {
1376      if (child instanceof Timeline) {
1377        _propagateYoyoEase(child, isYoyo);
1378      } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) {
1379        if (child.timeline) {
1380          _propagateYoyoEase(child.timeline, isYoyo);
1381        } else {
1382          ease = child._ease;
1383          child._ease = child._yEase;
1384          child._yEase = ease;
1385          child._yoyo = isYoyo;
1386        }
1387      }
1388
1389      child = child._next;
1390    }
vendor: 3,445 bytes, lines 1390-1501
1390
1391  },
1392      _parseEase = function _parseEase(ease, defaultEase) {
1393    return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase;
1394  },
1395      _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) {
1396    if (easeOut === void 0) {
1397      easeOut = function easeOut(p) {
1398        return 1 - easeIn(1 - p);
1399      };
1400    }
1401
1402    if (easeInOut === void 0) {
1403      easeInOut = function easeInOut(p) {
1404        return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2;
1405      };
1406    }
1407
1408    var ease = {
1409      easeIn: easeIn,
1410      easeOut: easeOut,
1411      easeInOut: easeInOut
1412    },
1413        lowercaseName;
1414
1415    _forEachName(names, function (name) {
1416      _easeMap[name] = _globals[name] = ease;
1417      _easeMap[lowercaseName = name.toLowerCase()] = easeOut;
1418
1419      for (var p in ease) {
1420        _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p];
1421      }
1422    });
1423
1424    return ease;
1425  },
1426      _easeInOutFromOut = function _easeInOutFromOut(easeOut) {
1427    return function (p) {
1428      return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2;
1429    };
1430  },
1431      _configElastic = function _configElastic(type, amplitude, period) {
1432    var p1 = amplitude >= 1 ? amplitude : 1,
1433        p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1),
1434        p3 = p2 / _2PI * (Math.asin(1 / p1) || 0),
1435        easeOut = function easeOut(p) {
1436      return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1;
1437    },
1438        ease = type === "out" ? easeOut : type === "in" ? function (p) {
1439      return 1 - easeOut(1 - p);
1440    } : _easeInOutFromOut(easeOut);
1441
1442    p2 = _2PI / p2;
1443
1444    ease.config = function (amplitude, period) {
1445      return _configElastic(type, amplitude, period);
1446    };
1447
1448    return ease;
1449  },
1450      _configBack = function _configBack(type, overshoot) {
1451    if (overshoot === void 0) {
1452      overshoot = 1.70158;
1453    }
1454
1455    var easeOut = function easeOut(p) {
1456      return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0;
1457    },
1458        ease = type === "out" ? easeOut : type === "in" ? function (p) {
1459      return 1 - easeOut(1 - p);
1460    } : _easeInOutFromOut(easeOut);
1461
1462    ease.config = function (overshoot) {
1463      return _configBack(type, overshoot);
1464    };
1465
1466    return ease;
1467  };
1468
1469  _forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) {
1470    var power = i < 5 ? i + 1 : i;
1471
1472    _insertEase(name + ",Power" + (power - 1), i ? function (p) {
1473      return Math.pow(p, power);
1474    } : function (p) {
1475      return p;
1476    }, function (p) {
1477      return 1 - Math.pow(1 - p, power);
1478    }, function (p) {
1479      return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2;
1480    });
1481  });
1482
1483  _easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn;
1484
1485  _insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic());
1486
1487  (function (n, c) {
1488    var n1 = 1 / c,
1489        n2 = 2 * n1,
1490        n3 = 2.5 * n1,
1491        easeOut = function easeOut(p) {
1492      return p < n1 ? n * p * p : p < n2 ? n * Math.pow(p - 1.5 / c, 2) + .75 : p < n3 ? n * (p -= 2.25 / c) * p + .9375 : n * Math.pow(p - 2.625 / c, 2) + .984375;
1493    };
1494
1495    _insertEase("Bounce", function (p) {
1496      return 1 - easeOut(1 - p);
1497    }, easeOut);
1498  })(7.5625, 2.75);
1499
1500  _insertEase("Expo", function (p) {
1501    return 
vendor: 18,509 bytes, lines 1501-2076
1501p ? Math.pow(2, 10 * (p - 1)) : 0;
1502  });
1503
1504  _insertEase("Circ", function (p) {
1505    return -(_sqrt(1 - p * p) - 1);
1506  });
1507
1508  _insertEase("Sine", function (p) {
1509    return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1;
1510  });
1511
1512  _insertEase("Back", _configBack("in"), _configBack("out"), _configBack());
1513
1514  _easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = {
1515    config: function config(steps, immediateStart) {
1516      if (steps === void 0) {
1517        steps = 1;
1518      }
1519
1520      var p1 = 1 / steps,
1521          p2 = steps + (immediateStart ? 0 : 1),
1522          p3 = immediateStart ? 1 : 0,
1523          max = 1 - _tinyNum;
1524      return function (p) {
1525        return ((p2 * _clamp(0, max, p) | 0) + p3) * p1;
1526      };
1527    }
1528  };
1529  _defaults.ease = _easeMap["quad.out"];
1530
1531  _forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) {
1532    return _callbackNames += name + "," + name + "Params,";
1533  });
1534
1535  var GSCache = function GSCache(target, harness) {
1536    this.id = _gsID++;
1537    target._gsap = this;
1538    this.target = target;
1539    this.harness = harness;
1540    this.get = harness ? harness.get : _getProperty;
1541    this.set = harness ? harness.getSetter : _getSetter;
1542  };
1543  var Animation = function () {
1544    function Animation(vars) {
1545      this.vars = vars;
1546      this._delay = +vars.delay || 0;
1547
1548      if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) {
1549        this._rDelay = vars.repeatDelay || 0;
1550        this._yoyo = !!vars.yoyo || !!vars.yoyoEase;
1551      }
1552
1553      this._ts = 1;
1554
1555      _setDuration(this, +vars.duration, 1, 1);
1556
1557      this.data = vars.data;
1558
1559      if (_context) {
1560        this._ctx = _context;
1561
1562        _context.data.push(this);
1563      }
1564
1565      _tickerActive || _ticker.wake();
1566    }
1567
1568    var _proto = Animation.prototype;
1569
1570    _proto.delay = function delay(value) {
1571      if (value || value === 0) {
1572        this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay);
1573        this._delay = value;
1574        return this;
1575      }
1576
1577      return this._delay;
1578    };
1579
1580    _proto.duration = function duration(value) {
1581      return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur;
1582    };
1583
1584    _proto.totalDuration = function totalDuration(value) {
1585      if (!arguments.length) {
1586        return this._tDur;
1587      }
1588
1589      this._dirty = 0;
1590      return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1));
1591    };
1592
1593    _proto.totalTime = function totalTime(_totalTime, suppressEvents) {
1594      _wake();
1595
1596      if (!arguments.length) {
1597        return this._tTime;
1598      }
1599
1600      var parent = this._dp;
1601
1602      if (parent && parent.smoothChildTiming && this._ts) {
1603        _alignPlayhead(this, _totalTime);
1604
1605        !parent._dp || parent.parent || _postAddChecks(parent, this);
1606
1607        while (parent && parent.parent) {
1608          if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) {
1609            parent.totalTime(parent._tTime, true);
1610          }
1611
1612          parent = parent.parent;
1613        }
1614
1615        if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) {
1616          _addToTimeline(this._dp, this, this._start - this._delay);
1617        }
1618      }
1619
1620      if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) {
1621        this._ts || (this._pTime = _totalTime);
1622
1623        _lazySafeRender(this, _totalTime, suppressEvents);
1624      }
1625
1626      return this;
1627    };
1628
1629    _proto.time = function time(value, suppressEvents) {
1630      return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % (this._dur + this._rDelay) || (value ? this._dur : 0), suppressEvents) : this._time;
1631    };
1632
1633    _proto.totalProgress = function totalProgress(value, suppressEvents) {
1634      return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.rawTime() > 0 ? 1 : 0;
1635    };
1636
1637    _proto.progress = function progress(value, suppressEvents) {
1638      return arguments.length ? this.totalTime(this.duration() * (this._yoyo && !(this.iteration() & 1) ? 1 - value : value) + _elapsedCycleDuration(this), suppressEvents) : this.duration() ? Math.min(1, this._time / this._dur) : this.rawTime() > 0 ? 1 : 0;
1639    };
1640
1641    _proto.iteration = function iteration(value, suppressEvents) {
1642      var cycleDuration = this.duration() + this._rDelay;
1643
1644      return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1;
1645    };
1646
1647    _proto.timeScale = function timeScale(value, suppressEvents) {
1648      if (!arguments.length) {
1649        return this._rts === -_tinyNum ? 0 : this._rts;
1650      }
1651
1652      if (this._rts === value) {
1653        return this;
1654      }
1655
1656      var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime;
1657      this._rts = +value || 0;
1658      this._ts = this._ps || value === -_tinyNum ? 0 : this._rts;
1659      this.totalTime(_clamp(-Math.abs(this._delay), this._tDur, tTime), suppressEvents !== false);
1660
1661      _setEnd(this);
1662
1663      return _recacheAncestors(this);
1664    };
1665
1666    _proto.paused = function paused(value) {
1667      if (!arguments.length) {
1668        return this._ps;
1669      }
1670
1671      if (this._ps !== value) {
1672        this._ps = value;
1673
1674        if (value) {
1675          this._pTime = this._tTime || Math.max(-this._delay, this.rawTime());
1676          this._ts = this._act = 0;
1677        } else {
1678          _wake();
1679
1680          this._ts = this._rts;
1681          this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && Math.abs(this._zTime) !== _tinyNum && (this._tTime -= _tinyNum));
1682        }
1683      }
1684
1685      return this;
1686    };
1687
1688    _proto.startTime = function startTime(value) {
1689      if (arguments.length) {
1690        this._start = value;
1691        var parent = this.parent || this._dp;
1692        parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay);
1693        return this;
1694      }
1695
1696      return this._start;
1697    };
1698
1699    _proto.endTime = function endTime(includeRepeats) {
1700      return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1);
1701    };
1702
1703    _proto.rawTime = function rawTime(wrapRepeats) {
1704      var parent = this.parent || this._dp;
1705      return !parent ? this._tTime : wrapRepeats && (!this._ts || this._repeat && this._time && this.totalProgress() < 1) ? this._tTime % (this._dur + this._rDelay) : !this._ts ? this._tTime : _parentToChildTotalTime(parent.rawTime(wrapRepeats), this);
1706    };
1707
1708    _proto.revert = function revert(config) {
1709      if (config === void 0) {
1710        config = _revertConfig;
1711      }
1712
1713      var prevIsReverting = _reverting;
1714      _reverting = config;
1715
1716      if (this._initted || this._startAt) {
1717        this.timeline && this.timeline.revert(config);
1718        this.totalTime(-0.01, config.suppressEvents);
1719      }
1720
1721      this.data !== "nested" && config.kill !== false && this.kill();
1722      _reverting = prevIsReverting;
1723      return this;
1724    };
1725
1726    _proto.globalTime = function globalTime(rawTime) {
1727      var animation = this,
1728          time = arguments.length ? rawTime : animation.rawTime();
1729
1730      while (animation) {
1731        time = animation._start + time / (Math.abs(animation._ts) || 1);
1732        animation = animation._dp;
1733      }
1734
1735      return !this.parent && this._sat ? this._sat.globalTime(rawTime) : time;
1736    };
1737
1738    _proto.repeat = function repeat(value) {
1739      if (arguments.length) {
1740        this._repeat = value === Infinity ? -2 : value;
1741        return _onUpdateTotalDuration(this);
1742      }
1743
1744      return this._repeat === -2 ? Infinity : this._repeat;
1745    };
1746
1747    _proto.repeatDelay = function repeatDelay(value) {
1748      if (arguments.length) {
1749        var time = this._time;
1750        this._rDelay = value;
1751
1752        _onUpdateTotalDuration(this);
1753
1754        return time ? this.time(time) : this;
1755      }
1756
1757      return this._rDelay;
1758    };
1759
1760    _proto.yoyo = function yoyo(value) {
1761      if (arguments.length) {
1762        this._yoyo = value;
1763        return this;
1764      }
1765
1766      return this._yoyo;
1767    };
1768
1769    _proto.seek = function seek(position, suppressEvents) {
1770      return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents));
1771    };
1772
1773    _proto.restart = function restart(includeDelay, suppressEvents) {
1774      return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents));
1775    };
1776
1777    _proto.play = function play(from, suppressEvents) {
1778      from != null && this.seek(from, suppressEvents);
1779      return this.reversed(false).paused(false);
1780    };
1781
1782    _proto.reverse = function reverse(from, suppressEvents) {
1783      from != null && this.seek(from || this.totalDuration(), suppressEvents);
1784      return this.reversed(true).paused(false);
1785    };
1786
1787    _proto.pause = function pause(atTime, suppressEvents) {
1788      atTime != null && this.seek(atTime, suppressEvents);
1789      return this.paused(true);
1790    };
1791
1792    _proto.resume = function resume() {
1793      return this.paused(false);
1794    };
1795
1796    _proto.reversed = function reversed(value) {
1797      if (arguments.length) {
1798        !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0));
1799        return this;
1800      }
1801
1802      return this._rts < 0;
1803    };
1804
1805    _proto.invalidate = function invalidate() {
1806      this._initted = this._act = 0;
1807      this._zTime = -_tinyNum;
1808      return this;
1809    };
1810
1811    _proto.isActive = function isActive() {
1812      var parent = this.parent || this._dp,
1813          start = this._start,
1814          rawTime;
1815      return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum);
1816    };
1817
1818    _proto.eventCallback = function eventCallback(type, callback, params) {
1819      var vars = this.vars;
1820
1821      if (arguments.length > 1) {
1822        if (!callback) {
1823          delete vars[type];
1824        } else {
1825          vars[type] = callback;
1826          params && (vars[type + "Params"] = params);
1827          type === "onUpdate" && (this._onUpdate = callback);
1828        }
1829
1830        return this;
1831      }
1832
1833      return vars[type];
1834    };
1835
1836    _proto.then = function then(onFulfilled) {
1837      var self = this;
1838      return new Promise(function (resolve) {
1839        var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough,
1840            _resolve = function _resolve() {
1841          var _then = self.then;
1842          self.then = null;
1843          _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then);
1844          resolve(f);
1845          self.then = _then;
1846        };
1847
1848        if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) {
1849          _resolve();
1850        } else {
1851          self._prom = _resolve;
1852        }
1853      });
1854    };
1855
1856    _proto.kill = function kill() {
1857      _interrupt(this);
1858    };
1859
1860    return Animation;
1861  }();
1862
1863  _setDefaults(Animation.prototype, {
1864    _time: 0,
1865    _start: 0,
1866    _end: 0,
1867    _tTime: 0,
1868    _tDur: 0,
1869    _dirty: 0,
1870    _repeat: 0,
1871    _yoyo: false,
1872    parent: null,
1873    _initted: false,
1874    _rDelay: 0,
1875    _ts: 1,
1876    _dp: 0,
1877    ratio: 0,
1878    _zTime: -_tinyNum,
1879    _prom: 0,
1880    _ps: false,
1881    _rts: 1
1882  });
1883
1884  var Timeline = function (_Animation) {
1885    _inheritsLoose(Timeline, _Animation);
1886
1887    function Timeline(vars, position) {
1888      var _this;
1889
1890      if (vars === void 0) {
1891        vars = {};
1892      }
1893
1894      _this = _Animation.call(this, vars) || this;
1895      _this.labels = {};
1896      _this.smoothChildTiming = !!vars.smoothChildTiming;
1897      _this.autoRemoveChildren = !!vars.autoRemoveChildren;
1898      _this._sort = _isNotFalse(vars.sortChildren);
1899      _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position);
1900      vars.reversed && _this.reverse();
1901      vars.paused && _this.paused(true);
1902      vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger);
1903      return _this;
1904    }
1905
1906    var _proto2 = Timeline.prototype;
1907
1908    _proto2.to = function to(targets, vars, position) {
1909      _createTweenType(0, arguments, this);
1910
1911      return this;
1912    };
1913
1914    _proto2.from = function from(targets, vars, position) {
1915      _createTweenType(1, arguments, this);
1916
1917      return this;
1918    };
1919
1920    _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) {
1921      _createTweenType(2, arguments, this);
1922
1923      return this;
1924    };
1925
1926    _proto2.set = function set(targets, vars, position) {
1927      vars.duration = 0;
1928      vars.parent = this;
1929      _inheritDefaults(vars).repeatDelay || (vars.repeat = 0);
1930      vars.immediateRender = !!vars.immediateRender;
1931      new Tween(targets, vars, _parsePosition(this, position), 1);
1932      return this;
1933    };
1934
1935    _proto2.call = function call(callback, params, position) {
1936      return _addToTimeline(this, Tween.delayedCall(0, callback, params), position);
1937    };
1938
1939    _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {
1940      vars.duration = duration;
1941      vars.stagger = vars.stagger || stagger;
1942      vars.onComplete = onCompleteAll;
1943      vars.onCompleteParams = onCompleteAllParams;
1944      vars.parent = this;
1945      new Tween(targets, vars, _parsePosition(this, position));
1946      return this;
1947    };
1948
1949    _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {
1950      vars.runBackwards = 1;
1951      _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender);
1952      return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams);
1953    };
1954
1955    _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) {
1956      toVars.startAt = fromVars;
1957      _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender);
1958      return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams);
1959    };
1960
1961    _proto2.render = function render(totalTime, suppressEvents, force) {
1962      var prevTime = this._time,
1963          tDur = this._dirty ? this.totalDuration() : this._tDur,
1964          dur = this._dur,
1965          tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime),
1966          crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur),
1967          time,
1968          child,
1969          next,
1970          iteration,
1971          cycleDuration,
1972          prevPaused,
1973          pauseTween,
1974          timeScale,
1975          prevStart,
1976          prevIteration,
1977          yoyo,
1978          isYoyo;
1979      this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur);
1980
1981      if (tTime !== this._tTime || force || crossingStart) {
1982        if (prevTime !== this._time && dur) {
1983          tTime += this._time - prevTime;
1984          totalTime += this._time - prevTime;
1985        }
1986
1987        time = tTime;
1988        prevStart = this._start;
1989        timeScale = this._ts;
1990        prevPaused = !timeScale;
1991
1992        if (crossingStart) {
1993          dur || (prevTime = this._zTime);
1994          (totalTime || !suppressEvents) && (this._zTime = totalTime);
1995        }
1996
1997        if (this._repeat) {
1998          yoyo = this._yoyo;
1999          cycleDuration = dur + this._rDelay;
2000
2001          if (this._repeat < -1 && totalTime < 0) {
2002            return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);
2003          }
2004
2005          time = _roundPrecise(tTime % cycleDuration);
2006
2007          if (tTime === tDur) {
2008            iteration = this._repeat;
2009            time = dur;
2010          } else {
2011            iteration = ~~(tTime / cycleDuration);
2012
2013            if (iteration && iteration === tTime / cycleDuration) {
2014              time = dur;
2015              iteration--;
2016            }
2017
2018            time > dur && (time = dur);
2019          }
2020
2021          prevIteration = _animationCycle(this._tTime, cycleDuration);
2022          !prevTime && this._tTime && prevIteration !== iteration && this._tTime - prevIteration * cycleDuration - this._dur <= 0 && (prevIteration = iteration);
2023
2024          if (yoyo && iteration & 1) {
2025            time = dur - time;
2026            isYoyo = 1;
2027          }
2028
2029          if (iteration !== prevIteration && !this._lock) {
2030            var rewinding = yoyo && prevIteration & 1,
2031                doesWrap = rewinding === (yoyo && iteration & 1);
2032            iteration < prevIteration && (rewinding = !rewinding);
2033            prevTime = rewinding ? 0 : tTime % dur ? dur : tTime;
2034            this._lock = 1;
2035            this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0;
2036            this._tTime = tTime;
2037            !suppressEvents && this.parent && _callback(this, "onRepeat");
2038            this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1);
2039
2040            if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) {
2041              return this;
2042            }
2043
2044            dur = this._dur;
2045            tDur = this._tDur;
2046
2047            if (doesWrap) {
2048              this._lock = 2;
2049              prevTime = rewinding ? dur : -0.0001;
2050              this.render(prevTime, true);
2051              this.vars.repeatRefresh && !isYoyo && this.invalidate();
2052            }
2053
2054            this._lock = 0;
2055
2056            if (!this._ts && !prevPaused) {
2057              return this;
2058            }
2059
2060            _propagateYoyoEase(this, isYoyo);
2061          }
2062        }
2063
2064        if (this._hasPause && !this._forcing && this._lock < 2) {
2065          pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time));
2066
2067          if (pauseTween) {
2068            tTime -= time - (time = pauseTween._start);
2069          }
2070        }
2071
2072        this._tTime = tTime;
2073        this._time = time;
2074        this._act = !timeScale;
2075
2076        if (!this._initted) {
vendor: 30,026 bytes, lines 2077-3039
2077          this._onUpdate = this.vars.onUpdate;
2078          this._initted = 1;
2079          this._zTime = totalTime;
2080          prevTime = 0;
2081        }
2082
2083        if (!prevTime && time && !suppressEvents && !iteration) {
2084          _callback(this, "onStart");
2085
2086          if (this._tTime !== tTime) {
2087            return this;
2088          }
2089        }
2090
2091        if (time >= prevTime && totalTime >= 0) {
2092          child = this._first;
2093
2094          while (child) {
2095            next = child._next;
2096
2097            if ((child._act || time >= child._start) && child._ts && pauseTween !== child) {
2098              if (child.parent !== this) {
2099                return this.render(totalTime, suppressEvents, force);
2100              }
2101
2102              child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force);
2103
2104              if (time !== this._time || !this._ts && !prevPaused) {
2105                pauseTween = 0;
2106                next && (tTime += this._zTime = -_tinyNum);
2107                break;
2108              }
2109            }
2110
2111            child = next;
2112          }
2113        } else {
2114          child = this._last;
2115          var adjustedTime = totalTime < 0 ? totalTime : time;
2116
2117          while (child) {
2118            next = child._prev;
2119
2120            if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) {
2121              if (child.parent !== this) {
2122                return this.render(totalTime, suppressEvents, force);
2123              }
2124
2125              child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force || _reverting && (child._initted || child._startAt));
2126
2127              if (time !== this._time || !this._ts && !prevPaused) {
2128                pauseTween = 0;
2129                next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum);
2130                break;
2131              }
2132            }
2133
2134            child = next;
2135          }
2136        }
2137
2138        if (pauseTween && !suppressEvents) {
2139          this.pause();
2140          pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1;
2141
2142          if (this._ts) {
2143            this._start = prevStart;
2144
2145            _setEnd(this);
2146
2147            return this.render(totalTime, suppressEvents, force);
2148          }
2149        }
2150
2151        this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true);
2152        if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) {
2153          (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1);
2154
2155          if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) {
2156            _callback(this, tTime === tDur && totalTime >= 0 ? "onComplete" : "onReverseComplete", true);
2157
2158            this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();
2159          }
2160        }
2161      }
2162
2163      return this;
2164    };
2165
2166    _proto2.add = function add(child, position) {
2167      var _this2 = this;
2168
2169      _isNumber(position) || (position = _parsePosition(this, position, child));
2170
2171      if (!(child instanceof Animation)) {
2172        if (_isArray(child)) {
2173          child.forEach(function (obj) {
2174            return _this2.add(obj, position);
2175          });
2176          return this;
2177        }
2178
2179        if (_isString(child)) {
2180          return this.addLabel(child, position);
2181        }
2182
2183        if (_isFunction(child)) {
2184          child = Tween.delayedCall(0, child);
2185        } else {
2186          return this;
2187        }
2188      }
2189
2190      return this !== child ? _addToTimeline(this, child, position) : this;
2191    };
2192
2193    _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) {
2194      if (nested === void 0) {
2195        nested = true;
2196      }
2197
2198      if (tweens === void 0) {
2199        tweens = true;
2200      }
2201
2202      if (timelines === void 0) {
2203        timelines = true;
2204      }
2205
2206      if (ignoreBeforeTime === void 0) {
2207        ignoreBeforeTime = -_bigNum;
2208      }
2209
2210      var a = [],
2211          child = this._first;
2212
2213      while (child) {
2214        if (child._start >= ignoreBeforeTime) {
2215          if (child instanceof Tween) {
2216            tweens && a.push(child);
2217          } else {
2218            timelines && a.push(child);
2219            nested && a.push.apply(a, child.getChildren(true, tweens, timelines));
2220          }
2221        }
2222
2223        child = child._next;
2224      }
2225
2226      return a;
2227    };
2228
2229    _proto2.getById = function getById(id) {
2230      var animations = this.getChildren(1, 1, 1),
2231          i = animations.length;
2232
2233      while (i--) {
2234        if (animations[i].vars.id === id) {
2235          return animations[i];
2236        }
2237      }
2238    };
2239
2240    _proto2.remove = function remove(child) {
2241      if (_isString(child)) {
2242        return this.removeLabel(child);
2243      }
2244
2245      if (_isFunction(child)) {
2246        return this.killTweensOf(child);
2247      }
2248
2249      _removeLinkedListItem(this, child);
2250
2251      if (child === this._recent) {
2252        this._recent = this._last;
2253      }
2254
2255      return _uncache(this);
2256    };
2257
2258    _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) {
2259      if (!arguments.length) {
2260        return this._tTime;
2261      }
2262
2263      this._forcing = 1;
2264
2265      if (!this._dp && this._ts) {
2266        this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts));
2267      }
2268
2269      _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents);
2270
2271      this._forcing = 0;
2272      return this;
2273    };
2274
2275    _proto2.addLabel = function addLabel(label, position) {
2276      this.labels[label] = _parsePosition(this, position);
2277      return this;
2278    };
2279
2280    _proto2.removeLabel = function removeLabel(label) {
2281      delete this.labels[label];
2282      return this;
2283    };
2284
2285    _proto2.addPause = function addPause(position, callback, params) {
2286      var t = Tween.delayedCall(0, callback || _emptyFunc, params);
2287      t.data = "isPause";
2288      this._hasPause = 1;
2289      return _addToTimeline(this, t, _parsePosition(this, position));
2290    };
2291
2292    _proto2.removePause = function removePause(position) {
2293      var child = this._first;
2294      position = _parsePosition(this, position);
2295
2296      while (child) {
2297        if (child._start === position && child.data === "isPause") {
2298          _removeFromParent(child);
2299        }
2300
2301        child = child._next;
2302      }
2303    };
2304
2305    _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) {
2306      var tweens = this.getTweensOf(targets, onlyActive),
2307          i = tweens.length;
2308
2309      while (i--) {
2310        _overwritingTween !== tweens[i] && tweens[i].kill(targets, props);
2311      }
2312
2313      return this;
2314    };
2315
2316    _proto2.getTweensOf = function getTweensOf(targets, onlyActive) {
2317      var a = [],
2318          parsedTargets = toArray(targets),
2319          child = this._first,
2320          isGlobalTime = _isNumber(onlyActive),
2321          children;
2322
2323      while (child) {
2324        if (child instanceof Tween) {
2325          if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) {
2326            a.push(child);
2327          }
2328        } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) {
2329          a.push.apply(a, children);
2330        }
2331
2332        child = child._next;
2333      }
2334
2335      return a;
2336    };
2337
2338    _proto2.tweenTo = function tweenTo(position, vars) {
2339      vars = vars || {};
2340
2341      var tl = this,
2342          endTime = _parsePosition(tl, position),
2343          _vars = vars,
2344          startAt = _vars.startAt,
2345          _onStart = _vars.onStart,
2346          onStartParams = _vars.onStartParams,
2347          immediateRender = _vars.immediateRender,
2348          initted,
2349          tween = Tween.to(tl, _setDefaults({
2350        ease: vars.ease || "none",
2351        lazy: false,
2352        immediateRender: false,
2353        time: endTime,
2354        overwrite: "auto",
2355        duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum,
2356        onStart: function onStart() {
2357          tl.pause();
2358
2359          if (!initted) {
2360            var duration = vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale());
2361            tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true);
2362            initted = 1;
2363          }
2364
2365          _onStart && _onStart.apply(tween, onStartParams || []);
2366        }
2367      }, vars));
2368
2369      return immediateRender ? tween.render(0) : tween;
2370    };
2371
2372    _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) {
2373      return this.tweenTo(toPosition, _setDefaults({
2374        startAt: {
2375          time: _parsePosition(this, fromPosition)
2376        }
2377      }, vars));
2378    };
2379
2380    _proto2.recent = function recent() {
2381      return this._recent;
2382    };
2383
2384    _proto2.nextLabel = function nextLabel(afterTime) {
2385      if (afterTime === void 0) {
2386        afterTime = this._time;
2387      }
2388
2389      return _getLabelInDirection(this, _parsePosition(this, afterTime));
2390    };
2391
2392    _proto2.previousLabel = function previousLabel(beforeTime) {
2393      if (beforeTime === void 0) {
2394        beforeTime = this._time;
2395      }
2396
2397      return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1);
2398    };
2399
2400    _proto2.currentLabel = function currentLabel(value) {
2401      return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum);
2402    };
2403
2404    _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) {
2405      if (ignoreBeforeTime === void 0) {
2406        ignoreBeforeTime = 0;
2407      }
2408
2409      var child = this._first,
2410          labels = this.labels,
2411          p;
2412
2413      while (child) {
2414        if (child._start >= ignoreBeforeTime) {
2415          child._start += amount;
2416          child._end += amount;
2417        }
2418
2419        child = child._next;
2420      }
2421
2422      if (adjustLabels) {
2423        for (p in labels) {
2424          if (labels[p] >= ignoreBeforeTime) {
2425            labels[p] += amount;
2426          }
2427        }
2428      }
2429
2430      return _uncache(this);
2431    };
2432
2433    _proto2.invalidate = function invalidate(soft) {
2434      var child = this._first;
2435      this._lock = 0;
2436
2437      while (child) {
2438        child.invalidate(soft);
2439        child = child._next;
2440      }
2441
2442      return _Animation.prototype.invalidate.call(this, soft);
2443    };
2444
2445    _proto2.clear = function clear(includeLabels) {
2446      if (includeLabels === void 0) {
2447        includeLabels = true;
2448      }
2449
2450      var child = this._first,
2451          next;
2452
2453      while (child) {
2454        next = child._next;
2455        this.remove(child);
2456        child = next;
2457      }
2458
2459      this._dp && (this._time = this._tTime = this._pTime = 0);
2460      includeLabels && (this.labels = {});
2461      return _uncache(this);
2462    };
2463
2464    _proto2.totalDuration = function totalDuration(value) {
2465      var max = 0,
2466          self = this,
2467          child = self._last,
2468          prevStart = _bigNum,
2469          prev,
2470          start,
2471          parent;
2472
2473      if (arguments.length) {
2474        return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value));
2475      }
2476
2477      if (self._dirty) {
2478        parent = self.parent;
2479
2480        while (child) {
2481          prev = child._prev;
2482          child._dirty && child.totalDuration();
2483          start = child._start;
2484
2485          if (start > prevStart && self._sort && child._ts && !self._lock) {
2486            self._lock = 1;
2487            _addToTimeline(self, child, start - child._delay, 1)._lock = 0;
2488          } else {
2489            prevStart = start;
2490          }
2491
2492          if (start < 0 && child._ts) {
2493            max -= start;
2494
2495            if (!parent && !self._dp || parent && parent.smoothChildTiming) {
2496              self._start += start / self._ts;
2497              self._time -= start;
2498              self._tTime -= start;
2499            }
2500
2501            self.shiftChildren(-start, false, -1e999);
2502            prevStart = 0;
2503          }
2504
2505          child._end > max && child._ts && (max = child._end);
2506          child = prev;
2507        }
2508
2509        _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1);
2510
2511        self._dirty = 0;
2512      }
2513
2514      return self._tDur;
2515    };
2516
2517    Timeline.updateRoot = function updateRoot(time) {
2518      if (_globalTimeline._ts) {
2519        _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline));
2520
2521        _lastRenderedFrame = _ticker.frame;
2522      }
2523
2524      if (_ticker.frame >= _nextGCFrame) {
2525        _nextGCFrame += _config.autoSleep || 120;
2526        var child = _globalTimeline._first;
2527        if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) {
2528          while (child && !child._ts) {
2529            child = child._next;
2530          }
2531
2532          child || _ticker.sleep();
2533        }
2534      }
2535    };
2536
2537    return Timeline;
2538  }(Animation);
2539
2540  _setDefaults(Timeline.prototype, {
2541    _lock: 0,
2542    _hasPause: 0,
2543    _forcing: 0
2544  });
2545
2546  var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) {
2547    var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter),
2548        index = 0,
2549        matchIndex = 0,
2550        result,
2551        startNums,
2552        color,
2553        endNum,
2554        chunk,
2555        startNum,
2556        hasRandom,
2557        a;
2558    pt.b = start;
2559    pt.e = end;
2560    start += "";
2561    end += "";
2562
2563    if (hasRandom = ~end.indexOf("random(")) {
2564      end = _replaceRandom(end);
2565    }
2566
2567    if (stringFilter) {
2568      a = [start, end];
2569      stringFilter(a, target, prop);
2570      start = a[0];
2571      end = a[1];
2572    }
2573
2574    startNums = start.match(_complexStringNumExp) || [];
2575
2576    while (result = _complexStringNumExp.exec(end)) {
2577      endNum = result[0];
2578      chunk = end.substring(index, result.index);
2579
2580      if (color) {
2581        color = (color + 1) % 5;
2582      } else if (chunk.substr(-5) === "rgba(") {
2583        color = 1;
2584      }
2585
2586      if (endNum !== startNums[matchIndex++]) {
2587        startNum = parseFloat(startNums[matchIndex - 1]) || 0;
2588        pt._pt = {
2589          _next: pt._pt,
2590          p: chunk || matchIndex === 1 ? chunk : ",",
2591          s: startNum,
2592          c: endNum.charAt(1) === "=" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum,
2593          m: color && color < 4 ? Math.round : 0
2594        };
2595        index = _complexStringNumExp.lastIndex;
2596      }
2597    }
2598
2599    pt.c = index < end.length ? end.substring(index, end.length) : "";
2600    pt.fp = funcParam;
2601
2602    if (_relExp.test(end) || hasRandom) {
2603      pt.e = 0;
2604    }
2605
2606    this._pt = pt;
2607    return pt;
2608  },
2609      _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) {
2610    _isFunction(end) && (end = end(index || 0, target, targets));
2611    var currentValue = target[prop],
2612        parsedStart = start !== "get" ? start : !_isFunction(currentValue) ? currentValue : funcParam ? target[prop.indexOf("set") || !_isFunction(target["get" + prop.substr(3)]) ? prop : "get" + prop.substr(3)](funcParam) : target[prop](),
2613        setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc,
2614        pt;
2615
2616    if (_isString(end)) {
2617      if (~end.indexOf("random(")) {
2618        end = _replaceRandom(end);
2619      }
2620
2621      if (end.charAt(1) === "=") {
2622        pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0);
2623
2624        if (pt || pt === 0) {
2625          end = pt;
2626        }
2627      }
2628    }
2629
2630    if (!optional || parsedStart !== end || _forceAllPropTweens) {
2631      if (!isNaN(parsedStart * end) && end !== "") {
2632        pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter);
2633        funcParam && (pt.fp = funcParam);
2634        modifier && pt.modifier(modifier, this, target);
2635        return this._pt = pt;
2636      }
2637
2638      !currentValue && !(prop in target) && _missingPlugin(prop, end);
2639      return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam);
2640    }
2641  },
2642      _processVars = function _processVars(vars, index, target, targets, tween) {
2643    _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets));
2644
2645    if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) {
2646      return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars;
2647    }
2648
2649    var copy = {},
2650        p;
2651
2652    for (p in vars) {
2653      copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets);
2654    }
2655
2656    return copy;
2657  },
2658      _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) {
2659    var plugin, pt, ptLookup, i;
2660
2661    if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) {
2662      tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority);
2663
2664      if (tween !== _quickTween) {
2665        ptLookup = tween._ptLookup[tween._targets.indexOf(target)];
2666        i = plugin._props.length;
2667
2668        while (i--) {
2669          ptLookup[plugin._props[i]] = pt;
2670        }
2671      }
2672    }
2673
2674    return plugin;
2675  },
2676      _overwritingTween,
2677      _forceAllPropTweens,
2678      _initTween = function _initTween(tween, time, tTime) {
2679    var vars = tween.vars,
2680        ease = vars.ease,
2681        startAt = vars.startAt,
2682        immediateRender = vars.immediateRender,
2683        lazy = vars.lazy,
2684        onUpdate = vars.onUpdate,
2685        runBackwards = vars.runBackwards,
2686        yoyoEase = vars.yoyoEase,
2687        keyframes = vars.keyframes,
2688        autoRevert = vars.autoRevert,
2689        dur = tween._dur,
2690        prevStartAt = tween._startAt,
2691        targets = tween._targets,
2692        parent = tween.parent,
2693        fullTargets = parent && parent.data === "nested" ? parent.vars.targets : targets,
2694        autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites,
2695        tl = tween.timeline,
2696        cleanVars,
2697        i,
2698        p,
2699        pt,
2700        target,
2701        hasPriority,
2702        gsData,
2703        harness,
2704        plugin,
2705        ptLookup,
2706        index,
2707        harnessVars,
2708        overwritten;
2709    tl && (!keyframes || !ease) && (ease = "none");
2710    tween._ease = _parseEase(ease, _defaults.ease);
2711    tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0;
2712
2713    if (yoyoEase && tween._yoyo && !tween._repeat) {
2714      yoyoEase = tween._yEase;
2715      tween._yEase = tween._ease;
2716      tween._ease = yoyoEase;
2717    }
2718
2719    tween._from = !tl && !!vars.runBackwards;
2720
2721    if (!tl || keyframes && !vars.stagger) {
2722      harness = targets[0] ? _getCache(targets[0]).harness : 0;
2723      harnessVars = harness && vars[harness.prop];
2724      cleanVars = _copyExcluding(vars, _reservedProps);
2725
2726      if (prevStartAt) {
2727        prevStartAt._zTime < 0 && prevStartAt.progress(1);
2728        time < 0 && runBackwards && immediateRender && !autoRevert ? prevStartAt.render(-1, true) : prevStartAt.revert(runBackwards && dur ? _revertConfigNoKill : _startAtRevertConfig);
2729        prevStartAt._lazy = 0;
2730      }
2731
2732      if (startAt) {
2733        _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({
2734          data: "isStart",
2735          overwrite: false,
2736          parent: parent,
2737          immediateRender: true,
2738          lazy: !prevStartAt && _isNotFalse(lazy),
2739          startAt: null,
2740          delay: 0,
2741          onUpdate: onUpdate && function () {
2742            return _callback(tween, "onUpdate");
2743          },
2744          stagger: 0
2745        }, startAt)));
2746
2747        tween._startAt._dp = 0;
2748        tween._startAt._sat = tween;
2749        time < 0 && (_reverting || !immediateRender && !autoRevert) && tween._startAt.revert(_revertConfigNoKill);
2750
2751        if (immediateRender) {
2752          if (dur && time <= 0 && tTime <= 0) {
2753            time && (tween._zTime = time);
2754            return;
2755          }
2756        }
2757      } else if (runBackwards && dur) {
2758        if (!prevStartAt) {
2759          time && (immediateRender = false);
2760          p = _setDefaults({
2761            overwrite: false,
2762            data: "isFromStart",
2763            lazy: immediateRender && !prevStartAt && _isNotFalse(lazy),
2764            immediateRender: immediateRender,
2765            stagger: 0,
2766            parent: parent
2767          }, cleanVars);
2768          harnessVars && (p[harness.prop] = harnessVars);
2769
2770          _removeFromParent(tween._startAt = Tween.set(targets, p));
2771
2772          tween._startAt._dp = 0;
2773          tween._startAt._sat = tween;
2774          time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true));
2775          tween._zTime = time;
2776
2777          if (!immediateRender) {
2778            _initTween(tween._startAt, _tinyNum, _tinyNum);
2779          } else if (!time) {
2780            return;
2781          }
2782        }
2783      }
2784
2785      tween._pt = tween._ptCache = 0;
2786      lazy = dur && _isNotFalse(lazy) || lazy && !dur;
2787
2788      for (i = 0; i < targets.length; i++) {
2789        target = targets[i];
2790        gsData = target._gsap || _harness(targets)[i]._gsap;
2791        tween._ptLookup[i] = ptLookup = {};
2792        _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender();
2793        index = fullTargets === targets ? i : fullTargets.indexOf(target);
2794
2795        if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) {
2796          tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority);
2797
2798          plugin._props.forEach(function (name) {
2799            ptLookup[name] = pt;
2800          });
2801
2802          plugin.priority && (hasPriority = 1);
2803        }
2804
2805        if (!harness || harnessVars) {
2806          for (p in cleanVars) {
2807            if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) {
2808              plugin.priority && (hasPriority = 1);
2809            } else {
2810              ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter);
2811            }
2812          }
2813        }
2814
2815        tween._op && tween._op[i] && tween.kill(target, tween._op[i]);
2816
2817        if (autoOverwrite && tween._pt) {
2818          _overwritingTween = tween;
2819
2820          _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time));
2821
2822          overwritten = !tween.parent;
2823          _overwritingTween = 0;
2824        }
2825
2826        tween._pt && lazy && (_lazyLookup[gsData.id] = 1);
2827      }
2828
2829      hasPriority && _sortPropTweensByPriority(tween);
2830      tween._onInit && tween._onInit(tween);
2831    }
2832
2833    tween._onUpdate = onUpdate;
2834    tween._initted = (!tween._op || tween._pt) && !overwritten;
2835    keyframes && time <= 0 && tl.render(_bigNum, true, true);
2836  },
2837      _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time, skipRecursion) {
2838    var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property],
2839        pt,
2840        rootPT,
2841        lookup,
2842        i;
2843
2844    if (!ptCache) {
2845      ptCache = tween._ptCache[property] = [];
2846      lookup = tween._ptLookup;
2847      i = tween._targets.length;
2848
2849      while (i--) {
2850        pt = lookup[i][property];
2851
2852        if (pt && pt.d && pt.d._pt) {
2853          pt = pt.d._pt;
2854
2855          while (pt && pt.p !== property && pt.fp !== property) {
2856            pt = pt._next;
2857          }
2858        }
2859
2860        if (!pt) {
2861          _forceAllPropTweens = 1;
2862          tween.vars[property] = "+=0";
2863
2864          _initTween(tween, time);
2865
2866          _forceAllPropTweens = 0;
2867          return skipRecursion ? _warn(property + " not eligible for reset") : 1;
2868        }
2869
2870        ptCache.push(pt);
2871      }
2872    }
2873
2874    i = ptCache.length;
2875
2876    while (i--) {
2877      rootPT = ptCache[i];
2878      pt = rootPT._pt || rootPT;
2879      pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c;
2880      pt.c = value - pt.s;
2881      rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e));
2882      rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b));
2883    }
2884  },
2885      _addAliasesToVars = function _addAliasesToVars(targets, vars) {
2886    var harness = targets[0] ? _getCache(targets[0]).harness : 0,
2887        propertyAliases = harness && harness.aliases,
2888        copy,
2889        p,
2890        i,
2891        aliases;
2892
2893    if (!propertyAliases) {
2894      return vars;
2895    }
2896
2897    copy = _merge({}, vars);
2898
2899    for (p in propertyAliases) {
2900      if (p in copy) {
2901        aliases = propertyAliases[p].split(",");
2902        i = aliases.length;
2903
2904        while (i--) {
2905          copy[aliases[i]] = copy[p];
2906        }
2907      }
2908    }
2909
2910    return copy;
2911  },
2912      _parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) {
2913    var ease = obj.ease || easeEach || "power1.inOut",
2914        p,
2915        a;
2916
2917    if (_isArray(obj)) {
2918      a = allProps[prop] || (allProps[prop] = []);
2919      obj.forEach(function (value, i) {
2920        return a.push({
2921          t: i / (obj.length - 1) * 100,
2922          v: value,
2923          e: ease
2924        });
2925      });
2926    } else {
2927      for (p in obj) {
2928        a = allProps[p] || (allProps[p] = []);
2929        p === "ease" || a.push({
2930          t: parseFloat(prop),
2931          v: obj[p],
2932          e: ease
2933        });
2934      }
2935    }
2936  },
2937      _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) {
2938    return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value;
2939  },
2940      _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert",
2941      _staggerPropsToSkip = {};
2942
2943  _forEachName(_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger", function (name) {
2944    return _staggerPropsToSkip[name] = 1;
2945  });
2946
2947  var Tween = function (_Animation2) {
2948    _inheritsLoose(Tween, _Animation2);
2949
2950    function Tween(targets, vars, position, skipInherit) {
2951      var _this3;
2952
2953      if (typeof vars === "number") {
2954        position.duration = vars;
2955        vars = position;
2956        position = null;
2957      }
2958
2959      _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this;
2960      var _this3$vars = _this3.vars,
2961          duration = _this3$vars.duration,
2962          delay = _this3$vars.delay,
2963          immediateRender = _this3$vars.immediateRender,
2964          stagger = _this3$vars.stagger,
2965          overwrite = _this3$vars.overwrite,
2966          keyframes = _this3$vars.keyframes,
2967          defaults = _this3$vars.defaults,
2968          scrollTrigger = _this3$vars.scrollTrigger,
2969          yoyoEase = _this3$vars.yoyoEase,
2970          parent = vars.parent || _globalTimeline,
2971          parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets),
2972          tl,
2973          i,
2974          copy,
2975          l,
2976          p,
2977          curTarget,
2978          staggerFunc,
2979          staggerVarsToMerge;
2980      _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://gsap.com", !_config.nullTargetWarn) || [];
2981      _this3._ptLookup = [];
2982      _this3._overwrite = overwrite;
2983
2984      if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {
2985        vars = _this3.vars;
2986        tl = _this3.timeline = new Timeline({
2987          data: "nested",
2988          defaults: defaults || {},
2989          targets: parent && parent.data === "nested" ? parent.vars.targets : parsedTargets
2990        });
2991        tl.kill();
2992        tl.parent = tl._dp = _assertThisInitialized(_this3);
2993        tl._start = 0;
2994
2995        if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {
2996          l = parsedTargets.length;
2997          staggerFunc = stagger && distribute(stagger);
2998
2999          if (_isObject(stagger)) {
3000            for (p in stagger) {
3001              if (~_staggerTweenProps.indexOf(p)) {
3002                staggerVarsToMerge || (staggerVarsToMerge = {});
3003                staggerVarsToMerge[p] = stagger[p];
3004              }
3005            }
3006          }
3007
3008          for (i = 0; i < l; i++) {
3009            copy = _copyExcluding(vars, _staggerPropsToSkip);
3010            copy.stagger = 0;
3011            yoyoEase && (copy.yoyoEase = yoyoEase);
3012            staggerVarsToMerge && _merge(copy, staggerVarsToMerge);
3013            curTarget = parsedTargets[i];
3014            copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets);
3015            copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay;
3016
3017            if (!stagger && l === 1 && copy.delay) {
3018              _this3._delay = delay = copy.delay;
3019              _this3._start += delay;
3020              copy.delay = 0;
3021            }
3022
3023            tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0);
3024            tl._ease = _easeMap.none;
3025          }
3026
3027          tl.duration() ? duration = delay = 0 : _this3.timeline = 0;
3028        } else if (keyframes) {
3029          _inheritDefaults(_setDefaults(tl.vars.defaults, {
3030            ease: "none"
3031          }));
3032
3033          tl._ease = _parseEase(keyframes.ease || vars.ease || "none");
3034          var time = 0,
3035              a,
3036              kf,
3037              v;
3038
3039          if (_isArray(keyframes)) {
vendor: 6,477 bytes, lines 3040-3246
3040            keyframes.forEach(function (frame) {
3041              return tl.to(parsedTargets, frame, ">");
3042            });
3043            tl.duration();
3044          } else {
3045            copy = {};
3046
3047            for (p in keyframes) {
3048              p === "ease" || p === "easeEach" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach);
3049            }
3050
3051            for (p in copy) {
3052              a = copy[p].sort(function (a, b) {
3053                return a.t - b.t;
3054              });
3055              time = 0;
3056
3057              for (i = 0; i < a.length; i++) {
3058                kf = a[i];
3059                v = {
3060                  ease: kf.e,
3061                  duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration
3062                };
3063                v[p] = kf.v;
3064                tl.to(parsedTargets, v, time);
3065                time += v.duration;
3066              }
3067            }
3068
3069            tl.duration() < duration && tl.to({}, {
3070              duration: duration - tl.duration()
3071            });
3072          }
3073        }
3074
3075        duration || _this3.duration(duration = tl.duration());
3076      } else {
3077        _this3.timeline = 0;
3078      }
3079
3080      if (overwrite === true && !_suppressOverwrites) {
3081        _overwritingTween = _assertThisInitialized(_this3);
3082
3083        _globalTimeline.killTweensOf(parsedTargets);
3084
3085        _overwritingTween = 0;
3086      }
3087
3088      _addToTimeline(parent, _assertThisInitialized(_this3), position);
3089
3090      vars.reversed && _this3.reverse();
3091      vars.paused && _this3.paused(true);
3092
3093      if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") {
3094        _this3._tTime = -_tinyNum;
3095
3096        _this3.render(Math.max(0, -delay) || 0);
3097      }
3098
3099      scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger);
3100      return _this3;
3101    }
3102
3103    var _proto3 = Tween.prototype;
3104
3105    _proto3.render = function render(totalTime, suppressEvents, force) {
3106      var prevTime = this._time,
3107          tDur = this._tDur,
3108          dur = this._dur,
3109          isNegative = totalTime < 0,
3110          tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime,
3111          time,
3112          pt,
3113          iteration,
3114          cycleDuration,
3115          prevIteration,
3116          isYoyo,
3117          ratio,
3118          timeline,
3119          yoyoEase;
3120
3121      if (!dur) {
3122        _renderZeroDurationTween(this, totalTime, suppressEvents, force);
3123      } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative) {
3124        time = tTime;
3125        timeline = this.timeline;
3126
3127        if (this._repeat) {
3128          cycleDuration = dur + this._rDelay;
3129
3130          if (this._repeat < -1 && isNegative) {
3131            return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);
3132          }
3133
3134          time = _roundPrecise(tTime % cycleDuration);
3135
3136          if (tTime === tDur) {
3137            iteration = this._repeat;
3138            time = dur;
3139          } else {
3140            iteration = ~~(tTime / cycleDuration);
3141
3142            if (iteration && iteration === _roundPrecise(tTime / cycleDuration)) {
3143              time = dur;
3144              iteration--;
3145            }
3146
3147            time > dur && (time = dur);
3148          }
3149
3150          isYoyo = this._yoyo && iteration & 1;
3151
3152          if (isYoyo) {
3153            yoyoEase = this._yEase;
3154            time = dur - time;
3155          }
3156
3157          prevIteration = _animationCycle(this._tTime, cycleDuration);
3158
3159          if (time === prevTime && !force && this._initted && iteration === prevIteration) {
3160            this._tTime = tTime;
3161            return this;
3162          }
3163
3164          if (iteration !== prevIteration) {
3165            timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo);
3166
3167            if (this.vars.repeatRefresh && !isYoyo && !this._lock && this._time !== cycleDuration && this._initted) {
3168              this._lock = force = 1;
3169              this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0;
3170            }
3171          }
3172        }
3173
3174        if (!this._initted) {
3175          if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) {
3176            this._tTime = 0;
3177            return this;
3178          }
3179
3180          if (prevTime !== this._time && !(force && this.vars.repeatRefresh && iteration !== prevIteration)) {
3181            return this;
3182          }
3183
3184          if (dur !== this._dur) {
3185            return this.render(totalTime, suppressEvents, force);
3186          }
3187        }
3188
3189        this._tTime = tTime;
3190        this._time = time;
3191
3192        if (!this._act && this._ts) {
3193          this._act = 1;
3194          this._lazy = 0;
3195        }
3196
3197        this.ratio = ratio = (yoyoEase || this._ease)(time / dur);
3198
3199        if (this._from) {
3200          this.ratio = ratio = 1 - ratio;
3201        }
3202
3203        if (time && !prevTime && !suppressEvents && !iteration) {
3204          _callback(this, "onStart");
3205
3206          if (this._tTime !== tTime) {
3207            return this;
3208          }
3209        }
3210
3211        pt = this._pt;
3212
3213        while (pt) {
3214          pt.r(ratio, pt.d);
3215          pt = pt._next;
3216        }
3217
3218        timeline && timeline.render(totalTime < 0 ? totalTime : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime);
3219
3220        if (this._onUpdate && !suppressEvents) {
3221          isNegative && _rewindStartAt(this, totalTime, suppressEvents, force);
3222
3223          _callback(this, "onUpdate");
3224        }
3225
3226        this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat");
3227
3228        if ((tTime === this._tDur || !tTime) && this._tTime === tTime) {
3229          isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true);
3230          (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1);
3231
3232          if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) {
3233            _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true);
3234
3235            this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();
3236          }
3237        }
3238      }
3239
3240      return this;
3241    };
3242
3243    _proto3.targets = function targets() {
3244      return this._targets;
3245    };
3246
vendor: 1,310 bytes, lines 3247-3280
3247    _proto3.invalidate = function invalidate(soft) {
3248      (!soft || !this.vars.runBackwards) && (this._startAt = 0);
3249      this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0;
3250      this._ptLookup = [];
3251      this.timeline && this.timeline.invalidate(soft);
3252      return _Animation2.prototype.invalidate.call(this, soft);
3253    };
3254
3255    _proto3.resetTo = function resetTo(property, value, start, startIsRelative, skipRecursion) {
3256      _tickerActive || _ticker.wake();
3257      this._ts || this.play();
3258      var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts),
3259          ratio;
3260      this._initted || _initTween(this, time);
3261      ratio = this._ease(time / this._dur);
3262
3263      if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time, skipRecursion)) {
3264        return this.resetTo(property, value, start, startIsRelative, 1);
3265      }
3266
3267      _alignPlayhead(this, 0);
3268
3269      this.parent || _addLinkedListItem(this._dp, this, "_first", "_last", this._dp._sort ? "_start" : 0);
3270      return this.render(0);
3271    };
3272
3273    _proto3.kill = function kill(targets, vars) {
3274      if (vars === void 0) {
3275        vars = "all";
3276      }
3277
3278      if (!targets && (!vars || vars === "all")) {
3279        this._lazy = this._pt = 0;
3280        return this.parent ? _interrupt(this) :
vendor: 16,527 bytes, lines 3280-3882
3280 this;
3281      }
3282
3283      if (this.timeline) {
3284        var tDur = this.timeline.totalDuration();
3285        this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this);
3286        this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1);
3287        return this;
3288      }
3289
3290      var parsedTargets = this._targets,
3291          killingTargets = targets ? toArray(targets) : parsedTargets,
3292          propTweenLookup = this._ptLookup,
3293          firstPT = this._pt,
3294          overwrittenProps,
3295          curLookup,
3296          curOverwriteProps,
3297          props,
3298          p,
3299          pt,
3300          i;
3301
3302      if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) {
3303        vars === "all" && (this._pt = 0);
3304        return _interrupt(this);
3305      }
3306
3307      overwrittenProps = this._op = this._op || [];
3308
3309      if (vars !== "all") {
3310        if (_isString(vars)) {
3311          p = {};
3312
3313          _forEachName(vars, function (name) {
3314            return p[name] = 1;
3315          });
3316
3317          vars = p;
3318        }
3319
3320        vars = _addAliasesToVars(parsedTargets, vars);
3321      }
3322
3323      i = parsedTargets.length;
3324
3325      while (i--) {
3326        if (~killingTargets.indexOf(parsedTargets[i])) {
3327          curLookup = propTweenLookup[i];
3328
3329          if (vars === "all") {
3330            overwrittenProps[i] = vars;
3331            props = curLookup;
3332            curOverwriteProps = {};
3333          } else {
3334            curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {};
3335            props = vars;
3336          }
3337
3338          for (p in props) {
3339            pt = curLookup && curLookup[p];
3340
3341            if (pt) {
3342              if (!("kill" in pt.d) || pt.d.kill(p) === true) {
3343                _removeLinkedListItem(this, pt, "_pt");
3344              }
3345
3346              delete curLookup[p];
3347            }
3348
3349            if (curOverwriteProps !== "all") {
3350              curOverwriteProps[p] = 1;
3351            }
3352          }
3353        }
3354      }
3355
3356      this._initted && !this._pt && firstPT && _interrupt(this);
3357      return this;
3358    };
3359
3360    Tween.to = function to(targets, vars) {
3361      return new Tween(targets, vars, arguments[2]);
3362    };
3363
3364    Tween.from = function from(targets, vars) {
3365      return _createTweenType(1, arguments);
3366    };
3367
3368    Tween.delayedCall = function delayedCall(delay, callback, params, scope) {
3369      return new Tween(callback, 0, {
3370        immediateRender: false,
3371        lazy: false,
3372        overwrite: false,
3373        delay: delay,
3374        onComplete: callback,
3375        onReverseComplete: callback,
3376        onCompleteParams: params,
3377        onReverseCompleteParams: params,
3378        callbackScope: scope
3379      });
3380    };
3381
3382    Tween.fromTo = function fromTo(targets, fromVars, toVars) {
3383      return _createTweenType(2, arguments);
3384    };
3385
3386    Tween.set = function set(targets, vars) {
3387      vars.duration = 0;
3388      vars.repeatDelay || (vars.repeat = 0);
3389      return new Tween(targets, vars);
3390    };
3391
3392    Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) {
3393      return _globalTimeline.killTweensOf(targets, props, onlyActive);
3394    };
3395
3396    return Tween;
3397  }(Animation);
3398
3399  _setDefaults(Tween.prototype, {
3400    _targets: [],
3401    _lazy: 0,
3402    _startAt: 0,
3403    _op: 0,
3404    _onInit: 0
3405  });
3406
3407  _forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) {
3408    Tween[name] = function () {
3409      var tl = new Timeline(),
3410          params = _slice.call(arguments, 0);
3411
3412      params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0);
3413      return tl[name].apply(tl, params);
3414    };
3415  });
3416
3417  var _setterPlain = function _setterPlain(target, property, value) {
3418    return target[property] = value;
3419  },
3420      _setterFunc = function _setterFunc(target, property, value) {
3421    return target[property](value);
3422  },
3423      _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) {
3424    return target[property](data.fp, value);
3425  },
3426      _setterAttribute = function _setterAttribute(target, property, value) {
3427    return target.setAttribute(property, value);
3428  },
3429      _getSetter = function _getSetter(target, property) {
3430    return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain;
3431  },
3432      _renderPlain = function _renderPlain(ratio, data) {
3433    return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data);
3434  },
3435      _renderBoolean = function _renderBoolean(ratio, data) {
3436    return data.set(data.t, data.p, !!(data.s + data.c * ratio), data);
3437  },
3438      _renderComplexString = function _renderComplexString(ratio, data) {
3439    var pt = data._pt,
3440        s = "";
3441
3442    if (!ratio && data.b) {
3443      s = data.b;
3444    } else if (ratio === 1 && data.e) {
3445      s = data.e;
3446    } else {
3447      while (pt) {
3448        s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s;
3449        pt = pt._next;
3450      }
3451
3452      s += data.c;
3453    }
3454
3455    data.set(data.t, data.p, s, data);
3456  },
3457      _renderPropTweens = function _renderPropTweens(ratio, data) {
3458    var pt = data._pt;
3459
3460    while (pt) {
3461      pt.r(ratio, pt.d);
3462      pt = pt._next;
3463    }
3464  },
3465      _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) {
3466    var pt = this._pt,
3467        next;
3468
3469    while (pt) {
3470      next = pt._next;
3471      pt.p === property && pt.modifier(modifier, tween, target);
3472      pt = next;
3473    }
3474  },
3475      _killPropTweensOf = function _killPropTweensOf(property) {
3476    var pt = this._pt,
3477        hasNonDependentRemaining,
3478        next;
3479
3480    while (pt) {
3481      next = pt._next;
3482
3483      if (pt.p === property && !pt.op || pt.op === property) {
3484        _removeLinkedListItem(this, pt, "_pt");
3485      } else if (!pt.dep) {
3486        hasNonDependentRemaining = 1;
3487      }
3488
3489      pt = next;
3490    }
3491
3492    return !hasNonDependentRemaining;
3493  },
3494      _setterWithModifier = function _setterWithModifier(target, property, value, data) {
3495    data.mSet(target, property, data.m.call(data.tween, value, data.mt), data);
3496  },
3497      _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) {
3498    var pt = parent._pt,
3499        next,
3500        pt2,
3501        first,
3502        last;
3503
3504    while (pt) {
3505      next = pt._next;
3506      pt2 = first;
3507
3508      while (pt2 && pt2.pr > pt.pr) {
3509        pt2 = pt2._next;
3510      }
3511
3512      if (pt._prev = pt2 ? pt2._prev : last) {
3513        pt._prev._next = pt;
3514      } else {
3515        first = pt;
3516      }
3517
3518      if (pt._next = pt2) {
3519        pt2._prev = pt;
3520      } else {
3521        last = pt;
3522      }
3523
3524      pt = next;
3525    }
3526
3527    parent._pt = first;
3528  };
3529
3530  var PropTween = function () {
3531    function PropTween(next, target, prop, start, change, renderer, data, setter, priority) {
3532      this.t = target;
3533      this.s = start;
3534      this.c = change;
3535      this.p = prop;
3536      this.r = renderer || _renderPlain;
3537      this.d = data || this;
3538      this.set = setter || _setterPlain;
3539      this.pr = priority || 0;
3540      this._next = next;
3541
3542      if (next) {
3543        next._prev = this;
3544      }
3545    }
3546
3547    var _proto4 = PropTween.prototype;
3548
3549    _proto4.modifier = function modifier(func, tween, target) {
3550      this.mSet = this.mSet || this.set;
3551      this.set = _setterWithModifier;
3552      this.m = func;
3553      this.mt = target;
3554      this.tween = tween;
3555    };
3556
3557    return PropTween;
3558  }();
3559
3560  _forEachName(_callbackNames + "parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger", function (name) {
3561    return _reservedProps[name] = 1;
3562  });
3563
3564  _globals.TweenMax = _globals.TweenLite = Tween;
3565  _globals.TimelineLite = _globals.TimelineMax = Timeline;
3566  _globalTimeline = new Timeline({
3567    sortChildren: false,
3568    defaults: _defaults,
3569    autoRemoveChildren: true,
3570    id: "root",
3571    smoothChildTiming: true
3572  });
3573  _config.stringFilter = _colorStringFilter;
3574
3575  var _media = [],
3576      _listeners = {},
3577      _emptyArray = [],
3578      _lastMediaTime = 0,
3579      _contextID = 0,
3580      _dispatch = function _dispatch(type) {
3581    return (_listeners[type] || _emptyArray).map(function (f) {
3582      return f();
3583    });
3584  },
3585      _onMediaChange = function _onMediaChange() {
3586    var time = Date.now(),
3587        matches = [];
3588
3589    if (time - _lastMediaTime > 2) {
3590      _dispatch("matchMediaInit");
3591
3592      _media.forEach(function (c) {
3593        var queries = c.queries,
3594            conditions = c.conditions,
3595            match,
3596            p,
3597            anyMatch,
3598            toggled;
3599
3600        for (p in queries) {
3601          match = _win.matchMedia(queries[p]).matches;
3602          match && (anyMatch = 1);
3603
3604          if (match !== conditions[p]) {
3605            conditions[p] = match;
3606            toggled = 1;
3607          }
3608        }
3609
3610        if (toggled) {
3611          c.revert();
3612          anyMatch && matches.push(c);
3613        }
3614      });
3615
3616      _dispatch("matchMediaRevert");
3617
3618      matches.forEach(function (c) {
3619        return c.onMatch(c, function (func) {
3620          return c.add(null, func);
3621        });
3622      });
3623      _lastMediaTime = time;
3624
3625      _dispatch("matchMedia");
3626    }
3627  };
3628
3629  var Context = function () {
3630    function Context(func, scope) {
3631      this.selector = scope && selector(scope);
3632      this.data = [];
3633      this._r = [];
3634      this.isReverted = false;
3635      this.id = _contextID++;
3636      func && this.add(func);
3637    }
3638
3639    var _proto5 = Context.prototype;
3640
3641    _proto5.add = function add(name, func, scope) {
3642      if (_isFunction(name)) {
3643        scope = func;
3644        func = name;
3645        name = _isFunction;
3646      }
3647
3648      var self = this,
3649          f = function f() {
3650        var prev = _context,
3651            prevSelector = self.selector,
3652            result;
3653        prev && prev !== self && prev.data.push(self);
3654        scope && (self.selector = selector(scope));
3655        _context = self;
3656        result = func.apply(self, arguments);
3657        _isFunction(result) && self._r.push(result);
3658        _context = prev;
3659        self.selector = prevSelector;
3660        self.isReverted = false;
3661        return result;
3662      };
3663
3664      self.last = f;
3665      return name === _isFunction ? f(self, function (func) {
3666        return self.add(null, func);
3667      }) : name ? self[name] = f : f;
3668    };
3669
3670    _proto5.ignore = function ignore(func) {
3671      var prev = _context;
3672      _context = null;
3673      func(this);
3674      _context = prev;
3675    };
3676
3677    _proto5.getTweens = function getTweens() {
3678      var a = [];
3679      this.data.forEach(function (e) {
3680        return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === "nested") && a.push(e);
3681      });
3682      return a;
3683    };
3684
3685    _proto5.clear = function clear() {
3686      this._r.length = this.data.length = 0;
3687    };
3688
3689    _proto5.kill = function kill(revert, matchMedia) {
3690      var _this4 = this;
3691
3692      if (revert) {
3693        (function () {
3694          var tweens = _this4.getTweens(),
3695              i = _this4.data.length,
3696              t;
3697
3698          while (i--) {
3699            t = _this4.data[i];
3700
3701            if (t.data === "isFlip") {
3702              t.revert();
3703              t.getChildren(true, true, false).forEach(function (tween) {
3704                return tweens.splice(tweens.indexOf(tween), 1);
3705              });
3706            }
3707          }
3708
3709          tweens.map(function (t) {
3710            return {
3711              g: t._dur || t._delay || t._sat && !t._sat.vars.immediateRender ? t.globalTime(0) : -Infinity,
3712              t: t
3713            };
3714          }).sort(function (a, b) {
3715            return b.g - a.g || -Infinity;
3716          }).forEach(function (o) {
3717            return o.t.revert(revert);
3718          });
3719          i = _this4.data.length;
3720
3721          while (i--) {
3722            t = _this4.data[i];
3723
3724            if (t instanceof Timeline) {
3725              if (t.data !== "nested") {
3726                t.scrollTrigger && t.scrollTrigger.revert();
3727                t.kill();
3728              }
3729            } else {
3730              !(t instanceof Tween) && t.revert && t.revert(revert);
3731            }
3732          }
3733
3734          _this4._r.forEach(function (f) {
3735            return f(revert, _this4);
3736          });
3737
3738          _this4.isReverted = true;
3739        })();
3740      } else {
3741        this.data.forEach(function (e) {
3742          return e.kill && e.kill();
3743        });
3744      }
3745
3746      this.clear();
3747
3748      if (matchMedia) {
3749        var i = _media.length;
3750
3751        while (i--) {
3752          _media[i].id === this.id && _media.splice(i, 1);
3753        }
3754      }
3755    };
3756
3757    _proto5.revert = function revert(config) {
3758      this.kill(config || {});
3759    };
3760
3761    return Context;
3762  }();
3763
3764  var MatchMedia = function () {
3765    function MatchMedia(scope) {
3766      this.contexts = [];
3767      this.scope = scope;
3768      _context && _context.data.push(this);
3769    }
3770
3771    var _proto6 = MatchMedia.prototype;
3772
3773    _proto6.add = function add(conditions, func, scope) {
3774      _isObject(conditions) || (conditions = {
3775        matches: conditions
3776      });
3777      var context = new Context(0, scope || this.scope),
3778          cond = context.conditions = {},
3779          mq,
3780          p,
3781          active;
3782      _context && !context.selector && (context.selector = _context.selector);
3783      this.contexts.push(context);
3784      func = context.add("onMatch", func);
3785      context.queries = conditions;
3786
3787      for (p in conditions) {
3788        if (p === "all") {
3789          active = 1;
3790        } else {
3791          mq = _win.matchMedia(conditions[p]);
3792
3793          if (mq) {
3794            _media.indexOf(context) < 0 && _media.push(context);
3795            (cond[p] = mq.matches) && (active = 1);
3796            mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange);
3797          }
3798        }
3799      }
3800
3801      active && func(context, function (f) {
3802        return context.add(null, f);
3803      });
3804      return this;
3805    };
3806
3807    _proto6.revert = function revert(config) {
3808      this.kill(config || {});
3809    };
3810
3811    _proto6.kill = function kill(revert) {
3812      this.contexts.forEach(function (c) {
3813        return c.kill(revert, true);
3814      });
3815    };
3816
3817    return MatchMedia;
3818  }();
3819
3820  var _gsap = {
3821    registerPlugin: function registerPlugin() {
3822      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
3823        args[_key2] = arguments[_key2];
3824      }
3825
3826      args.forEach(function (config) {
3827        return _createPlugin(config);
3828      });
3829    },
3830    timeline: function timeline(vars) {
3831      return new Timeline(vars);
3832    },
3833    getTweensOf: function getTweensOf(targets, onlyActive) {
3834      return _globalTimeline.getTweensOf(targets, onlyActive);
3835    },
3836    getProperty: function getProperty(target, property, unit, uncache) {
3837      _isString(target) && (target = toArray(target)[0]);
3838
3839      var getter = _getCache(target || {}).get,
3840          format = unit ? _passThrough : _numericIfPossible;
3841
3842      unit === "native" && (unit = "");
3843      return !target ? target : !property ? function (property, unit, uncache) {
3844        return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));
3845      } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));
3846    },
3847    quickSetter: function quickSetter(target, property, unit) {
3848      target = toArray(target);
3849
3850      if (target.length > 1) {
3851        var setters = target.map(function (t) {
3852          return gsap.quickSetter(t, property, unit);
3853        }),
3854            l = setters.length;
3855        return function (value) {
3856          var i = l;
3857
3858          while (i--) {
3859            setters[i](value);
3860          }
3861        };
3862      }
3863
3864      target = target[0] || {};
3865
3866      var Plugin = _plugins[property],
3867          cache = _getCache(target),
3868          p = cache.harness && (cache.harness.aliases || {})[property] || property,
3869          setter = Plugin ? function (value) {
3870        var p = new Plugin();
3871        _quickTween._pt = 0;
3872        p.init(target, unit ? value + unit : value, _quickTween, 0, [target]);
3873        p.render(1, p);
3874        _quickTween._pt && _renderPropTweens(1, _quickTween);
3875      } : cache.set(target, p);
3876
3877      return Plugin ? setter : function (value) {
3878        return setter(target, p, unit ? value + unit : value, cache, 1);
3879      };
3880    },
3881    quickTo: function quickTo(target, property, vars) {
3882      var _
3882merge2;
3883
3884      var tween = gsap.to(target, _merge((_merge2 = {}, _merge2[property] = "+=0.1", _merge2.paused = true, _merge
vendor: 5,649 bytes, lines 3884-4086
38842), vars || {})),
3885          func = function func(value, start, startIsRelative) {
3886        return tween.resetTo(property, value, start, startIsRelative);
3887      };
3888
3889      func.tween = tween;
3890      return func;
3891    },
3892    isTweening: function isTweening(targets) {
3893      return _globalTimeline.getTweensOf(targets, true).length > 0;
3894    },
3895    defaults: function defaults(value) {
3896      value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease));
3897      return _mergeDeep(_defaults, value || {});
3898    },
3899    config: function config(value) {
3900      return _mergeDeep(_config, value || {});
3901    },
3902    registerEffect: function registerEffect(_ref3) {
3903      var name = _ref3.name,
3904          effect = _ref3.effect,
3905          plugins = _ref3.plugins,
3906          defaults = _ref3.defaults,
3907          extendTimeline = _ref3.extendTimeline;
3908      (plugins || "").split(",").forEach(function (pluginName) {
3909        return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin.");
3910      });
3911
3912      _effects[name] = function (targets, vars, tl) {
3913        return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl);
3914      };
3915
3916      if (extendTimeline) {
3917        Timeline.prototype[name] = function (targets, vars, position) {
3918          return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position);
3919        };
3920      }
3921    },
3922    registerEase: function registerEase(name, ease) {
3923      _easeMap[name] = _parseEase(ease);
3924    },
3925    parseEase: function parseEase(ease, defaultEase) {
3926      return arguments.length ? _parseEase(ease, defaultEase) : _easeMap;
3927    },
3928    getById: function getById(id) {
3929      return _globalTimeline.getById(id);
3930    },
3931    exportRoot: function exportRoot(vars, includeDelayedCalls) {
3932      if (vars === void 0) {
3933        vars = {};
3934      }
3935
3936      var tl = new Timeline(vars),
3937          child,
3938          next;
3939      tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming);
3940
3941      _globalTimeline.remove(tl);
3942
3943      tl._dp = 0;
3944      tl._time = tl._tTime = _globalTimeline._time;
3945      child = _globalTimeline._first;
3946
3947      while (child) {
3948        next = child._next;
3949
3950        if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) {
3951          _addToTimeline(tl, child, child._start - child._delay);
3952        }
3953
3954        child = next;
3955      }
3956
3957      _addToTimeline(_globalTimeline, tl, 0);
3958
3959      return tl;
3960    },
3961    context: function context(func, scope) {
3962      return func ? new Context(func, scope) : _context;
3963    },
3964    matchMedia: function matchMedia(scope) {
3965      return new MatchMedia(scope);
3966    },
3967    matchMediaRefresh: function matchMediaRefresh() {
3968      return _media.forEach(function (c) {
3969        var cond = c.conditions,
3970            found,
3971            p;
3972
3973        for (p in cond) {
3974          if (cond[p]) {
3975            cond[p] = false;
3976            found = 1;
3977          }
3978        }
3979
3980        found && c.revert();
3981      }) || _onMediaChange();
3982    },
3983    addEventListener: function addEventListener(type, callback) {
3984      var a = _listeners[type] || (_listeners[type] = []);
3985      ~a.indexOf(callback) || a.push(callback);
3986    },
3987    removeEventListener: function removeEventListener(type, callback) {
3988      var a = _listeners[type],
3989          i = a && a.indexOf(callback);
3990      i >= 0 && a.splice(i, 1);
3991    },
3992    utils: {
3993      wrap: wrap,
3994      wrapYoyo: wrapYoyo,
3995      distribute: distribute,
3996      random: random,
3997      snap: snap,
3998      normalize: normalize,
3999      getUnit: getUnit,
4000      clamp: clamp,
4001      splitColor: splitColor,
4002      toArray: toArray,
4003      selector: selector,
4004      mapRange: mapRange,
4005      pipe: pipe,
4006      unitize: unitize,
4007      interpolate: interpolate,
4008      shuffle: shuffle
4009    },
4010    install: _install,
4011    effects: _effects,
4012    ticker: _ticker,
4013    updateRoot: Timeline.updateRoot,
4014    plugins: _plugins,
4015    globalTimeline: _globalTimeline,
4016    core: {
4017      PropTween: PropTween,
4018      globals: _addGlobal,
4019      Tween: Tween,
4020      Timeline: Timeline,
4021      Animation: Animation,
4022      getCache: _getCache,
4023      _removeLinkedListItem: _removeLinkedListItem,
4024      reverting: function reverting() {
4025        return _reverting;
4026      },
4027      context: function context(toAdd) {
4028        if (toAdd && _context) {
4029          _context.data.push(toAdd);
4030
4031          toAdd._ctx = _context;
4032        }
4033
4034        return _context;
4035      },
4036      suppressOverwrites: function suppressOverwrites(value) {
4037        return _suppressOverwrites = value;
4038      }
4039    }
4040  };
4041
4042  _forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) {
4043    return _gsap[name] = Tween[name];
4044  });
4045
4046  _ticker.add(Timeline.updateRoot);
4047
4048  _quickTween = _gsap.to({}, {
4049    duration: 0
4050  });
4051
4052  var _getPluginPropTween = function _getPluginPropTween(plugin, prop) {
4053    var pt = plugin._pt;
4054
4055    while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) {
4056      pt = pt._next;
4057    }
4058
4059    return pt;
4060  },
4061      _addModifiers = function _addModifiers(tween, modifiers) {
4062    var targets = tween._targets,
4063        p,
4064        i,
4065        pt;
4066
4067    for (p in modifiers) {
4068      i = targets.length;
4069
4070      while (i--) {
4071        pt = tween._ptLookup[i][p];
4072
4073        if (pt && (pt = pt.d)) {
4074          if (pt._pt) {
4075            pt = _getPluginPropTween(pt, p);
4076          }
4077
4078          pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p);
4079        }
4080      }
4081    }
4082  },
4083      _buildModifierPlugin = function _buildModifierPlugin(name, modifier) {
4084    return {
4085      name: name,
4086      
vendor: 21,125 bytes, lines 4086-4737
4086rawVars: 1,
4087      init: function init(target, vars, tween) {
4088        tween._onInit = function (tween) {
4089          var temp, p;
4090
4091          if (_isString(vars)) {
4092            temp = {};
4093
4094            _forEachName(vars, function (name) {
4095              return temp[name] = 1;
4096            });
4097
4098            vars = temp;
4099          }
4100
4101          if (modifier) {
4102            temp = {};
4103
4104            for (p in vars) {
4105              temp[p] = modifier(vars[p]);
4106            }
4107
4108            vars = temp;
4109          }
4110
4111          _addModifiers(tween, vars);
4112        };
4113      }
4114    };
4115  };
4116
4117  var gsap = _gsap.registerPlugin({
4118    name: "attr",
4119    init: function init(target, vars, tween, index, targets) {
4120      var p, pt, v;
4121      this.tween = tween;
4122
4123      for (p in vars) {
4124        v = target.getAttribute(p) || "";
4125        pt = this.add(target, "setAttribute", (v || 0) + "", vars[p], index, targets, 0, 0, p);
4126        pt.op = p;
4127        pt.b = v;
4128
4129        this._props.push(p);
4130      }
4131    },
4132    render: function render(ratio, data) {
4133      var pt = data._pt;
4134
4135      while (pt) {
4136        _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d);
4137        pt = pt._next;
4138      }
4139    }
4140  }, {
4141    name: "endArray",
4142    init: function init(target, value) {
4143      var i = value.length;
4144
4145      while (i--) {
4146        this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1);
4147      }
4148    }
4149  }, _buildModifierPlugin("roundProps", _roundModifier), _buildModifierPlugin("modifiers"), _buildModifierPlugin("snap", snap)) || _gsap;
4150  Tween.version = Timeline.version = gsap.version = "3.12.5";
4151  _coreReady = 1;
4152  _windowExists() && _wake();
4153  var Power0 = _easeMap.Power0,
4154      Power1 = _easeMap.Power1,
4155      Power2 = _easeMap.Power2,
4156      Power3 = _easeMap.Power3,
4157      Power4 = _easeMap.Power4,
4158      Linear = _easeMap.Linear,
4159      Quad = _easeMap.Quad,
4160      Cubic = _easeMap.Cubic,
4161      Quart = _easeMap.Quart,
4162      Quint = _easeMap.Quint,
4163      Strong = _easeMap.Strong,
4164      Elastic = _easeMap.Elastic,
4165      Back = _easeMap.Back,
4166      SteppedEase = _easeMap.SteppedEase,
4167      Bounce = _easeMap.Bounce,
4168      Sine = _easeMap.Sine,
4169      Expo = _easeMap.Expo,
4170      Circ = _easeMap.Circ;
4171
4172  var _win$1,
4173      _doc$1,
4174      _docElement,
4175      _pluginInitted,
4176      _tempDiv,
4177      _tempDivStyler,
4178      _recentSetterPlugin,
4179      _reverting$1,
4180      _windowExists$1 = function _windowExists() {
4181    return typeof window !== "undefined";
4182  },
4183      _transformProps = {},
4184      _RAD2DEG = 180 / Math.PI,
4185      _DEG2RAD = Math.PI / 180,
4186      _atan2 = Math.atan2,
4187      _bigNum$1 = 1e8,
4188      _capsExp = /([A-Z])/g,
4189      _horizontalExp = /(left|right|width|margin|padding|x)/i,
4190      _complexExp = /[\s,\(]\S/,
4191      _propertyAliases = {
4192    autoAlpha: "opacity,visibility",
4193    scale: "scaleX,scaleY",
4194    alpha: "opacity"
4195  },
4196      _renderCSSProp = function _renderCSSProp(ratio, data) {
4197    return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);
4198  },
4199      _renderPropWithEnd = function _renderPropWithEnd(ratio, data) {
4200    return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);
4201  },
4202      _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) {
4203    return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data);
4204  },
4205      _renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) {
4206    var value = data.s + data.c * ratio;
4207    data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data);
4208  },
4209      _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) {
4210    return data.set(data.t, data.p, ratio ? data.e : data.b, data);
4211  },
4212      _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) {
4213    return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data);
4214  },
4215      _setterCSSStyle = function _setterCSSStyle(target, property, value) {
4216    return target.style[property] = value;
4217  },
4218      _setterCSSProp = function _setterCSSProp(target, property, value) {
4219    return target.style.setProperty(property, value);
4220  },
4221      _setterTransform = function _setterTransform(target, property, value) {
4222    return target._gsap[property] = value;
4223  },
4224      _setterScale = function _setterScale(target, property, value) {
4225    return target._gsap.scaleX = target._gsap.scaleY = value;
4226  },
4227      _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) {
4228    var cache = target._gsap;
4229    cache.scaleX = cache.scaleY = value;
4230    cache.renderTransform(ratio, cache);
4231  },
4232      _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) {
4233    var cache = target._gsap;
4234    cache[property] = value;
4235    cache.renderTransform(ratio, cache);
4236  },
4237      _transformProp = "transform",
4238      _transformOriginProp = _transformProp + "Origin",
4239      _saveStyle = function _saveStyle(property, isNotCSS) {
4240    var _this = this;
4241
4242    var target = this.target,
4243        style = target.style,
4244        cache = target._gsap;
4245
4246    if (property in _transformProps && style) {
4247      this.tfm = this.tfm || {};
4248
4249      if (property !== "transform") {
4250        property = _propertyAliases[property] || property;
4251        ~property.indexOf(",") ? property.split(",").forEach(function (a) {
4252          return _this.tfm[a] = _get(target, a);
4253        }) : this.tfm[property] = cache.x ? cache[property] : _get(target, property);
4254        property === _transformOriginProp && (this.tfm.zOrigin = cache.zOrigin);
4255      } else {
4256        return _propertyAliases.transform.split(",").forEach(function (p) {
4257          return _saveStyle.call(_this, p, isNotCSS);
4258        });
4259      }
4260
4261      if (this.props.indexOf(_transformProp) >= 0) {
4262        return;
4263      }
4264
4265      if (cache.svg) {
4266        this.svgo = target.getAttribute("data-svg-origin");
4267        this.props.push(_transformOriginProp, isNotCSS, "");
4268      }
4269
4270      property = _transformProp;
4271    }
4272
4273    (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]);
4274  },
4275      _removeIndependentTransforms = function _removeIndependentTransforms(style) {
4276    if (style.translate) {
4277      style.removeProperty("translate");
4278      style.removeProperty("scale");
4279      style.removeProperty("rotate");
4280    }
4281  },
4282      _revertStyle = function _revertStyle() {
4283    var props = this.props,
4284        target = this.target,
4285        style = target.style,
4286        cache = target._gsap,
4287        i,
4288        p;
4289
4290    for (i = 0; i < props.length; i += 3) {
4291      props[i + 1] ? target[props[i]] = props[i + 2] : props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].substr(0, 2) === "--" ? props[i] : props[i].replace(_capsExp, "-$1").toLowerCase());
4292    }
4293
4294    if (this.tfm) {
4295      for (p in this.tfm) {
4296        cache[p] = this.tfm[p];
4297      }
4298
4299      if (cache.svg) {
4300        cache.renderTransform();
4301        target.setAttribute("data-svg-origin", this.svgo || "");
4302      }
4303
4304      i = _reverting$1();
4305
4306      if ((!i || !i.isStart) && !style[_transformProp]) {
4307        _removeIndependentTransforms(style);
4308
4309        if (cache.zOrigin && style[_transformOriginProp]) {
4310          style[_transformOriginProp] += " " + cache.zOrigin + "px";
4311          cache.zOrigin = 0;
4312          cache.renderTransform();
4313        }
4314
4315        cache.uncache = 1;
4316      }
4317    }
4318  },
4319      _getStyleSaver = function _getStyleSaver(target, properties) {
4320    var saver = {
4321      target: target,
4322      props: [],
4323      revert: _revertStyle,
4324      save: _saveStyle
4325    };
4326    target._gsap || gsap.core.getCache(target);
4327    properties && properties.split(",").forEach(function (p) {
4328      return saver.save(p);
4329    });
4330    return saver;
4331  },
4332      _supports3D,
4333      _createElement = function _createElement(type, ns) {
4334    var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type);
4335    return e && e.style ? e : _doc$1.createElement(type);
4336  },
4337      _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) {
4338    var cs = getComputedStyle(target);
4339    return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || "";
4340  },
4341      _prefixes = "O,Moz,ms,Ms,Webkit".split(","),
4342      _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) {
4343    var e = element || _tempDiv,
4344        s = e.style,
4345        i = 5;
4346
4347    if (property in s && !preferPrefix) {
4348      return property;
4349    }
4350
4351    property = property.charAt(0).toUpperCase() + property.substr(1);
4352
4353    while (i-- && !(_prefixes[i] + property in s)) {}
4354
4355    return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property;
4356  },
4357      _initCore = function _initCore() {
4358    if (_windowExists$1() && window.document) {
4359      _win$1 = window;
4360      _doc$1 = _win$1.document;
4361      _docElement = _doc$1.documentElement;
4362      _tempDiv = _createElement("div") || {
4363        style: {}
4364      };
4365      _tempDivStyler = _createElement("div");
4366      _transformProp = _checkPropPrefix(_transformProp);
4367      _transformOriginProp = _transformProp + "Origin";
4368      _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0";
4369      _supports3D = !!_checkPropPrefix("perspective");
4370      _reverting$1 = gsap.core.reverting;
4371      _pluginInitted = 1;
4372    }
4373  },
4374      _getBBoxHack = function _getBBoxHack(swapIfPossible) {
4375    var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"),
4376        oldParent = this.parentNode,
4377        oldSibling = this.nextSibling,
4378        oldCSS = this.style.cssText,
4379        bbox;
4380
4381    _docElement.appendChild(svg);
4382
4383    svg.appendChild(this);
4384    this.style.display = "block";
4385
4386    if (swapIfPossible) {
4387      try {
4388        bbox = this.getBBox();
4389        this._gsapBBox = this.getBBox;
4390        this.getBBox = _getBBoxHack;
4391      } catch (e) {}
4392    } else if (this._gsapBBox) {
4393      bbox = this._gsapBBox();
4394    }
4395
4396    if (oldParent) {
4397      if (oldSibling) {
4398        oldParent.insertBefore(this, oldSibling);
4399      } else {
4400        oldParent.appendChild(this);
4401      }
4402    }
4403
4404    _docElement.removeChild(svg);
4405
4406    this.style.cssText = oldCSS;
4407    return bbox;
4408  },
4409      _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) {
4410    var i = attributesArray.length;
4411
4412    while (i--) {
4413      if (target.hasAttribute(attributesArray[i])) {
4414        return target.getAttribute(attributesArray[i]);
4415      }
4416    }
4417  },
4418      _getBBox = function _getBBox(target) {
4419    var bounds;
4420
4421    try {
4422      bounds = target.getBBox();
4423    } catch (error) {
4424      bounds = _getBBoxHack.call(target, true);
4425    }
4426
4427    bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true));
4428    return bounds && !bounds.width && !bounds.x && !bounds.y ? {
4429      x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0,
4430      y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0,
4431      width: 0,
4432      height: 0
4433    } : bounds;
4434  },
4435      _isSVG = function _isSVG(e) {
4436    return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));
4437  },
4438      _removeProperty = function _removeProperty(target, property) {
4439    if (property) {
4440      var style = target.style,
4441          first2Chars;
4442
4443      if (property in _transformProps && property !== _transformOriginProp) {
4444        property = _transformProp;
4445      }
4446
4447      if (style.removeProperty) {
4448        first2Chars = property.substr(0, 2);
4449
4450        if (first2Chars === "ms" || property.substr(0, 6) === "webkit") {
4451          property = "-" + property;
4452        }
4453
4454        style.removeProperty(first2Chars === "--" ? property : property.replace(_capsExp, "-$1").toLowerCase());
4455      } else {
4456        style.removeAttribute(property);
4457      }
4458    }
4459  },
4460      _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) {
4461    var pt = new PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue);
4462    plugin._pt = pt;
4463    pt.b = beginning;
4464    pt.e = end;
4465
4466    plugin._props.push(property);
4467
4468    return pt;
4469  },
4470      _nonConvertibleUnits = {
4471    deg: 1,
4472    rad: 1,
4473    turn: 1
4474  },
4475      _nonStandardLayouts = {
4476    grid: 1,
4477    flex: 1
4478  },
4479      _convertToUnit = function _convertToUnit(target, property, value, unit) {
4480    var curValue = parseFloat(value) || 0,
4481        curUnit = (value + "").trim().substr((curValue + "").length) || "px",
4482        style = _tempDiv.style,
4483        horizontal = _horizontalExp.test(property),
4484        isRootSVG = target.tagName.toLowerCase() === "svg",
4485        measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"),
4486        amount = 100,
4487        toPixels = unit === "px",
4488        toPercent = unit === "%",
4489        px,
4490        parent,
4491        cache,
4492        isSVG;
4493
4494    if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) {
4495      return curValue;
4496    }
4497
4498    curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px"));
4499    isSVG = target.getCTM && _isSVG(target);
4500
4501    if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) {
4502      px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty];
4503      return _round(toPercent ? curValue / px * amount : curValue / 100 * px);
4504    }
4505
4506    style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit);
4507    parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode;
4508
4509    if (isSVG) {
4510      parent = (target.ownerSVGElement || {}).parentNode;
4511    }
4512
4513    if (!parent || parent === _doc$1 || !parent.appendChild) {
4514      parent = _doc$1.body;
4515    }
4516
4517    cache = parent._gsap;
4518
4519    if (cache && toPercent && cache.width && horizontal && cache.time === _ticker.time && !cache.uncache) {
4520      return _round(curValue / cache.width * amount);
4521    } else {
4522      if (toPercent && (property === "height" || property === "width")) {
4523        var v = target.style[property];
4524        target.style[property] = amount + unit;
4525        px = target[measureProperty];
4526        v ? target.style[property] = v : _removeProperty(target, property);
4527      } else {
4528        (toPercent || curUnit === "%") && !_nonStandardLayouts[_getComputedProperty(parent, "display")] && (style.position = _getComputedProperty(target, "position"));
4529        parent === target && (style.position = "static");
4530        parent.appendChild(_tempDiv);
4531        px = _tempDiv[measureProperty];
4532        parent.removeChild(_tempDiv);
4533        style.position = "absolute";
4534      }
4535
4536      if (horizontal && toPercent) {
4537        cache = _getCache(parent);
4538        cache.time = _ticker.time;
4539        cache.width = parent[measureProperty];
4540      }
4541    }
4542
4543    return _round(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0);
4544  },
4545      _get = function _get(target, property, unit, uncache) {
4546    var value;
4547    _pluginInitted || _initCore();
4548
4549    if (property in _propertyAliases && property !== "transform") {
4550      property = _propertyAliases[property];
4551
4552      if (~property.indexOf(",")) {
4553        property = property.split(",")[0];
4554      }
4555    }
4556
4557    if (_transformProps[property] && property !== "transform") {
4558      value = _parseTransform(target, uncache);
4559      value = property !== "transformOrigin" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px";
4560    } else {
4561      value = target.style[property];
4562
4563      if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) {
4564        value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || _getProperty(target, property) || (property === "opacity" ? 1 : 0);
4565      }
4566    }
4567
4568    return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value;
4569  },
4570      _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) {
4571    if (!start || start === "none") {
4572      var p = _checkPropPrefix(prop, target, 1),
4573          s = p && _getComputedProperty(target, p, 1);
4574
4575      if (s && s !== start) {
4576        prop = p;
4577        start = s;
4578      } else if (prop === "borderColor") {
4579        start = _getComputedProperty(target, "borderTopColor");
4580      }
4581    }
4582
4583    var pt = new PropTween(this._pt, target.style, prop, 0, 1, _renderComplexString),
4584        index = 0,
4585        matchIndex = 0,
4586        a,
4587        result,
4588        startValues,
4589        startNum,
4590        color,
4591        startValue,
4592        endValue,
4593        endNum,
4594        chunk,
4595        endUnit,
4596        startUnit,
4597        endValues;
4598    pt.b = start;
4599    pt.e = end;
4600    start += "";
4601    end += "";
4602
4603    if (end === "auto") {
4604      startValue = target.style[prop];
4605      target.style[prop] = end;
4606      end = _getComputedProperty(target, prop) || end;
4607      startValue ? target.style[prop] = startValue : _removeProperty(target, prop);
4608    }
4609
4610    a = [start, end];
4611
4612    _colorStringFilter(a);
4613
4614    start = a[0];
4615    end = a[1];
4616    startValues = start.match(_numWithUnitExp) || [];
4617    endValues = end.match(_numWithUnitExp) || [];
4618
4619    if (endValues.length) {
4620      while (result = _numWithUnitExp.exec(end)) {
4621        endValue = result[0];
4622        chunk = end.substring(index, result.index);
4623
4624        if (color) {
4625          color = (color + 1) % 5;
4626        } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") {
4627          color = 1;
4628        }
4629
4630        if (endValue !== (startValue = startValues[matchIndex++] || "")) {
4631          startNum = parseFloat(startValue) || 0;
4632          startUnit = startValue.substr((startNum + "").length);
4633          endValue.charAt(1) === "=" && (endValue = _parseRelative(startNum, endValue) + startUnit);
4634          endNum = parseFloat(endValue);
4635          endUnit = endValue.substr((endNum + "").length);
4636          index = _numWithUnitExp.lastIndex - endUnit.length;
4637
4638          if (!endUnit) {
4639            endUnit = endUnit || _config.units[prop] || startUnit;
4640
4641            if (index === end.length) {
4642              end += endUnit;
4643              pt.e += endUnit;
4644            }
4645          }
4646
4647          if (startUnit !== endUnit) {
4648            startNum = _convertToUnit(target, prop, startValue, endUnit) || 0;
4649          }
4650
4651          pt._pt = {
4652            _next: pt._pt,
4653            p: chunk || matchIndex === 1 ? chunk : ",",
4654            s: startNum,
4655            c: endNum - startNum,
4656            m: color && color < 4 || prop === "zIndex" ? Math.round : 0
4657          };
4658        }
4659      }
4660
4661      pt.c = index < end.length ? end.substring(index, end.length) : "";
4662    } else {
4663      pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue;
4664    }
4665
4666    _relExp.test(end) && (pt.e = 0);
4667    this._pt = pt;
4668    return pt;
4669  },
4670      _keywordToPercent = {
4671    top: "0%",
4672    bottom: "100%",
4673    left: "0%",
4674    right: "100%",
4675    center: "50%"
4676  },
4677      _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) {
4678    var split = value.split(" "),
4679        x = split[0],
4680        y = split[1] || "50%";
4681
4682    if (x === "top" || x === "bottom" || y === "left" || y === "right") {
4683      value = x;
4684      x = y;
4685      y = value;
4686    }
4687
4688    split[0] = _keywordToPercent[x] || x;
4689    split[1] = _keywordToPercent[y] || y;
4690    return split.join(" ");
4691  },
4692      _renderClearProps = function _renderClearProps(ratio, data) {
4693    if (data.tween && data.tween._time === data.tween._dur) {
4694      var target = data.t,
4695          style = target.style,
4696          props = data.u,
4697          cache = target._gsap,
4698          prop,
4699          clearTransforms,
4700          i;
4701
4702      if (props === "all" || props === true) {
4703        style.cssText = "";
4704        clearTransforms = 1;
4705      } else {
4706        props = props.split(",");
4707        i = props.length;
4708
4709        while (--i > -1) {
4710          prop = props[i];
4711
4712          if (_transformProps[prop]) {
4713            clearTransforms = 1;
4714            prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp;
4715          }
4716
4717          _removeProperty(target, prop);
4718        }
4719      }
4720
4721      if (clearTransforms) {
4722        _removeProperty(target, _transformProp);
4723
4724        if (cache) {
4725          cache.svg && target.removeAttribute("transform");
4726
4727          _parseTransform(target, 1);
4728
4729          cache.uncache = 1;
4730
4731          _removeIndependentTransforms(style);
4732        }
4733      }
4734    }
4735  },
4736      _specialProps = {
4737    clearProps: function clearProps(plugin, target, property, endValue, tween) {
vendor: 1,580 bytes, lines 4738-4778
4738      if (tween.data !== "isFromStart") {
4739        var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps);
4740        pt.u = endValue;
4741        pt.pr = -10;
4742        pt.tween = tween;
4743
4744        plugin._props.push(property);
4745
4746        return 1;
4747      }
4748    }
4749  },
4750      _identity2DMatrix = [1, 0, 0, 1, 0, 0],
4751      _rotationalProperties = {},
4752      _isNullTransform = function _isNullTransform(value) {
4753    return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value;
4754  },
4755      _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) {
4756    var matrixString = _getComputedProperty(target, _transformProp);
4757
4758    return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round);
4759  },
4760      _getMatrix = function _getMatrix(target, force2D) {
4761    var cache = target._gsap || _getCache(target),
4762        style = target.style,
4763        matrix = _getComputedTransformMatrixAsArray(target),
4764        parent,
4765        nextSibling,
4766        temp,
4767        addedToDOM;
4768
4769    if (cache.svg && target.getAttribute("transform")) {
4770      temp = target.transform.baseVal.consolidate().matrix;
4771      matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f];
4772      return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix;
4773    } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) {
4774      temp = style.display;
4775      style.display = "block";
4776      parent = target.parentNode;
4777
4778      if (!parent || !target.offsetParent
vendor: 18,926 bytes, lines 4778-5375
4778) {
4779        addedToDOM = 1;
4780        nextSibling = target.nextElementSibling;
4781
4782        _docElement.appendChild(target);
4783      }
4784
4785      matrix = _getComputedTransformMatrixAsArray(target);
4786      temp ? style.display = temp : _removeProperty(target, "display");
4787
4788      if (addedToDOM) {
4789        nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target);
4790      }
4791    }
4792
4793    return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix;
4794  },
4795      _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) {
4796    var cache = target._gsap,
4797        matrix = matrixArray || _getMatrix(target, true),
4798        xOriginOld = cache.xOrigin || 0,
4799        yOriginOld = cache.yOrigin || 0,
4800        xOffsetOld = cache.xOffset || 0,
4801        yOffsetOld = cache.yOffset || 0,
4802        a = matrix[0],
4803        b = matrix[1],
4804        c = matrix[2],
4805        d = matrix[3],
4806        tx = matrix[4],
4807        ty = matrix[5],
4808        originSplit = origin.split(" "),
4809        xOrigin = parseFloat(originSplit[0]) || 0,
4810        yOrigin = parseFloat(originSplit[1]) || 0,
4811        bounds,
4812        determinant,
4813        x,
4814        y;
4815
4816    if (!originIsAbsolute) {
4817      bounds = _getBBox(target);
4818      xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin);
4819      yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin);
4820    } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) {
4821      x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;
4822      y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;
4823      xOrigin = x;
4824      yOrigin = y;
4825    }
4826
4827    if (smooth || smooth !== false && cache.smooth) {
4828      tx = xOrigin - xOriginOld;
4829      ty = yOrigin - yOriginOld;
4830      cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx;
4831      cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty;
4832    } else {
4833      cache.xOffset = cache.yOffset = 0;
4834    }
4835
4836    cache.xOrigin = xOrigin;
4837    cache.yOrigin = yOrigin;
4838    cache.smooth = !!smooth;
4839    cache.origin = origin;
4840    cache.originIsAbsolute = !!originIsAbsolute;
4841    target.style[_transformOriginProp] = "0px 0px";
4842
4843    if (pluginToAddPropTweensTo) {
4844      _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin);
4845
4846      _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin);
4847
4848      _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset);
4849
4850      _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset);
4851    }
4852
4853    target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin);
4854  },
4855      _parseTransform = function _parseTransform(target, uncache) {
4856    var cache = target._gsap || new GSCache(target);
4857
4858    if ("x" in cache && !uncache && !cache.uncache) {
4859      return cache;
4860    }
4861
4862    var style = target.style,
4863        invertedScaleX = cache.scaleX < 0,
4864        px = "px",
4865        deg = "deg",
4866        cs = getComputedStyle(target),
4867        origin = _getComputedProperty(target, _transformOriginProp) || "0",
4868        x,
4869        y,
4870        z,
4871        scaleX,
4872        scaleY,
4873        rotation,
4874        rotationX,
4875        rotationY,
4876        skewX,
4877        skewY,
4878        perspective,
4879        xOrigin,
4880        yOrigin,
4881        matrix,
4882        angle,
4883        cos,
4884        sin,
4885        a,
4886        b,
4887        c,
4888        d,
4889        a12,
4890        a22,
4891        t1,
4892        t2,
4893        t3,
4894        a13,
4895        a23,
4896        a33,
4897        a42,
4898        a43,
4899        a32;
4900    x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0;
4901    scaleX = scaleY = 1;
4902    cache.svg = !!(target.getCTM && _isSVG(target));
4903
4904    if (cs.translate) {
4905      if (cs.translate !== "none" || cs.scale !== "none" || cs.rotate !== "none") {
4906        style[_transformProp] = (cs.translate !== "none" ? "translate3d(" + (cs.translate + " 0 0").split(" ").slice(0, 3).join(", ") + ") " : "") + (cs.rotate !== "none" ? "rotate(" + cs.rotate + ") " : "") + (cs.scale !== "none" ? "scale(" + cs.scale.split(" ").join(",") + ") " : "") + (cs[_transformProp] !== "none" ? cs[_transformProp] : "");
4907      }
4908
4909      style.scale = style.rotate = style.translate = "none";
4910    }
4911
4912    matrix = _getMatrix(target, cache.svg);
4913
4914    if (cache.svg) {
4915      if (cache.uncache) {
4916        t2 = target.getBBox();
4917        origin = cache.xOrigin - t2.x + "px " + (cache.yOrigin - t2.y) + "px";
4918        t1 = "";
4919      } else {
4920        t1 = !uncache && target.getAttribute("data-svg-origin");
4921      }
4922
4923      _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix);
4924    }
4925
4926    xOrigin = cache.xOrigin || 0;
4927    yOrigin = cache.yOrigin || 0;
4928
4929    if (matrix !== _identity2DMatrix) {
4930      a = matrix[0];
4931      b = matrix[1];
4932      c = matrix[2];
4933      d = matrix[3];
4934      x = a12 = matrix[4];
4935      y = a22 = matrix[5];
4936
4937      if (matrix.length === 6) {
4938        scaleX = Math.sqrt(a * a + b * b);
4939        scaleY = Math.sqrt(d * d + c * c);
4940        rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0;
4941        skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0;
4942        skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD)));
4943
4944        if (cache.svg) {
4945          x -= xOrigin - (xOrigin * a + yOrigin * c);
4946          y -= yOrigin - (xOrigin * b + yOrigin * d);
4947        }
4948      } else {
4949        a32 = matrix[6];
4950        a42 = matrix[7];
4951        a13 = matrix[8];
4952        a23 = matrix[9];
4953        a33 = matrix[10];
4954        a43 = matrix[11];
4955        x = matrix[12];
4956        y = matrix[13];
4957        z = matrix[14];
4958        angle = _atan2(a32, a33);
4959        rotationX = angle * _RAD2DEG;
4960
4961        if (angle) {
4962          cos = Math.cos(-angle);
4963          sin = Math.sin(-angle);
4964          t1 = a12 * cos + a13 * sin;
4965          t2 = a22 * cos + a23 * sin;
4966          t3 = a32 * cos + a33 * sin;
4967          a13 = a12 * -sin + a13 * cos;
4968          a23 = a22 * -sin + a23 * cos;
4969          a33 = a32 * -sin + a33 * cos;
4970          a43 = a42 * -sin + a43 * cos;
4971          a12 = t1;
4972          a22 = t2;
4973          a32 = t3;
4974        }
4975
4976        angle = _atan2(-c, a33);
4977        rotationY = angle * _RAD2DEG;
4978
4979        if (angle) {
4980          cos = Math.cos(-angle);
4981          sin = Math.sin(-angle);
4982          t1 = a * cos - a13 * sin;
4983          t2 = b * cos - a23 * sin;
4984          t3 = c * cos - a33 * sin;
4985          a43 = d * sin + a43 * cos;
4986          a = t1;
4987          b = t2;
4988          c = t3;
4989        }
4990
4991        angle = _atan2(b, a);
4992        rotation = angle * _RAD2DEG;
4993
4994        if (angle) {
4995          cos = Math.cos(angle);
4996          sin = Math.sin(angle);
4997          t1 = a * cos + b * sin;
4998          t2 = a12 * cos + a22 * sin;
4999          b = b * cos - a * sin;
5000          a22 = a22 * cos - a12 * sin;
5001          a = t1;
5002          a12 = t2;
5003        }
5004
5005        if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) {
5006          rotationX = rotation = 0;
5007          rotationY = 180 - rotationY;
5008        }
5009
5010        scaleX = _round(Math.sqrt(a * a + b * b + c * c));
5011        scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32));
5012        angle = _atan2(a12, a22);
5013        skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0;
5014        perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;
5015      }
5016
5017      if (cache.svg) {
5018        t1 = target.getAttribute("transform");
5019        cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp));
5020        t1 && target.setAttribute("transform", t1);
5021      }
5022    }
5023
5024    if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {
5025      if (invertedScaleX) {
5026        scaleX *= -1;
5027        skewX += rotation <= 0 ? 180 : -180;
5028        rotation += rotation <= 0 ? 180 : -180;
5029      } else {
5030        scaleY *= -1;
5031        skewX += skewX <= 0 ? 180 : -180;
5032      }
5033    }
5034
5035    uncache = uncache || cache.uncache;
5036    cache.x = x - ((cache.xPercent = x && (!uncache && cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px;
5037    cache.y = y - ((cache.yPercent = y && (!uncache && cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px;
5038    cache.z = z + px;
5039    cache.scaleX = _round(scaleX);
5040    cache.scaleY = _round(scaleY);
5041    cache.rotation = _round(rotation) + deg;
5042    cache.rotationX = _round(rotationX) + deg;
5043    cache.rotationY = _round(rotationY) + deg;
5044    cache.skewX = skewX + deg;
5045    cache.skewY = skewY + deg;
5046    cache.transformPerspective = perspective + px;
5047
5048    if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || !uncache && cache.zOrigin || 0) {
5049      style[_transformOriginProp] = _firstTwoOnly(origin);
5050    }
5051
5052    cache.xOffset = cache.yOffset = 0;
5053    cache.force3D = _config.force3D;
5054    cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms;
5055    cache.uncache = 0;
5056    return cache;
5057  },
5058      _firstTwoOnly = function _firstTwoOnly(value) {
5059    return (value = value.split(" "))[0] + " " + value[1];
5060  },
5061      _addPxTranslate = function _addPxTranslate(target, start, value) {
5062    var unit = getUnit(start);
5063    return _round(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit;
5064  },
5065      _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) {
5066    cache.z = "0px";
5067    cache.rotationY = cache.rotationX = "0deg";
5068    cache.force3D = 0;
5069
5070    _renderCSSTransforms(ratio, cache);
5071  },
5072      _zeroDeg = "0deg",
5073      _zeroPx = "0px",
5074      _endParenthesis = ") ",
5075      _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) {
5076    var _ref = cache || this,
5077        xPercent = _ref.xPercent,
5078        yPercent = _ref.yPercent,
5079        x = _ref.x,
5080        y = _ref.y,
5081        z = _ref.z,
5082        rotation = _ref.rotation,
5083        rotationY = _ref.rotationY,
5084        rotationX = _ref.rotationX,
5085        skewX = _ref.skewX,
5086        skewY = _ref.skewY,
5087        scaleX = _ref.scaleX,
5088        scaleY = _ref.scaleY,
5089        transformPerspective = _ref.transformPerspective,
5090        force3D = _ref.force3D,
5091        target = _ref.target,
5092        zOrigin = _ref.zOrigin,
5093        transforms = "",
5094        use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true;
5095
5096    if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) {
5097      var angle = parseFloat(rotationY) * _DEG2RAD,
5098          a13 = Math.sin(angle),
5099          a33 = Math.cos(angle),
5100          cos;
5101
5102      angle = parseFloat(rotationX) * _DEG2RAD;
5103      cos = Math.cos(angle);
5104      x = _addPxTranslate(target, x, a13 * cos * -zOrigin);
5105      y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin);
5106      z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin);
5107    }
5108
5109    if (transformPerspective !== _zeroPx) {
5110      transforms += "perspective(" + transformPerspective + _endParenthesis;
5111    }
5112
5113    if (xPercent || yPercent) {
5114      transforms += "translate(" + xPercent + "%, " + yPercent + "%) ";
5115    }
5116
5117    if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) {
5118      transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis;
5119    }
5120
5121    if (rotation !== _zeroDeg) {
5122      transforms += "rotate(" + rotation + _endParenthesis;
5123    }
5124
5125    if (rotationY !== _zeroDeg) {
5126      transforms += "rotateY(" + rotationY + _endParenthesis;
5127    }
5128
5129    if (rotationX !== _zeroDeg) {
5130      transforms += "rotateX(" + rotationX + _endParenthesis;
5131    }
5132
5133    if (skewX !== _zeroDeg || skewY !== _zeroDeg) {
5134      transforms += "skew(" + skewX + ", " + skewY + _endParenthesis;
5135    }
5136
5137    if (scaleX !== 1 || scaleY !== 1) {
5138      transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis;
5139    }
5140
5141    target.style[_transformProp] = transforms || "translate(0, 0)";
5142  },
5143      _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) {
5144    var _ref2 = cache || this,
5145        xPercent = _ref2.xPercent,
5146        yPercent = _ref2.yPercent,
5147        x = _ref2.x,
5148        y = _ref2.y,
5149        rotation = _ref2.rotation,
5150        skewX = _ref2.skewX,
5151        skewY = _ref2.skewY,
5152        scaleX = _ref2.scaleX,
5153        scaleY = _ref2.scaleY,
5154        target = _ref2.target,
5155        xOrigin = _ref2.xOrigin,
5156        yOrigin = _ref2.yOrigin,
5157        xOffset = _ref2.xOffset,
5158        yOffset = _ref2.yOffset,
5159        forceCSS = _ref2.forceCSS,
5160        tx = parseFloat(x),
5161        ty = parseFloat(y),
5162        a11,
5163        a21,
5164        a12,
5165        a22,
5166        temp;
5167
5168    rotation = parseFloat(rotation);
5169    skewX = parseFloat(skewX);
5170    skewY = parseFloat(skewY);
5171
5172    if (skewY) {
5173      skewY = parseFloat(skewY);
5174      skewX += skewY;
5175      rotation += skewY;
5176    }
5177
5178    if (rotation || skewX) {
5179      rotation *= _DEG2RAD;
5180      skewX *= _DEG2RAD;
5181      a11 = Math.cos(rotation) * scaleX;
5182      a21 = Math.sin(rotation) * scaleX;
5183      a12 = Math.sin(rotation - skewX) * -scaleY;
5184      a22 = Math.cos(rotation - skewX) * scaleY;
5185
5186      if (skewX) {
5187        skewY *= _DEG2RAD;
5188        temp = Math.tan(skewX - skewY);
5189        temp = Math.sqrt(1 + temp * temp);
5190        a12 *= temp;
5191        a22 *= temp;
5192
5193        if (skewY) {
5194          temp = Math.tan(skewY);
5195          temp = Math.sqrt(1 + temp * temp);
5196          a11 *= temp;
5197          a21 *= temp;
5198        }
5199      }
5200
5201      a11 = _round(a11);
5202      a21 = _round(a21);
5203      a12 = _round(a12);
5204      a22 = _round(a22);
5205    } else {
5206      a11 = scaleX;
5207      a22 = scaleY;
5208      a21 = a12 = 0;
5209    }
5210
5211    if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) {
5212      tx = _convertToUnit(target, "x", x, "px");
5213      ty = _convertToUnit(target, "y", y, "px");
5214    }
5215
5216    if (xOrigin || yOrigin || xOffset || yOffset) {
5217      tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset);
5218      ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset);
5219    }
5220
5221    if (xPercent || yPercent) {
5222      temp = target.getBBox();
5223      tx = _round(tx + xPercent / 100 * temp.width);
5224      ty = _round(ty + yPercent / 100 * temp.height);
5225    }
5226
5227    temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")";
5228    target.setAttribute("transform", temp);
5229    forceCSS && (target.style[_transformProp] = temp);
5230  },
5231      _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) {
5232    var cap = 360,
5233        isString = _isString(endValue),
5234        endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1),
5235        change = endNum - startNum,
5236        finalValue = startNum + change + "deg",
5237        direction,
5238        pt;
5239
5240    if (isString) {
5241      direction = endValue.split("_")[1];
5242
5243      if (direction === "short") {
5244        change %= cap;
5245
5246        if (change !== change % (cap / 2)) {
5247          change += change < 0 ? cap : -cap;
5248        }
5249      }
5250
5251      if (direction === "cw" && change < 0) {
5252        change = (change + cap * _bigNum$1) % cap - ~~(change / cap) * cap;
5253      } else if (direction === "ccw" && change > 0) {
5254        change = (change - cap * _bigNum$1) % cap - ~~(change / cap) * cap;
5255      }
5256    }
5257
5258    plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd);
5259    pt.e = finalValue;
5260    pt.u = "deg";
5261
5262    plugin._props.push(property);
5263
5264    return pt;
5265  },
5266      _assign = function _assign(target, source) {
5267    for (var p in source) {
5268      target[p] = source[p];
5269    }
5270
5271    return target;
5272  },
5273      _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) {
5274    var startCache = _assign({}, target._gsap),
5275        exclude = "perspective,force3D,transformOrigin,svgOrigin",
5276        style = target.style,
5277        endCache,
5278        p,
5279        startValue,
5280        endValue,
5281        startNum,
5282        endNum,
5283        startUnit,
5284        endUnit;
5285
5286    if (startCache.svg) {
5287      startValue = target.getAttribute("transform");
5288      target.setAttribute("transform", "");
5289      style[_transformProp] = transforms;
5290      endCache = _parseTransform(target, 1);
5291
5292      _removeProperty(target, _transformProp);
5293
5294      target.setAttribute("transform", startValue);
5295    } else {
5296      startValue = getComputedStyle(target)[_transformProp];
5297      style[_transformProp] = transforms;
5298      endCache = _parseTransform(target, 1);
5299      style[_transformProp] = startValue;
5300    }
5301
5302    for (p in _transformProps) {
5303      startValue = startCache[p];
5304      endValue = endCache[p];
5305
5306      if (startValue !== endValue && exclude.indexOf(p) < 0) {
5307        startUnit = getUnit(startValue);
5308        endUnit = getUnit(endValue);
5309        startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue);
5310        endNum = parseFloat(endValue);
5311        plugin._pt = new PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp);
5312        plugin._pt.u = endUnit || 0;
5313
5314        plugin._props.push(p);
5315      }
5316    }
5317
5318    _assign(endCache, startCache);
5319  };
5320
5321  _forEachName("padding,margin,Width,Radius", function (name, index) {
5322    var t = "Top",
5323        r = "Right",
5324        b = "Bottom",
5325        l = "Left",
5326        props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) {
5327      return index < 2 ? name + side : "border" + side + name;
5328    });
5329
5330    _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) {
5331      var a, vars;
5332
5333      if (arguments.length < 4) {
5334        a = props.map(function (prop) {
5335          return _get(plugin, prop, property);
5336        });
5337        vars = a.join(" ");
5338        return vars.split(a[0]).length === 5 ? a[0] : vars;
5339      }
5340
5341      a = (endValue + "").split(" ");
5342      vars = {};
5343      props.forEach(function (prop, i) {
5344        return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0];
5345      });
5346      plugin.init(target, vars, tween);
5347    };
5348  });
5349
5350  var CSSPlugin = {
5351    name: "css",
5352    register: _initCore,
5353    targetTest: function targetTest(target) {
5354      return target.style && target.nodeType;
5355    },
5356    init: function init(target, vars, tween, index, targets) {
5357      var props = this._props,
5358          style = target.style,
5359          startAt = tween.vars.startAt,
5360          startValue,
5361          endValue,
5362          endNum,
5363          startNum,
5364          type,
5365          specialProp,
5366          p,
5367          startUnit,
5368          endUnit,
5369          relative,
5370          isTransformRelated,
5371          transformPropTween,
5372          cache,
5373          smooth,
5374          hasPriority,
5375          inlineProps
vendor: 8,025 bytes, lines 5375-5562
5375;
5376      _pluginInitted || _initCore();
5377      this.styles = this.styles || _getStyleSaver(target);
5378      inlineProps = this.styles.props;
5379      this.tween = tween;
5380
5381      for (p in vars) {
5382        if (p === "autoRound") {
5383          continue;
5384        }
5385
5386        endValue = vars[p];
5387
5388        if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) {
5389          continue;
5390        }
5391
5392        type = typeof endValue;
5393        specialProp = _specialProps[p];
5394
5395        if (type === "function") {
5396          endValue = endValue.call(tween, index, target, targets);
5397          type = typeof endValue;
5398        }
5399
5400        if (type === "string" && ~endValue.indexOf("random(")) {
5401          endValue = _replaceRandom(endValue);
5402        }
5403
5404        if (specialProp) {
5405          specialProp(this, target, p, endValue, tween) && (hasPriority = 1);
5406        } else if (p.substr(0, 2) === "--") {
5407          startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim();
5408          endValue += "";
5409          _colorExp.lastIndex = 0;
5410
5411          if (!_colorExp.test(startValue)) {
5412            startUnit = getUnit(startValue);
5413            endUnit = getUnit(endValue);
5414          }
5415
5416          endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit);
5417          this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p);
5418          props.push(p);
5419          inlineProps.push(p, 0, style[p]);
5420        } else if (type !== "undefined") {
5421          if (startAt && p in startAt) {
5422            startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p];
5423            _isString(startValue) && ~startValue.indexOf("random(") && (startValue = _replaceRandom(startValue));
5424            getUnit(startValue + "") || startValue === "auto" || (startValue += _config.units[p] || getUnit(_get(target, p)) || "");
5425            (startValue + "").charAt(1) === "=" && (startValue = _get(target, p));
5426          } else {
5427            startValue = _get(target, p);
5428          }
5429
5430          startNum = parseFloat(startValue);
5431          relative = type === "string" && endValue.charAt(1) === "=" && endValue.substr(0, 2);
5432          relative && (endValue = endValue.substr(2));
5433          endNum = parseFloat(endValue);
5434
5435          if (p in _propertyAliases) {
5436            if (p === "autoAlpha") {
5437              if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) {
5438                startNum = 0;
5439              }
5440
5441              inlineProps.push("visibility", 0, style.visibility);
5442
5443              _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum);
5444            }
5445
5446            if (p !== "scale" && p !== "transform") {
5447              p = _propertyAliases[p];
5448              ~p.indexOf(",") && (p = p.split(",")[0]);
5449            }
5450          }
5451
5452          isTransformRelated = p in _transformProps;
5453
5454          if (isTransformRelated) {
5455            this.styles.save(p);
5456
5457            if (!transformPropTween) {
5458              cache = target._gsap;
5459              cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform);
5460              smooth = vars.smoothOrigin !== false && cache.smooth;
5461              transformPropTween = this._pt = new PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1);
5462              transformPropTween.dep = 1;
5463            }
5464
5465            if (p === "scale") {
5466              this._pt = new PropTween(this._pt, cache, "scaleY", cache.scaleY, (relative ? _parseRelative(cache.scaleY, relative + endNum) : endNum) - cache.scaleY || 0, _renderCSSProp);
5467              this._pt.u = 0;
5468              props.push("scaleY", p);
5469              p += "X";
5470            } else if (p === "transformOrigin") {
5471              inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]);
5472              endValue = _convertKeywordsToPercentages(endValue);
5473
5474              if (cache.svg) {
5475                _applySVGOrigin(target, endValue, 0, smooth, 0, this);
5476              } else {
5477                endUnit = parseFloat(endValue.split(" ")[2]) || 0;
5478                endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit);
5479
5480                _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue));
5481              }
5482
5483              continue;
5484            } else if (p === "svgOrigin") {
5485              _applySVGOrigin(target, endValue, 1, smooth, 0, this);
5486
5487              continue;
5488            } else if (p in _rotationalProperties) {
5489              _addRotationalPropTween(this, cache, p, startNum, relative ? _parseRelative(startNum, relative + endValue) : endValue);
5490
5491              continue;
5492            } else if (p === "smoothOrigin") {
5493              _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue);
5494
5495              continue;
5496            } else if (p === "force3D") {
5497              cache[p] = endValue;
5498              continue;
5499            } else if (p === "transform") {
5500              _addRawTransformPTs(this, endValue, target);
5501
5502              continue;
5503            }
5504          } else if (!(p in style)) {
5505            p = _checkPropPrefix(p) || p;
5506          }
5507
5508          if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) {
5509            startUnit = (startValue + "").substr((startNum + "").length);
5510            endNum || (endNum = 0);
5511            endUnit = getUnit(endValue) || (p in _config.units ? _config.units[p] : startUnit);
5512            startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit));
5513            this._pt = new PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, (relative ? _parseRelative(startNum, relative + endNum) : endNum) - startNum, !isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp);
5514            this._pt.u = endUnit || 0;
5515
5516            if (startUnit !== endUnit && endUnit !== "%") {
5517              this._pt.b = startValue;
5518              this._pt.r = _renderCSSPropWithBeginning;
5519            }
5520          } else if (!(p in style)) {
5521            if (p in target) {
5522              this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets);
5523            } else if (p !== "parseTransform") {
5524              _missingPlugin(p, endValue);
5525
5526              continue;
5527            }
5528          } else {
5529            _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue);
5530          }
5531
5532          isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : inlineProps.push(p, 1, startValue || target[p]));
5533          props.push(p);
5534        }
5535      }
5536
5537      hasPriority && _sortPropTweensByPriority(this);
5538    },
5539    render: function render(ratio, data) {
5540      if (data.tween._time || !_reverting$1()) {
5541        var pt = data._pt;
5542
5543        while (pt) {
5544          pt.r(ratio, pt.d);
5545          pt = pt._next;
5546        }
5547      } else {
5548        data.styles.revert();
5549      }
5550    },
5551    get: _get,
5552    aliases: _propertyAliases,
5553    getSetter: function getSetter(target, property, plugin) {
5554      var p = _propertyAliases[property];
5555      p && p.indexOf(",") < 0 && (property = p);
5556      return property in _transformProps && property !== _transformOriginProp && (target._gsap.x || _get(target, "x")) ? plugin && _recentSetterPlugin === plugin ? property === "scale" ? _setterScale : _setterTransform : (_recentSetterPlugin = plugin || {}) && (property === "scale" ? _setterScaleWithRender : _setterTransformWithRender) : target.style && !_isUndefined(target.style[property]) ? _setterCSSStyle : ~property.indexOf("-") ? _setterCSSProp : _getSetter(target, property);
5557    },
5558    core: {
5559      _removeProperty: _removeProperty,
5560      _getMatrix: _getMatrix
5561    }
5562  };
5563  gsap.utils.checkPrefix = _checkPropPrefix;
5564  gsap.core.getStyleSaver = _getStyleSaver;
5565
5566  (function (positionAndScale, rotation, others, aliases) {
5567    var all = _forEachName(positionAndScale + "," + rotation + "," + others, function (name) {
5568      _transformProps[name] = 1;
5569    });
5570
5571    _forEachName(rotation, function (name) {
5572      _config.units[name] = "deg";
5573      _rotationalProperties[name] = 1;
5574    });
5575
5576    _propertyAliases[all[13]] = positionAndScale + "," + rotation;
5577
5578    _forEachName(aliases, function (name) {
5579      var split = name.split(":");
5580      _propertyAliases[split[1]] = all[split[0]];
5581    });
5582  })("x,y,z,scale,scaleX,scaleY,xPercent,yPercent", "rotation,rotationX,rotationY,skewX,skewY", "transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective", "0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY");
5583
5584  _forEachName("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) {
5585    _config.units[name] = "px";
5586  });
5587
5588  gsap.registerPlugin(CSSPlugin);
5589
5590  var gsapWithCSS = gsap.registerPlugin(CSSPlugin) || gsap,
5591      TweenMaxWithCSS = gsapWithCSS.core.Tween;
5592
5593  exports.Back = Back;
5594  exports.Bounce = Bounce;
5595  exports.CSSPlugin = CSSPlugin;
5596  exports.Circ = Circ;
5597  exports.Cubic = Cubic;
5598  exports.Elastic = Elastic;
5599  exports.Expo = Expo;
5600  exports.Linear = Linear;
5601  exports.Power0 = Power0;
5602  exports.Power1 = Power1;
5603  exports.Power2 = Power2;
5604  exports.Power3 = Power3;
5605  exports.Power4 = Power4;
5606  exports.Quad = Quad;
5607  exports.Quart = Quart;
5608  exports.Quint = Quint;
5609  exports.Sine = Sine;
5610  exports.SteppedEase = SteppedEase;
5611  exports.Strong = Strong;
5612  exports.TimelineLite = Timeline;
5613  exports.TimelineMax = Timeline;
5614  exports.TweenLite = Tween;
5615  exports.TweenMax = TweenMaxWithCSS;
5616  exports.default = gsapWithCSS;
5617  exports.gsap = gsapWithCSS;
5618
5619  if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;}
5620
5621})));
5622"use strict";
5623
5624function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5625function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
5626function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
5627function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
5628function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
5629function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
5630(function (global, factory) {
5631  (typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Lenis = factory());
5632})(void 0, function () {
5633  'use strict';
5634
5635  var version = "1.1.9";
5636
5637  // Clamp a value between a minimum and maximum value
5638  function clamp(min, input, max) {
5639    return Math.max(min, Math.min(input, max));
5640  }
5641
5642  // Linearly interpolate between two values using an amount (0 <= t <= 1)
5643  function lerp(x, y, t) {
5644    return (1 - t) * x + t * y;
5645  }
5646
5647  // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
5648  function damp(x, y, lambda, dt) {
5649    return lerp(x, y, 1 - Math.exp(-lambda * dt));
5650  }
5651
5652  // Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor
5653  // https://anguscroll.com/just/just-modulo
5654  function modulo(n, d) {
5655    return (n % d + d) % d;
5656  }
5657  var Animate = /*#__PURE__*/function () {
5658    function Animate() {
5659      _classCallCheck(this, Animate);
5660      this.isRunning = false;
5661      this.value = 0;
5662      this.from = 0;
5663      this.to = 0;
5664      this.duration = 0;
5665      this.currentTime = 0;
5666    }
5667    _createClass(Animate, [{
5668      key: "advance",
5669      value: function advance(deltaTime) {
5670        var _a;
5671        if (!this.isRunning) return;
5672        var completed = false;
5673        if (this.duration && this.easing) {
5674          this.currentTime += deltaTime;
5675          var linearProgress = clamp(0, this.currentTime / this.duration, 1);
5676          completed = linearProgress >= 1;
5677          var easedProgress = completed ? 1 : this.easing(linearProgress);
5678          this.value = this.from + (this.to - this.from) * easedProgress;
5679        } else if (this.lerp) {
5680          this.value = damp(this.value, this.to, this.lerp * 60, deltaTime);
5681          if (Math.round(this.value) === this.to) {
5682            this.value = this.to;
5683            completed = true;
5684          }
5685        } else {
5686          this.value = this.to;
5687          completed = true;
5688        }
5689        if (completed) {
5690          this.stop();
5691        }
5692        (_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.call(this, this.value, completed);
5693      }
5694    }, {
5695      key: "stop",
5696      value: function stop() {
5697        this.isRunning = false;
5698      }
5699    }, {
5700      key: "fromTo",
5701      value: function fromTo(from, to, _ref) {
5702        var lerp = _ref.lerp,
5703          duration = _ref.duration,
5704          easing = _ref.easing,
5705          onStart = _ref.onStart,
5706          onUpdate = _ref.onUpdate;
5707        this.from = this.value = from;
5708        this.to = to;
5709        this.lerp = lerp;
5710        this.duration = duration;
5711        this.easing = easing;
5712        this.currentTime = 0;
5713        this.isRunning = true;
5714        onStart === null || onStart === void 0 ? void 0 : onStart();
5715        this.onUpdate = onUpdate;
5716      }
5717    }]);
5718    return Animate;
5719  }();
5720  function debounce(callback, delay) {
5721    var timer;
5722    return function () {
5723      var args = arguments;
5724      var context = this;
5725      clearTimeout(timer);
5726      timer = setTimeout(function () {
5727        callback.apply(context, args);
5728      }, delay);
5729    };
5730  }
5731  var Dimensions = /*#__PURE__*/function () {
5732    function Dimensions() {
5733      var _this = this;
5734      var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
5735        wrapper = _ref2.wrapper,
5736        content = _ref2.content,
5737        _ref2$autoResize = _ref2.autoResize,
5738        autoResize = _ref2$autoResize === void 0 ? true : _ref2$autoResize,
5739        _ref2$debounce = _ref2.debounce,
5740        debounceValue = _ref2$debounce === void 0 ? 250 : _ref2$debounce;
5741      _classCallCheck(this, Dimensions);
5742      this.width = 0;
5743      this.height = 0;
5744      this.scrollWidth = 0;
5745      this.scrollHeight = 0;
5746      this.resize = function () {
5747        _this.onWrapperResize();
5748        _this.onContentResize();
5749      };
5750      this.onWrapperResize = function () {
5751        if (_this.wrapper === window) {
5752          _this.width = window.innerWidth;
5753          _this.height = window.innerHeight;
5754        } else if (_this.wrapper instanceof HTMLElement) {
5755          _this.width = _this.wrapper.clientWidth;
5756          _this.height = _this.wrapper.clientHeight;
5757        }
5758      };
5759      this.onContentResize = function () {
5760        if (_this.wrapper === window) {
5761          _this.scrollHeight = _this.content.scrollHeight;
5762          _this.scrollWidth = _this.content.scrollWidth;
5763        } else if (_this.wrapper instanceof HTMLElement) {
5764          _this.scrollHeight = _this.wrapper.scrollHeight;
5765          _this.scrollWidth = _this.wrapper.scrollWidth;
5766        }
5767      };
5768      this.wrapper = wrapper;
5769      this.content = content;
5770      if (autoResize) {
5771        this.debouncedResize = debounce(this.resize, debounceValue);
5772        if (this.wrapper === window) {
5773          window.addEventListener('resize', this.debouncedResize, false);
5774        } else {
5775          this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize);
5776          this.wrapperResizeObserver.observe(this.wrapper);
5777        }
5778        this.contentResizeObserver = new ResizeObserver(this.debouncedResize);
5779        this.contentResizeObserver.observe(this.content);
5780      }
5781      this.resize();
5782    }
5783    _createClass(Dimensions, [{
5784      key: "destroy",
5785      value: function destroy() {
5786        var _a, _b;
5787        (_a = this.wrapperResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
5788        (_b = this.contentResizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
5789        window.removeEventListener('resize', this.debouncedResize, false);
5790      }
5791    }, {
5792      key: "limit",
5793      get: function get() {
5794        return {
5795          x: this.scrollWidth - this.width,
5796          y: this.scrollHeight - this.height
5797        };
5798      }
5799    }]);
5800    return Dimensions;
5801  }();
5802  var Emitter = /*#__PURE__*/function () {
5803    function Emitter() {
5804      _classCallCheck(this, Emitter);
5805      this.events = {};
5806    }
5807    _createClass(Emitter, [{
5808      key: "emit",
5809      value: function emit(event) {
5810        var callbacks = this.events[event] || [];
5811        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
5812          args[_key - 1] = arguments[_key];
5813        }
5814        for (var i = 0, length = callbacks.length; i < length; i++) {
5815          callbacks[i].apply(callbacks, args);
5816        }
5817      }
5818    }, {
5819      key: "on",
5820      value: function on(event, callback) {
5821        var _this2 = this;
5822        var _a;
5823        ((_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.push(callback)) || (this.events[event] = [callback]);
5824        return function () {
5825          var _a;
5826          _this2.events[event] = (_a = _this2.events[event]) === null || _a === void 0 ? void 0 : _a.filter(function (i) {
5827            return callback !== i;
5828          });
5829        };
5830      }
5831    }, {
5832      key: "off",
5833      value: function off(event, callback) {
5834        var _a;
5835        this.events[event] = (_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.filter(function (i) {
5836          return callback !== i;
5837        });
5838      }
5839    }, {
5840      key: "destroy",
5841      value: function destroy() {
5842        this.events = {};
5843      }
5844    }]);
5845    return Emitter;
5846  }();
5847  var LINE_HEIGHT = 100 / 6;
5848  var VirtualScroll = /*#__PURE__*/function () {
5849    function VirtualScroll(element, _ref3) {
5850      var _this3 = this;
5851      var _ref3$wheelMultiplier = _ref3.wheelMultiplier,
5852        wheelMultiplier = _ref3$wheelMultiplier === void 0 ? 1 : _ref3$wheelMultiplier,
5853        _ref3$touchMultiplier = _ref3.touchMultiplier,
5854        touchMultiplier = _ref3$touchMultiplier === void 0 ? 1 : _ref3$touchMultiplier;
5855      _classCallCheck(this, VirtualScroll);
5856      this.lastDelta = {
5857        x: 0,
5858        y: 0
5859      };
5860      this.windowWidth = 0;
5861      this.windowHeight = 0;
5862      this.onTouchStart = function (event) {
5863        var _ref4 = event.targetTouches ? event.targetTouches[0] : event,
5864          clientX = _ref4.clientX,
5865          clientY = _ref4.clientY;
5866        _this3.touchStart.x = clientX;
5867        _this3.touchStart.y = clientY;
5868        _this3.lastDelta = {
5869          x: 0,
5870          y: 0
5871        };
5872        _this3.emitter.emit('scroll', {
5873          deltaX: 0,
5874          deltaY: 0,
5875          event: event
5876        });
5877      };
5878      this.onTouchMove = function (event) {
5879        var _a, _b, _c, _d;
5880        var _ref5 = event.targetTouches ? event.targetTouches[0] : event,
5881          clientX = _ref5.clientX,
5882          clientY = _ref5.clientY;
5883        var deltaX = -(clientX - ((_b = (_a = _this3.touchStart) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0)) * _this3.touchMultiplier;
5884        var deltaY = -(clientY - ((_d = (_c = _this3.touchStart) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0)) * _this3.touchMultiplier;
5885        _this3.touchStart.x = clientX;
5886        _this3.touchStart.y = clientY;
5887        _this3.lastDelta = {
5888          x: deltaX,
5889          y: deltaY
5890        };
5891        _this3.emitter.emit('scroll', {
5892          deltaX: deltaX,
5893          deltaY: deltaY,
5894          event: event
5895        });
5896      };
5897      this.onTouchEnd = function (event) {
5898        _this3.emitter.emit('scroll', {
5899          deltaX: _this3.lastDelta.x,
5900          deltaY: _this3.lastDelta.y,
5901          event: event
5902        });
5903      };
5904      this.onWheel = function (event) {
5905        var deltaX = event.deltaX,
5906          deltaY = event.deltaY,
5907          deltaMode = event.deltaMode;
5908        var multiplierX = deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? _this3.windowWidth : 1;
5909        var multiplierY = deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? _this3.windowHeight : 1;
5910        deltaX *= multiplierX;
5911        deltaY *= multiplierY;
5912        deltaX *= _this3.wheelMultiplier;
5913        deltaY *= _this3.wheelMultiplier;
5914        _this3.emitter.emit('scroll', {
5915          deltaX: deltaX,
5916          deltaY: deltaY,
5917          event: event
5918        });
5919      };
5920      this.onWindowResize = function () {
5921        _this3.windowWidth = window.innerWidth;
5922        _this3.windowHeight = window.innerHeight;
5923      };
5924      this.element = element;
5925      this.wheelMultiplier = wheelMultiplier;
5926      this.touchMultiplier = touchMultiplier;
5927      this.touchStart = {
5928        x: null,
5929        y: null
5930      };
5931      this.emitter = new Emitter();
5932      window.addEventListener('resize', this.onWindowResize, false);
5933      this.onWindowResize();
5934      this.element.addEventListener('wheel', this.onWheel, {
5935        passive: false
5936      });
5937      this.element.addEventListener('touchstart', this.onTouchStart, {
5938        passive: false
5939      });
5940      this.element.addEventListener('touchmove', this.onTouchMove, {
5941        passive: false
5942      });
5943      this.element.addEventListener('touchend', this.onTouchEnd, {
5944        passive: false
5945      });
5946    }
5947    _createClass(VirtualScroll, [{
5948      key: "on",
5949      value: function on(event, callback) {
5950        return this.emitter.on(event, callback);
5951      }
5952    }, {
5953      key: "destroy",
5954      value: function destroy() {
5955        this.emitter.destroy();
5956        window.removeEventListener('resize', this.onWindowResize, false);
5957        this.element.removeEventListener('wheel', this.onWheel);
5958        this.element.removeEventListener('touchstart', this.onTouchStart);
5959        this.element.removeEventListener('touchmove', this.onTouchMove);
5960        this.element.removeEventListener('touchend', this.onTouchEnd);
5961      }
5962    }]);
5963    return VirtualScroll;
5964  }();
5965  var Lenis = /*#__PURE__*/function () {
5966    function Lenis() {
5967      var _this4 = this;
5968      var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
5969        _ref6$wrapper = _ref6.wrapper,
5970        wrapper = _ref6$wrapper === void 0 ? window : _ref6$wrapper,
5971        _ref6$content = _ref6.content,
5972        content = _ref6$content === void 0 ? document.documentElement : _ref6$content,
5973        _ref6$wheelEventsTarg = _ref6.wheelEventsTarget,
5974        wheelEventsTarget = _ref6$wheelEventsTarg === void 0 ? wrapper : _ref6$wheelEventsTarg,
5975        _ref6$eventsTarget = _ref6.eventsTarget,
5976        eventsTarget = _ref6$eventsTarget === void 0 ? wheelEventsTarget : _ref6$eventsTarget,
5977        _ref6$smoothWheel = _ref6.smoothWheel,
5978        smoothWheel = _ref6$smoothWheel === void 0 ? true : _ref6$smoothWheel,
5979        _ref6$syncTouch = _ref6.syncTouch,
5980        syncTouch = _ref6$syncTouch === void 0 ? false : _ref6$syncTouch,
5981        _ref6$syncTouchLerp = _ref6.syncTouchLerp,
5982        syncTouchLerp = _ref6$syncTouchLerp === void 0 ? 0.075 : _ref6$syncTouchLerp,
5983        _ref6$touchInertiaMul = _ref6.touchInertiaMultiplier,
5984        touchInertiaMultiplier = _ref6$touchInertiaMul === void 0 ? 35 : _ref6$touchInertiaMul,
5985        duration = _ref6.duration,
5986        _ref6$easing = _ref6.easing,
5987        easing = _ref6$easing === void 0 ? function (t) {
5988          return Math.min(1, 1.001 - Math.pow(2, -10 * t));
5989        } : _ref6$easing,
5990        _ref6$lerp = _ref6.lerp,
5991        lerp = _ref6$lerp === void 0 ? 0.1 : _ref6$lerp,
5992        _ref6$infinite = _ref6.infinite,
5993        infinite = _ref6$infinite === void 0 ? false : _ref6$infinite,
5994        _ref6$orientation = _ref6.orientation,
5995        orientation = _ref6$orientation === void 0 ? 'vertical' : _ref6$orientation,
5996        _ref6$gestureOrientat = _ref6.gestureOrientation,
5997        gestureOrientation = _ref6$gestureOrientat === void 0 ? 'vertical' : _ref6$gestureOrientat,
5998        _ref6$touchMultiplier = _ref6.touchMultiplier,
5999        touchMultiplier = _ref6$touchMultiplier === void 0 ? 1 : _ref6$touchMultiplier,
6000        _ref6$wheelMultiplier = _ref6.wheelMultiplier,
6001        wheelMultiplier = _ref6$wheelMultiplier === void 0 ? 1 : _ref6$wheelMultiplier,
6002        _ref6$autoResize = _ref6.autoResize,
6003        autoResize = _ref6$autoResize === void 0 ? true : _ref6$autoResize,
6004        prevent = _ref6.prevent,
6005        virtualScroll = _ref6.virtualScroll,
6006        _ref6$__experimental_ = _ref6.__experimental__naiveDimensions,
6007        __experimental__naiveDimensions = _ref6$__experimental_ === void 0 ? false : _ref6$__experimental_;
6008      _classCallCheck(this, Lenis);
6009      this.__isScrolling = false;
6010      this.__isStopped = false;
6011      this.__isLocked = false;
6012      this.userData = {};
6013      this.lastVelocity = 0;
6014      this.velocity = 0;
6015      this.direction = 0;
6016      this.onPointerDown = function (event) {
6017        if (event.button === 1) {
6018          _this4.reset();
6019        }
6020      };
6021      this.onVirtualScroll = function (data) {
6022        if (typeof _this4.options.virtualScroll === 'function' && _this4.options.virtualScroll(data) === false) return;
6023        var deltaX = data.deltaX,
6024          deltaY = data.deltaY,
6025          event = data.event;
6026        _this4.emitter.emit('virtual-scroll', {
6027          deltaX: deltaX,
6028          deltaY: deltaY,
6029          event: event
6030        });
6031        if (event.ctrlKey) return;
6032        var isTouch = event.type.includes('touch');
6033        var isWheel = event.type.includes('wheel');
6034        _this4.isTouching = event.type === 'touchstart' || event.type === 'touchmove';
6035        var isTapToStop = _this4.options.syncTouch && isTouch && event.type === 'touchstart' && !_this4.isStopped && !_this4.isLocked;
6036        if (isTapToStop) {
6037          _this4.reset();
6038          return;
6039        }
6040        var isClick = deltaX === 0 && deltaY === 0;
6041        var isUnknownGesture = _this4.options.gestureOrientation === 'vertical' && deltaY === 0 || _this4.options.gestureOrientation === 'horizontal' && deltaX === 0;
6042        if (isClick || isUnknownGesture) {
6043          return;
6044        }
6045        var composedPath = event.composedPath();
6046        composedPath = composedPath.slice(0, composedPath.indexOf(_this4.rootElement));
6047        var prevent = _this4.options.prevent;
6048        if (!!composedPath.find(function (node) {
6049          var _a, _b, _c, _d, _e;
6050          return node instanceof Element && (typeof prevent === 'function' && (prevent === null || prevent === void 0 ? void 0 : prevent(node)) || ((_a = node.hasAttribute) === null || _a === void 0 ? void 0 : _a.call(node, 'data-lenis-prevent')) || isTouch && ((_b = node.hasAttribute) === null || _b === void 0 ? void 0 : _b.call(node, 'data-lenis-prevent-touch')) || isWheel && ((_c = node.hasAttribute) === null || _c === void 0 ? void 0 : _c.call(node, 'data-lenis-prevent-wheel')) || ((_d = node.classList) === null || _d === void 0 ? void 0 : _d.contains('lenis')) && !((_e = node.classList) === null || _e === void 0 ? void 0 : _e.contains('lenis-stopped')));
6051        })) return;
6052        if (_this4.isStopped || _this4.isLocked) {
6053          event.preventDefault();
6054          return;
6055        }
6056        var isSmooth = _this4.options.syncTouch && isTouch || _this4.options.smoothWheel && isWheel;
6057        if (!isSmooth) {
6058          _this4.isScrolling = 'native';
6059          _this4.animate.stop();
6060          return;
6061        }
6062        event.preventDefault();
6063        var delta = deltaY;
6064        if (_this4.options.gestureOrientation === 'both') {
6065          delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX;
6066        } else if (_this4.options.gestureOrientation === 'horizontal') {
6067          delta = deltaX;
6068        }
6069        var syncTouch = isTouch && _this4.options.syncTouch;
6070        var isTouchEnd = isTouch && event.type === 'touchend';
6071        var hasTouchInertia = isTouchEnd && Math.abs(delta) > 5;
6072        if (hasTouchInertia) {
6073          delta = _this4.velocity * _this4.options.touchInertiaMultiplier;
6074        }
6075        _this4.scrollTo(_this4.targetScroll + delta, Object.assign({
6076          programmatic: false
6077        }, syncTouch ? {
6078          lerp: hasTouchInertia ? _this4.options.syncTouchLerp : 1
6079        } : {
6080          lerp: _this4.options.lerp,
6081          duration: _this4.options.duration,
6082          easing: _this4.options.easing
6083        }));
6084      };
6085      this.onNativeScroll = function () {
6086        clearTimeout(_this4.__resetVelocityTimeout);
6087        delete _this4.__resetVelocityTimeout;
6088        if (_this4.__preventNextNativeScrollEvent) {
6089          delete _this4.__preventNextNativeScrollEvent;
6090          return;
6091        }
6092        if (_this4.isScrolling === false || _this4.isScrolling === 'native') {
6093          var lastScroll = _this4.animatedScroll;
6094          _this4.animatedScroll = _this4.targetScroll = _this4.actualScroll;
6095          _this4.lastVelocity = _this4.velocity;
6096          _this4.velocity = _this4.animatedScroll - lastScroll;
6097          _this4.direction = Math.sign(_this4.animatedScroll - lastScroll);
6098          _this4.isScrolling = 'native';
6099          _this4.emit();
6100          if (_this4.velocity !== 0) {
6101            _this4.__resetVelocityTimeout = setTimeout(function () {
6102              _this4.lastVelocity = _this4.velocity;
6103              _this4.velocity = 0;
6104              _this4.isScrolling = false;
6105              _this4.emit();
6106            }, 400);
6107          }
6108        }
6109      };
6110      window.lenisVersion = version;
6111      if (!wrapper || wrapper === document.documentElement || wrapper === document.body) {
6112        wrapper = window;
6113      }
6114      this.options = {
6115        wrapper: wrapper,
6116        content: content,
6117        wheelEventsTarget: wheelEventsTarget,
6118        eventsTarget: eventsTarget,
6119        smoothWheel: smoothWheel,
6120        syncTouch: syncTouch,
6121        syncTouchLerp: syncTouchLerp,
6122        touchInertiaMultiplier: touchInertiaMultiplier,
6123        duration: duration,
6124        easing: easing,
6125        lerp: lerp,
6126        infinite: infinite,
6127        gestureOrientation: gestureOrientation,
6128        orientation: orientation,
6129        touchMultiplier: touchMultiplier,
6130        wheelMultiplier: wheelMultiplier,
6131        autoResize: autoResize,
6132        prevent: prevent,
6133        virtualScroll: virtualScroll,
6134        __experimental__naiveDimensions: __experimental__naiveDimensions
6135      };
6136      this.animate = new Animate();
6137      this.emitter = new Emitter();
6138      this.dimensions = new Dimensions({
6139        wrapper: wrapper,
6140        content: content,
6141        autoResize: autoResize
6142      });
6143      this.updateClassName();
6144      this.userData = {};
6145      this.time = 0;
6146      this.velocity = this.lastVelocity = 0;
6147      this.isLocked = false;
6148      this.isStopped = false;
6149      this.isScrolling = false;
6150      this.targetScroll = this.animatedScroll = this.actualScroll;
6151      this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false);
6152      this.options.wrapper.addEventListener('pointerdown', this.onPointerDown, false);
6153      this.virtualScroll = new VirtualScroll(eventsTarget, {
6154        touchMultiplier: touchMultiplier,
6155        wheelMultiplier: wheelMultiplier
6156      });
6157      this.virtualScroll.on('scroll', this.onVirtualScroll);
6158    }
6159    _createClass(Lenis, [{
6160      key: "destroy",
6161      value: function destroy() {
6162        this.emitter.destroy();
6163        this.options.wrapper.removeEventListener('scroll', this.onNativeScroll, false);
6164        this.options.wrapper.removeEventListener('pointerdown', this.onPointerDown, false);
6165        this.virtualScroll.destroy();
6166        this.dimensions.destroy();
6167        this.cleanUpClassName();
6168      }
6169    }, {
6170      key: "on",
6171      value: function on(event, callback) {
6172        return this.emitter.on(event, callback);
6173      }
6174    }, {
6175      key: "off",
6176      value: function off(event, callback) {
6177        return this.emitter.off(event, callback);
6178      }
6179    }, {
6180      key: "setScroll",
6181      value: function setScroll(scroll) {
6182        if (this.isHorizontal) {
6183          this.rootElement.scrollLeft = scroll;
6184        } else {
6185          this.rootElement.scrollTop = scroll;
6186        }
6187      }
6188    }, {
6189      key: "resize",
6190      value: function resize() {
6191        this.dimensions.resize();
6192      }
6193    }, {
6194      key: "emit",
6195      value: function emit() {
6196        this.emitter.emit('scroll', this);
6197      }
6198    }, {
6199      key: "reset",
6200      value: function reset() {
6201        this.isLocked = false;
6202        this.isScrolling = false;
6203        this.animatedScroll = this.targetScroll = this.actualScroll;
6204        this.lastVelocity = this.velocity = 0;
6205        this.animate.stop();
6206      }
6207    }, {
6208      key: "start",
6209      value: function start() {
6210        if (!this.isStopped) return;
6211        this.isStopped = false;
6212        this.reset();
6213      }
6214    }, {
6215      key: "stop",
6216      value: function stop() {
6217        if (this.isStopped) return;
6218        this.isStopped = true;
6219        this.animate.stop();
6220        this.reset();
6221      }
6222    }, {
6223      key: "raf",
6224      value: function raf(time) {
6225        var deltaTime = time - (this.time || time);
6226        this.time = time;
6227        this.animate.advance(deltaTime * 0.001);
6228      }
6229    }, {
6230      key: "scrollTo",
6231      value: function scrollTo(target) {
6232        var _this5 = this;
6233        var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
6234          _ref7$offset = _ref7.offset,
6235          offset = _ref7$offset === void 0 ? 0 : _ref7$offset,
6236          _ref7$immediate = _ref7.immediate,
6237          immediate = _ref7$immediate === void 0 ? false : _ref7$immediate,
6238          _ref7$lock = _ref7.lock,
6239          lock = _ref7$lock === void 0 ? false : _ref7$lock,
6240          _ref7$duration = _ref7.duration,
6241          duration = _ref7$duration === void 0 ? this.options.duration : _ref7$duration,
6242          _ref7$easing = _ref7.easing,
6243          easing = _ref7$easing === void 0 ? this.options.easing : _ref7$easing,
6244          _ref7$lerp = _ref7.lerp,
6245          lerp = _ref7$lerp === void 0 ? this.options.lerp : _ref7$lerp,
6246          _onStart = _ref7.onStart,
6247          onComplete = _ref7.onComplete,
6248          _ref7$force = _ref7.force,
6249          force = _ref7$force === void 0 ? false : _ref7$force,
6250          _ref7$programmatic = _ref7.programmatic,
6251          programmatic = _ref7$programmatic === void 0 ? true : _ref7$programmatic,
6252          _ref7$userData = _ref7.userData,
6253          userData = _ref7$userData === void 0 ? {} : _ref7$userData;
6254        if ((this.isStopped || this.isLocked) && !force) return;
6255        if (typeof target === 'string' && ['top', 'left', 'start'].includes(target)) {
6256          target = 0;
6257        } else if (typeof target === 'string' && ['bottom', 'right', 'end'].includes(target)) {
6258          target = this.limit;
6259        } else {
6260          var node;
6261          if (typeof target === 'string') {
6262            node = document.querySelector(target);
6263          } else if (target instanceof HTMLElement && (target === null || target === void 0 ? void 0 : target.nodeType)) {
6264            node = target;
6265          }
6266          if (node) {
6267            if (this.options.wrapper !== window) {
6268              var wrapperRect = this.rootElement.getBoundingClientRect();
6269              offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top;
6270            }
6271            var rect = node.getBoundingClientRect();
6272            target = (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll;
6273          }
6274        }
6275        if (typeof target !== 'number') return;
6276        target += offset;
6277        target = Math.round(target);
6278        if (this.options.infinite) {
6279          if (programmatic) {
6280            this.targetScroll = this.animatedScroll = this.scroll;
6281          }
6282        } else {
6283          target = clamp(0, target, this.limit);
6284        }
6285        if (target === this.targetScroll) return;
6286        this.userData = userData;
6287        if (immediate) {
6288          this.animatedScroll = this.targetScroll = target;
6289          this.setScroll(this.scroll);
6290          this.reset();
6291          this.preventNextNativeScrollEvent();
6292          this.emit();
6293          onComplete === null || onComplete === void 0 ? void 0 : onComplete(this);
6294          this.userData = {};
6295          return;
6296        }
6297        if (!programmatic) {
6298          this.targetScroll = target;
6299        }
6300        this.animate.fromTo(this.animatedScroll, target, {
6301          duration: duration,
6302          easing: easing,
6303          lerp: lerp,
6304          onStart: function onStart() {
6305            if (lock) _this5.isLocked = true;
6306            _this5.isScrolling = 'smooth';
6307            _onStart === null || _onStart === void 0 ? void 0 : _onStart(_this5);
6308          },
6309          onUpdate: function onUpdate(value, completed) {
6310            _this5.isScrolling = 'smooth';
6311            _this5.lastVelocity = _this5.velocity;
6312            _this5.velocity = value - _this5.animatedScroll;
6313            _this5.direction = Math.sign(_this5.velocity);
6314            _this5.animatedScroll = value;
6315            _this5.setScroll(_this5.scroll);
6316            if (programmatic) {
6317              _this5.targetScroll = value;
6318            }
6319            if (!completed) _this5.emit();
6320            if (completed) {
6321              _this5.reset();
6322              _this5.emit();
6323              onComplete === null || onComplete === void 0 ? void 0 : onComplete(_this5);
6324              _this5.userData = {};
6325              _this5.preventNextNativeScrollEvent();
6326            }
6327          }
6328        });
6329      }
6330    }, {
6331      key: "preventNextNativeScrollEvent",
6332      value: function preventNextNativeScrollEvent() {
6333        var _this6 = this;
6334        this.__preventNextNativeScrollEvent = true;
6335        requestAnimationFrame(function () {
6336          delete _this6.__preventNextNativeScrollEvent;
6337        });
6338      }
6339    }, {
6340      key: "rootElement",
6341      get: function get() {
6342        return this.options.wrapper === window ? document.documentElement : this.options.wrapper;
6343      }
6344    }, {
6345      key: "limit",
6346      get: function get() {
6347        if (this.options.__experimental__naiveDimensions) {
6348          if (this.isHorizontal) {
6349            return this.rootElement.scrollWidth - this.rootElement.clientWidth;
6350          } else {
6351            return this.rootElement.scrollHeight - this.rootElement.clientHeight;
6352          }
6353        } else {
6354          return this.dimensions.limit[this.isHorizontal ? 'x' : 'y'];
6355        }
6356      }
6357    }, {
6358      key: "isHorizontal",
6359      get: function get() {
6360        return this.options.orientation === 'horizontal';
6361      }
6362    }, {
6363      key: "actualScroll",
6364      get: function get() {
6365        return this.isHorizontal ? this.rootElement.scrollLeft : this.rootElement.scrollTop;
6366      }
6367    }, {
6368      key: "scroll",
6369      get: function get() {
6370        return this.options.infinite ? modulo(this.animatedScroll, this.limit) : this.animatedScroll;
6371      }
6372    }, {
6373      key: "progress",
6374      get: function get() {
6375        return this.limit === 0 ? 1 : this.scroll / this.limit;
6376      }
6377    }, {
6378      key: "isScrolling",
6379      get: function get() {
6380        return this.__isScrolling;
6381      },
6382      set: function set(value) {
6383        if (this.__isScrolling !== value) {
6384          this.__isScrolling = value;
6385          this.updateClassName();
6386        }
6387      }
6388    }, {
6389      key: "isStopped",
6390      get: function get() {
6391        return this.__isStopped;
6392      },
6393      set: function set(value) {
6394        if (this.__isStopped !== value) {
6395          this.__isStopped = value;
6396          this.updateClassName();
6397        }
6398      }
6399    }, {
6400      key: "isLocked",
6401      get: function get() {
6402        return this.__isLocked;
6403      },
6404      set: function set(value) {
6405        if (this.__isLocked !== value) {
6406          this.__isLocked = value;
6407          this.updateClassName();
6408        }
6409      }
6410    }, {
6411      key: "isSmooth",
6412      get: function get() {
6413        return this.isScrolling === 'smooth';
6414      }
6415    }, {
6416      key: "className",
6417      get: function get() {
6418        var className = 'lenis';
6419        if (this.isStopped) className += ' lenis-stopped';
6420        if (this.isLocked) className += ' lenis-locked';
6421        if (this.isScrolling) className += ' lenis-scrolling';
6422        if (this.isScrolling === 'smooth') className += ' lenis-smooth';
6423        return className;
6424      }
6425    }, {
6426      key: "updateClassName",
6427      value: function updateClassName() {
6428        this.cleanUpClassName();
6429        this.rootElement.className = "".concat(this.rootElement.className, " ").concat(this.className).trim();
6430      }
6431    }, {
6432      key: "cleanUpClassName",
6433      value: function cleanUpClassName() {
6434        this.rootElement.className = this.rootElement.className.replace(/lenis(-\w+)?/g, '').trim();
6435      }
6436    }]);
6437    return Lenis;
6438  }();
6439  return Lenis;
6440});
6441(function(window, $) {
6442  "use strict";
6443
6444  var counter = 0,
6445    $headCache = $('head'),
6446    oldBigText = window.BigText,
6447    oldjQueryMethod = $.fn.bigtext,
6448    BigText = {
6449      DEBUG_MODE: false,
6450      DEFAULT_MIN_FONT_SIZE_PX: null,
6451      DEFAULT_MAX_FONT_SIZE_PX: 1056,
6452      GLOBAL_STYLE_ID: 'bigtext-style',
6453      STYLE_ID: 'bigtext-id',
6454      LINE_CLASS_PREFIX: 'bigtext-line',
6455      EXEMPT_CLASS: 'bigtext-exempt',
6456      noConflict: function(restore)
6457      {
6458        if(restore) {
6459          $.fn.bigtext = oldjQueryMethod;
6460          window.BigText = oldBigText;
6461        }
6462        return BigText;
6463      },
6464      supports: {
6465        wholeNumberFontSizeOnly: (function() {
6466          if( !( 'getComputedStyle' in window ) ) {
6467            return true;
6468          }
6469          var test = $('<div/>').css({
6470              position: 'absolute',
6471              'font-size': '14.1px'
6472            }).insertBefore( $('script').eq(0) ),
6473            computedStyle = window.getComputedStyle( test[0], null );
6474
6475          var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px';
6476          test.remove();
6477          return ret;
6478        })()
6479      },
6480      init: function() {
6481        if(!$('#'+BigText.GLOBAL_STYLE_ID).length) {
6482          $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }',
6483                                          '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }']));
6484        }
6485      },
6486      bindResize: function(eventName, resizeFunction) {
6487        var timeoutId;
6488        $(window).off(eventName).on(eventName, function() {
6489          if( timeoutId ) {
6490            clearTimeout( timeoutId );
6491          }
6492          timeoutId = setTimeout( resizeFunction, 100 );
6493        });
6494      },
6495      getStyleId: function(id)
6496      {
6497        return BigText.STYLE_ID + '-' + id;
6498      },
6499      generateStyleTag: function(id, css)
6500      {
6501        return $('<style>' + css.join('\n') + '</style>').attr('id', id);
6502      },
6503      clearCss: function(id)
6504      {
6505        var styleId = BigText.getStyleId(id);
6506        $('#' + styleId).remove();
6507      },
6508      generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes)
6509      {
6510        var css = [];
6511
6512        BigText.clearCss(id);
6513
6514        for(var j=0, k=linesFontSizes.length; j<k; j++) {
6515          css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' +
6516            (minFontSizes[j] ? ' white-space: normal;' : '') +
6517            (linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') +
6518            (lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') +
6519            '}');
6520        }
6521
6522        return BigText.generateStyleTag(BigText.getStyleId(id), css);
6523      },
6524      jQueryMethod: function(options)
6525      {
6526        BigText.init();
6527
6528        options = $.extend({
6529          minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX,
6530          maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX,
6531          childSelector: '',
6532          resize: true
6533        }, options || {});
6534
6535        this.each(function()
6536        {
6537          var $t = $(this).addClass('bigtext'),
6538            maxWidth = $t.width(),
6539            id = $t.attr('id'),
6540            $children = options.childSelector ? $t.find( options.childSelector ) : $t.children();
6541
6542          if(!id) {
6543            id = 'bigtext-id' + (counter++);
6544            $t.attr('id', id);
6545          }
6546
6547          if(options.resize) {
6548            BigText.bindResize('resize.bigtext-event-' + id, function()
6549            {
6550              // TODO only call this if the width has changed.
6551              BigText.jQueryMethod.call($('#' + id), options);
6552            });
6553          }
6554
6555          BigText.clearCss(id);
6556
6557          $children.addClass(function(lineNumber, className)
6558          {
6559            // remove existing line classes.
6560            return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''),
6561                BigText.LINE_CLASS_PREFIX + lineNumber].join(' ');
6562          });
6563
6564          var sizes = BigText.calculateSizes($t, $children, maxWidth, options.maxfontsize, options.minfontsize);
6565          $headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes));
6566        });
6567
6568        return this.trigger('bigtext:complete');
6569      },
6570      testLineDimensions: function($line, maxWidth, property, size, interval, units, previousWidth)
6571      {
6572        var width;
6573        previousWidth = typeof previousWidth === 'number' ? previousWidth : 0;
6574        $line.css(property, size + units);
6575
6576        width = $line.width();
6577
6578        if(width >= maxWidth) {
6579    // console.log(width, ' previous: ' + previousWidth, property + ' at ' + interval, 'prior: ' + (parseFloat(size) - interval), 'new:' + parseFloat(size));
6580          $line.css(property, '');
6581
6582          if(width === maxWidth) {
6583            return {
6584              match: 'exact',
6585              size: parseFloat((parseFloat(size) - 0.1).toFixed(3))
6586            };
6587          }
6588
6589          // Since this is an estimate, we calculate how far over the width we went with the new value.
6590          // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value.
6591          // Otherwise, we revert to the underestimate.
6592          var under = maxWidth - previousWidth,
6593            over = width - maxWidth;
6594
6595          return {
6596            match: 'estimate',
6597            size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3))
6598          };
6599        }
6600
6601        return width;
6602      },
6603      calculateSizes: function($t, $children, maxWidth, maxFontSize, minFontSize)
6604      {
6605        var $c = $t.clone(true)
6606          .addClass('bigtext-cloned')
6607          .css({
6608            fontFamily: $t.css('font-family'),
6609            textTransform: $t.css('text-transform'),
6610            wordSpacing: $t.css('word-spacing'),
6611            letterSpacing: $t.css('letter-spacing'),
6612            position: 'absolute',
6613            left: BigText.DEBUG_MODE ? 0 : -9999,
6614            top: BigText.DEBUG_MODE ? 0 : -9999
6615          })
6616          .appendTo(document.body);
6617
6618        // font-size isn't the only thing we can modify, we can also mess with:
6619        // word-spacing and letter-spacing. WebKit does not respect subpixel
6620        // letter-spacing, word-spacing, or font-size.
6621        // TODO try -webkit-transform: scale() as a workaround.
6622        var fontSizes = [],
6623          wordSpacings = [],
6624          minFontSizes = [],
6625          ratios = [];
6626
6627        $children.css('float', 'left').each(function() {
6628          var $line = $(this),
6629            // TODO replace 8, 4 with a proportional size to the calculated font-size.
6630            intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1],
6631            lineMax,
6632            newFontSize;
6633
6634          if($line.hasClass(BigText.EXEMPT_CLASS)) {
6635            fontSizes.push(null);
6636            ratios.push(null);
6637            minFontSizes.push(false);
6638            return;
6639          }
6640
6641          // TODO we can cache this ratio?
6642          var autoGuessSubtraction = 32, // font size in px
6643            currentFontSize = parseFloat($line.css('font-size')),
6644            ratio = ( $line.width() / currentFontSize ).toFixed(6);
6645
6646          newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction;
6647
6648          outer: for(var m=0, n=intervals.length; m<n; m++) {
6649            inner: for(var j=1, k=10; j<=k; j++) {
6650              if(newFontSize + j*intervals[m] > maxFontSize) {
6651                newFontSize = maxFontSize;
6652                break outer;
6653              }
6654
6655              lineMax = BigText.testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax);
6656              if(typeof lineMax !== 'number') {
6657                newFontSize = lineMax.size;
6658
6659                if(lineMax.match === 'exact') {
6660                  break outer;
6661                }
6662                break inner;
6663              }
6664            }
6665          }
6666
6667          ratios.push(maxWidth / newFontSize);
6668
6669          if(newFontSize > maxFontSize) {
6670            fontSizes.push(maxFontSize);
6671            minFontSizes.push(false);
6672          } else if(!!minFontSize && newFontSize < minFontSize) {
6673            fontSizes.push(minFontSize);
6674            minFontSizes.push(true);
6675          } else {
6676            fontSizes.push(newFontSize);
6677            minFontSizes.push(false);
6678          }
6679        }).each(function(lineNumber) {
6680          var $line = $(this),
6681            wordSpacing = 0,
6682            interval = 1,
6683            maxWordSpacing;
6684
6685          if($line.hasClass(BigText.EXEMPT_CLASS)) {
6686            wordSpacings.push(null);
6687            return;
6688          }
6689
6690          // must re-use font-size, even though it was removed above.
6691          $line.css('font-size', fontSizes[lineNumber] + 'px');
6692
6693          for(var m=1, n=3; m<n; m+=interval) {
6694            maxWordSpacing = BigText.testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px', maxWordSpacing);
6695            if(typeof maxWordSpacing !== 'number') {
6696              wordSpacing = maxWordSpacing.size;
6697              break;
6698            }
6699          }
6700
6701          $line.css('font-size', '');
6702          wordSpacings.push(wordSpacing);
6703        }).removeAttr('style');
6704
6705        if( !BigText.DEBUG_MODE ) {
6706          $c.remove();
6707        } else {
6708          $c.css({
6709            'background-color': 'rgba(255,255,255,.4)'
6710          });
6711        }
6712
6713        return {
6714          fontSizes: fontSizes,
6715          wordSpacings: wordSpacings,
6716          ratios: ratios,
6717          minFontSizes: minFontSizes
6718        };
6719      }
6720    };
6721
6722  $.fn.bigtext = BigText.jQueryMethod;
6723  window.BigText = BigText;
6724
6725})(this, jQuery);
6726/*!
6727 * Isotope PACKAGED v3.0.6
6728 *
6729 * Licensed GPLv3 for open source use
6730 * or Isotope Commercial License for commercial use
6731 *
6732 * https://isotope.metafizzy.co
6733 * Copyright 2010-2018 Metafizzy
vendor: 15,902 bytes, lines 6733-7383
6733
6734 */
6735
6736/**
6737 * Bridget makes jQuery widgets
6738 * v2.0.1
6739 * MIT license
6740 */
6741
6742/* jshint browser: true, strict: true, undef: true, unused: true */
6743
6744( function( window, factory ) {
6745  // universal module definition
6746  /*jshint strict: false */ /* globals define, module, require */
6747  if ( typeof define == 'function' && define.amd ) {
6748    // AMD
6749    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
6750      return factory( window, jQuery );
6751    });
6752  } else if ( typeof module == 'object' && module.exports ) {
6753    // CommonJS
6754    module.exports = factory(
6755      window,
6756      require('jquery')
6757    );
6758  } else {
6759    // browser global
6760    window.jQueryBridget = factory(
6761      window,
6762      window.jQuery
6763    );
6764  }
6765
6766}( window, function factory( window, jQuery ) {
6767'use strict';
6768
6769// ----- utils ----- //
6770
6771var arraySlice = Array.prototype.slice;
6772
6773// helper function for logging errors
6774// $.error breaks jQuery chaining
6775var console = window.console;
6776var logError = typeof console == 'undefined' ? function() {} :
6777  function( message ) {
6778    console.error( message );
6779  };
6780
6781// ----- jQueryBridget ----- //
6782
6783function jQueryBridget( namespace, PluginClass, $ ) {
6784  $ = $ || jQuery || window.jQuery;
6785  if ( !$ ) {
6786    return;
6787  }
6788
6789  // add option method -> $().plugin('option', {...})
6790  if ( !PluginClass.prototype.option ) {
6791    // option setter
6792    PluginClass.prototype.option = function( opts ) {
6793      // bail out if not an object
6794      if ( !$.isPlainObject( opts ) ){
6795        return;
6796      }
6797      this.options = $.extend( true, this.options, opts );
6798    };
6799  }
6800
6801  // make jQuery plugin
6802  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
6803    if ( typeof arg0 == 'string' ) {
6804      // method call $().plugin( 'methodName', { options } )
6805      // shift arguments by 1
6806      var args = arraySlice.call( arguments, 1 );
6807      return methodCall( this, arg0, args );
6808    }
6809    // just $().plugin({ options })
6810    plainCall( this, arg0 );
6811    return this;
6812  };
6813
6814  // $().plugin('methodName')
6815  function methodCall( $elems, methodName, args ) {
6816    var returnValue;
6817    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
6818
6819    $elems.each( function( i, elem ) {
6820      // get instance
6821      var instance = $.data( elem, namespace );
6822      if ( !instance ) {
6823        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
6824          pluginMethodStr );
6825        return;
6826      }
6827
6828      var method = instance[ methodName ];
6829      if ( !method || methodName.charAt(0) == '_' ) {
6830        logError( pluginMethodStr + ' is not a valid method' );
6831        return;
6832      }
6833
6834      // apply method, get return value
6835      var value = method.apply( instance, args );
6836      // set return value if value is returned, use only first value
6837      returnValue = returnValue === undefined ? value : returnValue;
6838    });
6839
6840    return returnValue !== undefined ? returnValue : $elems;
6841  }
6842
6843  function plainCall( $elems, options ) {
6844    $elems.each( function( i, elem ) {
6845      var instance = $.data( elem, namespace );
6846      if ( instance ) {
6847        // set options & init
6848        instance.option( options );
6849        instance._init();
6850      } else {
6851        // initialize new instance
6852        instance = new PluginClass( elem, options );
6853        $.data( elem, namespace, instance );
6854      }
6855    });
6856  }
6857
6858  updateJQuery( $ );
6859
6860}
6861
6862// ----- updateJQuery ----- //
6863
6864// set $.bridget for v1 backwards compatibility
6865function updateJQuery( $ ) {
6866  if ( !$ || ( $ && $.bridget ) ) {
6867    return;
6868  }
6869  $.bridget = jQueryBridget;
6870}
6871
6872updateJQuery( jQuery || window.jQuery );
6873
6874// -----  ----- //
6875
6876return jQueryBridget;
6877
6878}));
6879
6880/**
6881 * EvEmitter v1.1.0
6882 * Lil' event emitter
6883 * MIT License
6884 */
6885
6886/* jshint unused: true, undef: true, strict: true */
6887
6888( function( global, factory ) {
6889  // universal module definition
6890  /* jshint strict: false */ /* globals define, module, window */
6891  if ( typeof define == 'function' && define.amd ) {
6892    // AMD - RequireJS
6893    define( 'ev-emitter/ev-emitter',factory );
6894  } else if ( typeof module == 'object' && module.exports ) {
6895    // CommonJS - Browserify, Webpack
6896    module.exports = factory();
6897  } else {
6898    // Browser globals
6899    global.EvEmitter = factory();
6900  }
6901
6902}( typeof window != 'undefined' ? window : this, function() {
6903
6904
6905
6906function EvEmitter() {}
6907
6908var proto = EvEmitter.prototype;
6909
6910proto.on = function( eventName, listener ) {
6911  if ( !eventName || !listener ) {
6912    return;
6913  }
6914  // set events hash
6915  var events = this._events = this._events || {};
6916  // set listeners array
6917  var listeners = events[ eventName ] = events[ eventName ] || [];
6918  // only add once
6919  if ( listeners.indexOf( listener ) == -1 ) {
6920    listeners.push( listener );
6921  }
6922
6923  return this;
6924};
6925
6926proto.once = function( eventName, listener ) {
6927  if ( !eventName || !listener ) {
6928    return;
6929  }
6930  // add event
6931  this.on( eventName, listener );
6932  // set once flag
6933  // set onceEvents hash
6934  var onceEvents = this._onceEvents = this._onceEvents || {};
6935  // set onceListeners object
6936  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
6937  // set flag
6938  onceListeners[ listener ] = true;
6939
6940  return this;
6941};
6942
6943proto.off = function( eventName, listener ) {
6944  var listeners = this._events && this._events[ eventName ];
6945  if ( !listeners || !listeners.length ) {
6946    return;
6947  }
6948  var index = listeners.indexOf( listener );
6949  if ( index != -1 ) {
6950    listeners.splice( index, 1 );
6951  }
6952
6953  return this;
6954};
6955
6956proto.emitEvent = function( eventName, args ) {
6957  var listeners = this._events && this._events[ eventName ];
6958  if ( !listeners || !listeners.length ) {
6959    return;
6960  }
6961  // copy over to avoid interference if .off() in listener
6962  listeners = listeners.slice(0);
6963  args = args || [];
6964  // once stuff
6965  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
6966
6967  for ( var i=0; i < listeners.length; i++ ) {
6968    var listener = listeners[i]
6969    var isOnce = onceListeners && onceListeners[ listener ];
6970    if ( isOnce ) {
6971      // remove listener
6972      // remove before trigger to prevent recursion
6973      this.off( eventName, listener );
6974      // unset once flag
6975      delete onceListeners[ listener ];
6976    }
6977    // trigger listener
6978    listener.apply( this, args );
6979  }
6980
6981  return this;
6982};
6983
6984proto.allOff = function() {
6985  delete this._events;
6986  delete this._onceEvents;
6987};
6988
6989return EvEmitter;
6990
6991}));
6992
6993/*!
6994 * getSize v2.0.3
6995 * measure size of elements
6996 * MIT license
6997 */
6998
6999/* jshint browser: true, strict: true, undef: true, unused: true */
7000/* globals console: false */
7001
7002( function( window, factory ) {
7003  /* jshint strict: false */ /* globals define, module */
7004  if ( typeof define == 'function' && define.amd ) {
7005    // AMD
7006    define( 'get-size/get-size',factory );
7007  } else if ( typeof module == 'object' && module.exports ) {
7008    // CommonJS
7009    module.exports = factory();
7010  } else {
7011    // browser global
7012    window.getSize = factory();
7013  }
7014
7015})( window, function factory() {
7016'use strict';
7017
7018// -------------------------- helpers -------------------------- //
7019
7020// get a number from a string, not a percentage
7021function getStyleSize( value ) {
7022  var num = parseFloat( value );
7023  // not a percent like '100%', and a number
7024  var isValid = value.indexOf('%') == -1 && !isNaN( num );
7025  return isValid && num;
7026}
7027
7028function noop() {}
7029
7030var logError = typeof console == 'undefined' ? noop :
7031  function( message ) {
7032    console.error( message );
7033  };
7034
7035// -------------------------- measurements -------------------------- //
7036
7037var measurements = [
7038  'paddingLeft',
7039  'paddingRight',
7040  'paddingTop',
7041  'paddingBottom',
7042  'marginLeft',
7043  'marginRight',
7044  'marginTop',
7045  'marginBottom',
7046  'borderLeftWidth',
7047  'borderRightWidth',
7048  'borderTopWidth',
7049  'borderBottomWidth'
7050];
7051
7052var measurementsLength = measurements.length;
7053
7054function getZeroSize() {
7055  var size = {
7056    width: 0,
7057    height: 0,
7058    innerWidth: 0,
7059    innerHeight: 0,
7060    outerWidth: 0,
7061    outerHeight: 0
7062  };
7063  for ( var i=0; i < measurementsLength; i++ ) {
7064    var measurement = measurements[i];
7065    size[ measurement ] = 0;
7066  }
7067  return size;
7068}
7069
7070// -------------------------- getStyle -------------------------- //
7071
7072/**
7073 * getStyle, get style of element, check for Firefox bug
7074 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
7075 */
7076function getStyle( elem ) {
7077  var style = getComputedStyle( elem );
7078  if ( !style ) {
7079    logError( 'Style returned ' + style +
7080      '. Are you running this code in a hidden iframe on Firefox? ' +
7081      'See https://bit.ly/getsizebug1' );
7082  }
7083  return style;
7084}
7085
7086// -------------------------- setup -------------------------- //
7087
7088var isSetup = false;
7089
7090var isBoxSizeOuter;
7091
7092/**
7093 * setup
7094 * check isBoxSizerOuter
7095 * do on first getSize() rather than on page load for Firefox bug
7096 */
7097function setup() {
7098  // setup once
7099  if ( isSetup ) {
7100    return;
7101  }
7102  isSetup = true;
7103
7104  // -------------------------- box sizing -------------------------- //
7105
7106  /**
7107   * Chrome & Safari measure the outer-width on style.width on border-box elems
7108   * IE11 & Firefox<29 measures the inner-width
7109   */
7110  var div = document.createElement('div');
7111  div.style.width = '200px';
7112  div.style.padding = '1px 2px 3px 4px';
7113  div.style.borderStyle = 'solid';
7114  div.style.borderWidth = '1px 2px 3px 4px';
7115  div.style.boxSizing = 'border-box';
7116
7117  var body = document.body || document.documentElement;
7118  body.appendChild( div );
7119  var style = getStyle( div );
7120  // round value for browser zoom. desandro/masonry#928
7121  isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
7122  getSize.isBoxSizeOuter = isBoxSizeOuter;
7123
7124  body.removeChild( div );
7125}
7126
7127// -------------------------- getSize -------------------------- //
7128
7129function getSize( elem ) {
7130  setup();
7131
7132  // use querySeletor if elem is string
7133  if ( typeof elem == 'string' ) {
7134    elem = document.querySelector( elem );
7135  }
7136
7137  // do not proceed on non-objects
7138  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
7139    return;
7140  }
7141
7142  var style = getStyle( elem );
7143
7144  // if hidden, everything is 0
7145  if ( style.display == 'none' ) {
7146    return getZeroSize();
7147  }
7148
7149  var size = {};
7150  size.width = elem.offsetWidth;
7151  size.height = elem.offsetHeight;
7152
7153  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
7154
7155  // get all measurements
7156  for ( var i=0; i < measurementsLength; i++ ) {
7157    var measurement = measurements[i];
7158    var value = style[ measurement ];
7159    var num = parseFloat( value );
7160    // any 'auto', 'medium' value will be 0
7161    size[ measurement ] = !isNaN( num ) ? num : 0;
7162  }
7163
7164  var paddingWidth = size.paddingLeft + size.paddingRight;
7165  var paddingHeight = size.paddingTop + size.paddingBottom;
7166  var marginWidth = size.marginLeft + size.marginRight;
7167  var marginHeight = size.marginTop + size.marginBottom;
7168  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
7169  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
7170
7171  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
7172
7173  // overwrite width and height if we can get it from style
7174  var styleWidth = getStyleSize( style.width );
7175  if ( styleWidth !== false ) {
7176    size.width = styleWidth +
7177      // add padding and border unless it's already including it
7178      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
7179  }
7180
7181  var styleHeight = getStyleSize( style.height );
7182  if ( styleHeight !== false ) {
7183    size.height = styleHeight +
7184      // add padding and border unless it's already including it
7185      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
7186  }
7187
7188  size.innerWidth = size.width - ( paddingWidth + borderWidth );
7189  size.innerHeight = size.height - ( paddingHeight + borderHeight );
7190
7191  size.outerWidth = size.width + marginWidth;
7192  size.outerHeight = size.height + marginHeight;
7193
7194  return size;
7195}
7196
7197return getSize;
7198
7199});
7200
7201/**
7202 * matchesSelector v2.0.2
7203 * matchesSelector( element, '.selector' )
7204 * MIT license
7205 */
7206
7207/*jshint browser: true, strict: true, undef: true, unused: true */
7208
7209( function( window, factory ) {
7210  /*global define: false, module: false */
7211  'use strict';
7212  // universal module definition
7213  if ( typeof define == 'function' && define.amd ) {
7214    // AMD
7215    define( 'desandro-matches-selector/matches-selector',factory );
7216  } else if ( typeof module == 'object' && module.exports ) {
7217    // CommonJS
7218    module.exports = factory();
7219  } else {
7220    // browser global
7221    window.matchesSelector = factory();
7222  }
7223
7224}( window, function factory() {
7225  'use strict';
7226
7227  var matchesMethod = ( function() {
7228    var ElemProto = window.Element.prototype;
7229    // check for the standard method name first
7230    if ( ElemProto.matches ) {
7231      return 'matches';
7232    }
7233    // check un-prefixed
7234    if ( ElemProto.matchesSelector ) {
7235      return 'matchesSelector';
7236    }
7237    // check vendor prefixes
7238    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
7239
7240    for ( var i=0; i < prefixes.length; i++ ) {
7241      var prefix = prefixes[i];
7242      var method = prefix + 'MatchesSelector';
7243      if ( ElemProto[ method ] ) {
7244        return method;
7245      }
7246    }
7247  })();
7248
7249  return function matchesSelector( elem, selector ) {
7250    return elem[ matchesMethod ]( selector );
7251  };
7252
7253}));
7254
7255/**
7256 * Fizzy UI utils v2.0.7
7257 * MIT license
7258 */
7259
7260/*jshint browser: true, undef: true, unused: true, strict: true */
7261
7262( function( window, factory ) {
7263  // universal module definition
7264  /*jshint strict: false */ /*globals define, module, require */
7265
7266  if ( typeof define == 'function' && define.amd ) {
7267    // AMD
7268    define( 'fizzy-ui-utils/utils',[
7269      'desandro-matches-selector/matches-selector'
7270    ], function( matchesSelector ) {
7271      return factory( window, matchesSelector );
7272    });
7273  } else if ( typeof module == 'object' && module.exports ) {
7274    // CommonJS
7275    module.exports = factory(
7276      window,
7277      require('desandro-matches-selector')
7278    );
7279  } else {
7280    // browser global
7281    window.fizzyUIUtils = factory(
7282      window,
7283      window.matchesSelector
7284    );
7285  }
7286
7287}( window, function factory( window, matchesSelector ) {
7288
7289
7290
7291var utils = {};
7292
7293// ----- extend ----- //
7294
7295// extends objects
7296utils.extend = function( a, b ) {
7297  for ( var prop in b ) {
7298    a[ prop ] = b[ prop ];
7299  }
7300  return a;
7301};
7302
7303// ----- modulo ----- //
7304
7305utils.modulo = function( num, div ) {
7306  return ( ( num % div ) + div ) % div;
7307};
7308
7309// ----- makeArray ----- //
7310
7311var arraySlice = Array.prototype.slice;
7312
7313// turn element or nodeList into an array
7314utils.makeArray = function( obj ) {
7315  if ( Array.isArray( obj ) ) {
7316    // use object if already an array
7317    return obj;
7318  }
7319  // return empty array if undefined or null. #6
7320  if ( obj === null || obj === undefined ) {
7321    return [];
7322  }
7323
7324  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
7325  if ( isArrayLike ) {
7326    // convert nodeList to array
7327    return arraySlice.call( obj );
7328  }
7329
7330  // array of single index
7331  return [ obj ];
7332};
7333
7334// ----- removeFrom ----- //
7335
7336utils.removeFrom = function( ary, obj ) {
7337  var index = ary.indexOf( obj );
7338  if ( index != -1 ) {
7339    ary.splice( index, 1 );
7340  }
7341};
7342
7343// ----- getParent ----- //
7344
7345utils.getParent = function( elem, selector ) {
7346  while ( elem.parentNode && elem != document.body ) {
7347    elem = elem.parentNode;
7348    if ( matchesSelector( elem, selector ) ) {
7349      return elem;
7350    }
7351  }
7352};
7353
7354// ----- getQueryElement ----- //
7355
7356// use element as selector string
7357utils.getQueryElement = function( elem ) {
7358  if ( typeof elem == 'string' ) {
7359    return document.querySelector( elem );
7360  }
7361  return elem;
7362};
7363
7364// ----- handleEvent ----- //
7365
7366// enable .ontype to trigger from .addEventListener( elem, 'type' )
7367utils.handleEvent = function( event ) {
7368  var method = 'on' + event.type;
7369  if ( this[ method ] ) {
7370    this[ method ]( event );
7371  }
7372};
7373
7374// ----- filterFindElements ----- //
7375
7376utils.filterFindElements = function( elems, selector ) {
7377  // make array of elems
7378  elems = utils.makeArray( elems );
7379  var ffElems = [];
7380
7381  elems.forEach( function( elem ) {
7382    // check that elem is an actual element
7383    
7383// START UNCODE EDIT
7384    // if ( !( elem instanceof HTMLElement ) ) {
7385    if ( !( elem instanceof HTMLElement ) && !SiteParameters.is_frontend_editor ) {
7386    // END UNCODE EDIT
vendor: 36,979 bytes, lines 7386-8867
7386
7387      return;
7388    }
7389    // add elem if no selector
7390    if ( !selector ) {
7391      ffElems.push( elem );
7392      return;
7393    }
7394    // filter & find items if we have a selector
7395    // filter
7396    if ( matchesSelector( elem, selector ) ) {
7397      ffElems.push( elem );
7398    }
7399    // find children
7400    var childElems = elem.querySelectorAll( selector );
7401    // concat childElems to filterFound array
7402    for ( var i=0; i < childElems.length; i++ ) {
7403      ffElems.push( childElems[i] );
7404    }
7405  });
7406
7407  return ffElems;
7408};
7409
7410// ----- debounceMethod ----- //
7411
7412utils.debounceMethod = function( _class, methodName, threshold ) {
7413  threshold = threshold || 100;
7414  // original method
7415  var method = _class.prototype[ methodName ];
7416  var timeoutName = methodName + 'Timeout';
7417
7418  _class.prototype[ methodName ] = function() {
7419    var timeout = this[ timeoutName ];
7420    clearTimeout( timeout );
7421
7422    var args = arguments;
7423    var _this = this;
7424    this[ timeoutName ] = setTimeout( function() {
7425      method.apply( _this, args );
7426      delete _this[ timeoutName ];
7427    }, threshold );
7428  };
7429};
7430
7431// ----- docReady ----- //
7432
7433utils.docReady = function( callback ) {
7434  var readyState = document.readyState;
7435  if ( readyState == 'complete' || readyState == 'interactive' ) {
7436    // do async to allow for other scripts to run. metafizzy/flickity#441
7437    setTimeout( callback );
7438  } else {
7439    document.addEventListener( 'DOMContentLoaded', callback );
7440  }
7441};
7442
7443// ----- htmlInit ----- //
7444
7445// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
7446utils.toDashed = function( str ) {
7447  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
7448    return $1 + '-' + $2;
7449  }).toLowerCase();
7450};
7451
7452var console = window.console;
7453/**
7454 * allow user to initialize classes via [data-namespace] or .js-namespace class
7455 * htmlInit( Widget, 'widgetName' )
7456 * options are parsed from data-namespace-options
7457 */
7458utils.htmlInit = function( WidgetClass, namespace ) {
7459  utils.docReady( function() {
7460    var dashedNamespace = utils.toDashed( namespace );
7461    var dataAttr = 'data-' + dashedNamespace;
7462    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
7463    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
7464    var elems = utils.makeArray( dataAttrElems )
7465      .concat( utils.makeArray( jsDashElems ) );
7466    var dataOptionsAttr = dataAttr + '-options';
7467    var jQuery = window.jQuery;
7468
7469    elems.forEach( function( elem ) {
7470      var attr = elem.getAttribute( dataAttr ) ||
7471        elem.getAttribute( dataOptionsAttr );
7472      var options;
7473      try {
7474        options = attr && JSON.parse( attr );
7475      } catch ( error ) {
7476        // log error, do not initialize
7477        if ( console ) {
7478          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
7479          ': ' + error );
7480        }
7481        return;
7482      }
7483      // initialize
7484      var instance = new WidgetClass( elem, options );
7485      // make available via $().data('namespace')
7486      if ( jQuery ) {
7487        jQuery.data( elem, namespace, instance );
7488      }
7489    });
7490
7491  });
7492};
7493
7494// -----  ----- //
7495
7496return utils;
7497
7498}));
7499
7500/**
7501 * Outlayer Item
7502 */
7503
7504( function( window, factory ) {
7505  // universal module definition
7506  /* jshint strict: false */ /* globals define, module, require */
7507  if ( typeof define == 'function' && define.amd ) {
7508    // AMD - RequireJS
7509    define( 'outlayer/item',[
7510        'ev-emitter/ev-emitter',
7511        'get-size/get-size'
7512      ],
7513      factory
7514    );
7515  } else if ( typeof module == 'object' && module.exports ) {
7516    // CommonJS - Browserify, Webpack
7517    module.exports = factory(
7518      require('ev-emitter'),
7519      require('get-size')
7520    );
7521  } else {
7522    // browser global
7523    window.Outlayer = {};
7524    window.Outlayer.Item = factory(
7525      window.EvEmitter,
7526      window.getSize
7527    );
7528  }
7529
7530}( window, function factory( EvEmitter, getSize ) {
7531'use strict';
7532
7533// ----- helpers ----- //
7534
7535function isEmptyObj( obj ) {
7536  for ( var prop in obj ) {
7537    return false;
7538  }
7539  prop = null;
7540  return true;
7541}
7542
7543// -------------------------- CSS3 support -------------------------- //
7544
7545
7546var docElemStyle = document.documentElement.style;
7547
7548var transitionProperty = typeof docElemStyle.transition == 'string' ?
7549  'transition' : 'WebkitTransition';
7550var transformProperty = typeof docElemStyle.transform == 'string' ?
7551  'transform' : 'WebkitTransform';
7552
7553var transitionEndEvent = {
7554  WebkitTransition: 'webkitTransitionEnd',
7555  transition: 'transitionend'
7556}[ transitionProperty ];
7557
7558// cache all vendor properties that could have vendor prefix
7559var vendorProperties = {
7560  transform: transformProperty,
7561  transition: transitionProperty,
7562  transitionDuration: transitionProperty + 'Duration',
7563  transitionProperty: transitionProperty + 'Property',
7564  transitionDelay: transitionProperty + 'Delay'
7565};
7566
7567// -------------------------- Item -------------------------- //
7568
7569function Item( element, layout ) {
7570  if ( !element ) {
7571    return;
7572  }
7573
7574  this.element = element;
7575  // parent layout class, i.e. Masonry, Isotope, or Packery
7576  this.layout = layout;
7577  this.position = {
7578    x: 0,
7579    y: 0
7580  };
7581
7582  this._create();
7583}
7584
7585// inherit EvEmitter
7586var proto = Item.prototype = Object.create( EvEmitter.prototype );
7587proto.constructor = Item;
7588
7589proto._create = function() {
7590  // transition objects
7591  this._transn = {
7592    ingProperties: {},
7593    clean: {},
7594    onEnd: {}
7595  };
7596
7597  this.css({
7598    position: 'absolute'
7599  });
7600};
7601
7602// trigger specified handler for event type
7603proto.handleEvent = function( event ) {
7604  var method = 'on' + event.type;
7605  if ( this[ method ] ) {
7606    this[ method ]( event );
7607  }
7608};
7609
7610proto.getSize = function() {
7611  this.size = getSize( this.element );
7612};
7613
7614/**
7615 * apply CSS styles to element
7616 * @param {Object} style
7617 */
7618proto.css = function( style ) {
7619  var elemStyle = this.element.style;
7620
7621  for ( var prop in style ) {
7622    // use vendor property if available
7623    var supportedProp = vendorProperties[ prop ] || prop;
7624    elemStyle[ supportedProp ] = style[ prop ];
7625  }
7626};
7627
7628 // measure position, and sets it
7629proto.getPosition = function() {
7630  var style = getComputedStyle( this.element );
7631  var isOriginLeft = this.layout._getOption('originLeft');
7632  var isOriginTop = this.layout._getOption('originTop');
7633  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
7634  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
7635  var x = parseFloat( xValue );
7636  var y = parseFloat( yValue );
7637  // convert percent to pixels
7638  var layoutSize = this.layout.size;
7639  if ( xValue.indexOf('%') != -1 ) {
7640    x = ( x / 100 ) * layoutSize.width;
7641  }
7642  if ( yValue.indexOf('%') != -1 ) {
7643    y = ( y / 100 ) * layoutSize.height;
7644  }
7645  // clean up 'auto' or other non-integer values
7646  x = isNaN( x ) ? 0 : x;
7647  y = isNaN( y ) ? 0 : y;
7648  // remove padding from measurement
7649  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
7650  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
7651
7652  this.position.x = x;
7653  this.position.y = y;
7654};
7655
7656// set settled position, apply padding
7657proto.layoutPosition = function() {
7658  var layoutSize = this.layout.size;
7659  var style = {};
7660  var isOriginLeft = this.layout._getOption('originLeft');
7661  var isOriginTop = this.layout._getOption('originTop');
7662
7663  // x
7664  var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
7665  var xProperty = isOriginLeft ? 'left' : 'right';
7666  var xResetProperty = isOriginLeft ? 'right' : 'left';
7667
7668  var x = this.position.x + layoutSize[ xPadding ];
7669  // set in percentage or pixels
7670  style[ xProperty ] = this.getXValue( x );
7671  // reset other property
7672  style[ xResetProperty ] = '';
7673
7674  // y
7675  var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
7676  var yProperty = isOriginTop ? 'top' : 'bottom';
7677  var yResetProperty = isOriginTop ? 'bottom' : 'top';
7678
7679  var y = this.position.y + layoutSize[ yPadding ];
7680  // set in percentage or pixels
7681  style[ yProperty ] = this.getYValue( y );
7682  // reset other property
7683  style[ yResetProperty ] = '';
7684
7685  this.css( style );
7686  this.emitEvent( 'layout', [ this ] );
7687};
7688
7689proto.getXValue = function( x ) {
7690  var isHorizontal = this.layout._getOption('horizontal');
7691  return this.layout.options.percentPosition && !isHorizontal ?
7692    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
7693};
7694
7695proto.getYValue = function( y ) {
7696  var isHorizontal = this.layout._getOption('horizontal');
7697  return this.layout.options.percentPosition && isHorizontal ?
7698    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
7699};
7700
7701proto._transitionTo = function( x, y ) {
7702  this.getPosition();
7703  // get current x & y from top/left
7704  var curX = this.position.x;
7705  var curY = this.position.y;
7706
7707  var didNotMove = x == this.position.x && y == this.position.y;
7708
7709  // save end position
7710  this.setPosition( x, y );
7711
7712  // if did not move and not transitioning, just go to layout
7713  if ( didNotMove && !this.isTransitioning ) {
7714    this.layoutPosition();
7715    return;
7716  }
7717
7718  var transX = x - curX;
7719  var transY = y - curY;
7720  var transitionStyle = {};
7721  transitionStyle.transform = this.getTranslate( transX, transY );
7722
7723  this.transition({
7724    to: transitionStyle,
7725    onTransitionEnd: {
7726      transform: this.layoutPosition
7727    },
7728    isCleaning: true
7729  });
7730};
7731
7732proto.getTranslate = function( x, y ) {
7733  // flip cooridinates if origin on right or bottom
7734  var isOriginLeft = this.layout._getOption('originLeft');
7735  var isOriginTop = this.layout._getOption('originTop');
7736  x = isOriginLeft ? x : -x;
7737  y = isOriginTop ? y : -y;
7738  return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
7739};
7740
7741// non transition + transform support
7742proto.goTo = function( x, y ) {
7743  this.setPosition( x, y );
7744  this.layoutPosition();
7745};
7746
7747proto.moveTo = proto._transitionTo;
7748
7749proto.setPosition = function( x, y ) {
7750  this.position.x = parseFloat( x );
7751  this.position.y = parseFloat( y );
7752};
7753
7754// ----- transition ----- //
7755
7756/**
7757 * @param {Object} style - CSS
7758 * @param {Function} onTransitionEnd
7759 */
7760
7761// non transition, just trigger callback
7762proto._nonTransition = function( args ) {
7763  this.css( args.to );
7764  if ( args.isCleaning ) {
7765    this._removeStyles( args.to );
7766  }
7767  for ( var prop in args.onTransitionEnd ) {
7768    args.onTransitionEnd[ prop ].call( this );
7769  }
7770};
7771
7772/**
7773 * proper transition
7774 * @param {Object} args - arguments
7775 *   @param {Object} to - style to transition to
7776 *   @param {Object} from - style to start transition from
7777 *   @param {Boolean} isCleaning - removes transition styles after transition
7778 *   @param {Function} onTransitionEnd - callback
7779 */
7780proto.transition = function( args ) {
7781  // redirect to nonTransition if no transition duration
7782  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
7783    this._nonTransition( args );
7784    return;
7785  }
7786
7787  var _transition = this._transn;
7788  // keep track of onTransitionEnd callback by css property
7789  for ( var prop in args.onTransitionEnd ) {
7790    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
7791  }
7792  // keep track of properties that are transitioning
7793  for ( prop in args.to ) {
7794    _transition.ingProperties[ prop ] = true;
7795    // keep track of properties to clean up when transition is done
7796    if ( args.isCleaning ) {
7797      _transition.clean[ prop ] = true;
7798    }
7799  }
7800
7801  // set from styles
7802  if ( args.from ) {
7803    this.css( args.from );
7804    // force redraw. http://blog.alexmaccaw.com/css-transitions
7805    var h = this.element.offsetHeight;
7806    // hack for JSHint to hush about unused var
7807    h = null;
7808  }
7809  // enable transition
7810  this.enableTransition( args.to );
7811  // set styles that are transitioning
7812  this.css( args.to );
7813
7814  this.isTransitioning = true;
7815
7816};
7817
7818// dash before all cap letters, including first for
7819// WebkitTransform => -webkit-transform
7820function toDashedAll( str ) {
7821  return str.replace( /([A-Z])/g, function( $1 ) {
7822    return '-' + $1.toLowerCase();
7823  });
7824}
7825
7826var transitionProps = 'opacity,' + toDashedAll( transformProperty );
7827
7828proto.enableTransition = function(/* style */) {
7829  // HACK changing transitionProperty during a transition
7830  // will cause transition to jump
7831  if ( this.isTransitioning ) {
7832    return;
7833  }
7834
7835  // make `transition: foo, bar, baz` from style object
7836  // HACK un-comment this when enableTransition can work
7837  // while a transition is happening
7838  // var transitionValues = [];
7839  // for ( var prop in style ) {
7840  //   // dash-ify camelCased properties like WebkitTransition
7841  //   prop = vendorProperties[ prop ] || prop;
7842  //   transitionValues.push( toDashedAll( prop ) );
7843  // }
7844  // munge number to millisecond, to match stagger
7845  var duration = this.layout.options.transitionDuration;
7846  duration = typeof duration == 'number' ? duration + 'ms' : duration;
7847  // enable transition styles
7848  this.css({
7849    transitionProperty: transitionProps,
7850    transitionDuration: duration,
7851    transitionDelay: this.staggerDelay || 0
7852  });
7853  // listen for transition end event
7854  this.element.addEventListener( transitionEndEvent, this, false );
7855};
7856
7857// ----- events ----- //
7858
7859proto.onwebkitTransitionEnd = function( event ) {
7860  this.ontransitionend( event );
7861};
7862
7863proto.onotransitionend = function( event ) {
7864  this.ontransitionend( event );
7865};
7866
7867// properties that I munge to make my life easier
7868var dashedVendorProperties = {
7869  '-webkit-transform': 'transform'
7870};
7871
7872proto.ontransitionend = function( event ) {
7873  // disregard bubbled events from children
7874  if ( event.target !== this.element ) {
7875    return;
7876  }
7877  var _transition = this._transn;
7878  // get property name of transitioned property, convert to prefix-free
7879  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
7880
7881  // remove property that has completed transitioning
7882  delete _transition.ingProperties[ propertyName ];
7883  // check if any properties are still transitioning
7884  if ( isEmptyObj( _transition.ingProperties ) ) {
7885    // all properties have completed transitioning
7886    this.disableTransition();
7887  }
7888  // clean style
7889  if ( propertyName in _transition.clean ) {
7890    // clean up style
7891    this.element.style[ event.propertyName ] = '';
7892    delete _transition.clean[ propertyName ];
7893  }
7894  // trigger onTransitionEnd callback
7895  if ( propertyName in _transition.onEnd ) {
7896    var onTransitionEnd = _transition.onEnd[ propertyName ];
7897    onTransitionEnd.call( this );
7898    delete _transition.onEnd[ propertyName ];
7899  }
7900
7901  this.emitEvent( 'transitionEnd', [ this ] );
7902};
7903
7904proto.disableTransition = function() {
7905  this.removeTransitionStyles();
7906  this.element.removeEventListener( transitionEndEvent, this, false );
7907  this.isTransitioning = false;
7908};
7909
7910/**
7911 * removes style property from element
7912 * @param {Object} style
7913**/
7914proto._removeStyles = function( style ) {
7915  // clean up transition styles
7916  var cleanStyle = {};
7917  for ( var prop in style ) {
7918    cleanStyle[ prop ] = '';
7919  }
7920  this.css( cleanStyle );
7921};
7922
7923var cleanTransitionStyle = {
7924  transitionProperty: '',
7925  transitionDuration: '',
7926  transitionDelay: ''
7927};
7928
7929proto.removeTransitionStyles = function() {
7930  // remove transition
7931  this.css( cleanTransitionStyle );
7932};
7933
7934// ----- stagger ----- //
7935
7936proto.stagger = function( delay ) {
7937  delay = isNaN( delay ) ? 0 : delay;
7938  this.staggerDelay = delay + 'ms';
7939};
7940
7941// ----- show/hide/remove ----- //
7942
7943// remove element from DOM
7944proto.removeElem = function() {
7945  this.element.parentNode.removeChild( this.element );
7946  // remove display: none
7947  this.css({ display: '' });
7948  this.emitEvent( 'remove', [ this ] );
7949};
7950
7951proto.remove = function() {
7952  // just remove element if no transition support or no transition
7953  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
7954    this.removeElem();
7955    return;
7956  }
7957
7958  // start transition
7959  this.once( 'transitionEnd', function() {
7960    this.removeElem();
7961  });
7962  this.hide();
7963};
7964
7965proto.reveal = function() {
7966  delete this.isHidden;
7967  // remove display: none
7968  this.css({ display: '' });
7969
7970  var options = this.layout.options;
7971
7972  var onTransitionEnd = {};
7973  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
7974  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
7975
7976  this.transition({
7977    from: options.hiddenStyle,
7978    to: options.visibleStyle,
7979    isCleaning: true,
7980    onTransitionEnd: onTransitionEnd
7981  });
7982};
7983
7984proto.onRevealTransitionEnd = function() {
7985  // check if still visible
7986  // during transition, item may have been hidden
7987  if ( !this.isHidden ) {
7988    this.emitEvent('reveal');
7989  }
7990};
7991
7992/**
7993 * get style property use for hide/reveal transition end
7994 * @param {String} styleProperty - hiddenStyle/visibleStyle
7995 * @returns {String}
7996 */
7997proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
7998  var optionStyle = this.layout.options[ styleProperty ];
7999  // use opacity
8000  if ( optionStyle.opacity ) {
8001    return 'opacity';
8002  }
8003  // get first property
8004  for ( var prop in optionStyle ) {
8005    return prop;
8006  }
8007};
8008
8009proto.hide = function() {
8010  // set flag
8011  this.isHidden = true;
8012  // remove display: none
8013  this.css({ display: '' });
8014
8015  var options = this.layout.options;
8016
8017  var onTransitionEnd = {};
8018  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
8019  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
8020
8021  this.transition({
8022    from: options.visibleStyle,
8023    to: options.hiddenStyle,
8024    // keep hidden stuff hidden
8025    isCleaning: true,
8026    onTransitionEnd: onTransitionEnd
8027  });
8028};
8029
8030proto.onHideTransitionEnd = function() {
8031  // check if still hidden
8032  // during transition, item may have been un-hidden
8033  if ( this.isHidden ) {
8034    this.css({ display: 'none' });
8035    this.emitEvent('hide');
8036  }
8037};
8038
8039proto.destroy = function() {
8040  this.css({
8041    position: '',
8042    left: '',
8043    right: '',
8044    top: '',
8045    bottom: '',
8046    transition: '',
8047    transform: ''
8048  });
8049};
8050
8051return Item;
8052
8053}));
8054
8055/*!
8056 * Outlayer v2.1.1
8057 * the brains and guts of a layout library
8058 * MIT license
8059 */
8060
8061( function( window, factory ) {
8062  'use strict';
8063  // universal module definition
8064  /* jshint strict: false */ /* globals define, module, require */
8065  if ( typeof define == 'function' && define.amd ) {
8066    // AMD - RequireJS
8067    define( 'outlayer/outlayer',[
8068        'ev-emitter/ev-emitter',
8069        'get-size/get-size',
8070        'fizzy-ui-utils/utils',
8071        './item'
8072      ],
8073      function( EvEmitter, getSize, utils, Item ) {
8074        return factory( window, EvEmitter, getSize, utils, Item);
8075      }
8076    );
8077  } else if ( typeof module == 'object' && module.exports ) {
8078    // CommonJS - Browserify, Webpack
8079    module.exports = factory(
8080      window,
8081      require('ev-emitter'),
8082      require('get-size'),
8083      require('fizzy-ui-utils'),
8084      require('./item')
8085    );
8086  } else {
8087    // browser global
8088    window.Outlayer = factory(
8089      window,
8090      window.EvEmitter,
8091      window.getSize,
8092      window.fizzyUIUtils,
8093      window.Outlayer.Item
8094    );
8095  }
8096
8097}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
8098'use strict';
8099
8100// ----- vars ----- //
8101
8102var console = window.console;
8103var jQuery = window.jQuery;
8104var noop = function() {};
8105
8106// -------------------------- Outlayer -------------------------- //
8107
8108// globally unique identifiers
8109var GUID = 0;
8110// internal store of all Outlayer intances
8111var instances = {};
8112
8113
8114/**
8115 * @param {Element, String} element
8116 * @param {Object} options
8117 * @constructor
8118 */
8119function Outlayer( element, options ) {
8120  var queryElement = utils.getQueryElement( element );
8121  if ( !queryElement ) {
8122    if ( console ) {
8123      console.error( 'Bad element for ' + this.constructor.namespace +
8124        ': ' + ( queryElement || element ) );
8125    }
8126    return;
8127  }
8128  this.element = queryElement;
8129  // add jQuery
8130  if ( jQuery ) {
8131    this.$element = jQuery( this.element );
8132  }
8133
8134  // options
8135  this.options = utils.extend( {}, this.constructor.defaults );
8136  this.option( options );
8137
8138  // add id for Outlayer.getFromElement
8139  var id = ++GUID;
8140  this.element.outlayerGUID = id; // expando
8141  instances[ id ] = this; // associate via id
8142
8143  // kick it off
8144  this._create();
8145
8146  var isInitLayout = this._getOption('initLayout');
8147  if ( isInitLayout ) {
8148    this.layout();
8149  }
8150}
8151
8152// settings are for internal use only
8153Outlayer.namespace = 'outlayer';
8154Outlayer.Item = Item;
8155
8156// default options
8157Outlayer.defaults = {
8158  containerStyle: {
8159    position: 'relative'
8160  },
8161  initLayout: true,
8162  originLeft: true,
8163  originTop: true,
8164  resize: true,
8165  resizeContainer: true,
8166  // item options
8167  transitionDuration: '0.4s',
8168  hiddenStyle: {
8169    opacity: 0,
8170    transform: 'scale(0.001)'
8171  },
8172  visibleStyle: {
8173    opacity: 1,
8174    transform: 'scale(1)'
8175  }
8176};
8177
8178var proto = Outlayer.prototype;
8179// inherit EvEmitter
8180utils.extend( proto, EvEmitter.prototype );
8181
8182/**
8183 * set options
8184 * @param {Object} opts
8185 */
8186proto.option = function( opts ) {
8187  utils.extend( this.options, opts );
8188};
8189
8190/**
8191 * get backwards compatible option value, check old name
8192 */
8193proto._getOption = function( option ) {
8194  var oldOption = this.constructor.compatOptions[ option ];
8195  return oldOption && this.options[ oldOption ] !== undefined ?
8196    this.options[ oldOption ] : this.options[ option ];
8197};
8198
8199Outlayer.compatOptions = {
8200  // currentName: oldName
8201  initLayout: 'isInitLayout',
8202  horizontal: 'isHorizontal',
8203  layoutInstant: 'isLayoutInstant',
8204  originLeft: 'isOriginLeft',
8205  originTop: 'isOriginTop',
8206  resize: 'isResizeBound',
8207  resizeContainer: 'isResizingContainer'
8208};
8209
8210proto._create = function() {
8211  // get items from children
8212  this.reloadItems();
8213  // elements that affect layout, but are not laid out
8214  this.stamps = [];
8215  this.stamp( this.options.stamp );
8216  // set container style
8217  utils.extend( this.element.style, this.options.containerStyle );
8218
8219  // bind resize method
8220  var canBindResize = this._getOption('resize');
8221  if ( canBindResize ) {
8222    this.bindResize();
8223  }
8224};
8225
8226// goes through all children again and gets bricks in proper order
8227proto.reloadItems = function() {
8228  // collection of item elements
8229  this.items = this._itemize( this.element.children );
8230};
8231
8232
8233/**
8234 * turn elements into Outlayer.Items to be used in layout
8235 * @param {Array or NodeList or HTMLElement} elems
8236 * @returns {Array} items - collection of new Outlayer Items
8237 */
8238proto._itemize = function( elems ) {
8239
8240  var itemElems = this._filterFindItemElements( elems );
8241  var Item = this.constructor.Item;
8242
8243  // create new Outlayer Items for collection
8244  var items = [];
8245  for ( var i=0; i < itemElems.length; i++ ) {
8246    var elem = itemElems[i];
8247    var item = new Item( elem, this );
8248    items.push( item );
8249  }
8250
8251  return items;
8252};
8253
8254/**
8255 * get item elements to be used in layout
8256 * @param {Array or NodeList or HTMLElement} elems
8257 * @returns {Array} items - item elements
8258 */
8259proto._filterFindItemElements = function( elems ) {
8260  return utils.filterFindElements( elems, this.options.itemSelector );
8261};
8262
8263/**
8264 * getter method for getting item elements
8265 * @returns {Array} elems - collection of item elements
8266 */
8267proto.getItemElements = function() {
8268  return this.items.map( function( item ) {
8269    return item.element;
8270  });
8271};
8272
8273// ----- init & layout ----- //
8274
8275/**
8276 * lays out all items
8277 */
8278proto.layout = function() {
8279  this._resetLayout();
8280  this._manageStamps();
8281
8282  // don't animate first layout
8283  var layoutInstant = this._getOption('layoutInstant');
8284  var isInstant = layoutInstant !== undefined ?
8285    layoutInstant : !this._isLayoutInited;
8286  this.layoutItems( this.items, isInstant );
8287
8288  // flag for initalized
8289  this._isLayoutInited = true;
8290};
8291
8292// _init is alias for layout
8293proto._init = proto.layout;
8294
8295/**
8296 * logic before any new layout
8297 */
8298proto._resetLayout = function() {
8299  this.getSize();
8300};
8301
8302
8303proto.getSize = function() {
8304  this.size = getSize( this.element );
8305};
8306
8307/**
8308 * get measurement from option, for columnWidth, rowHeight, gutter
8309 * if option is String -> get element from selector string, & get size of element
8310 * if option is Element -> get size of element
8311 * else use option as a number
8312 *
8313 * @param {String} measurement
8314 * @param {String} size - width or height
8315 * @private
8316 */
8317proto._getMeasurement = function( measurement, size ) {
8318  var option = this.options[ measurement ];
8319  var elem;
8320  if ( !option ) {
8321    // default to 0
8322    this[ measurement ] = 0;
8323  } else {
8324    // use option as an element
8325    if ( typeof option == 'string' ) {
8326      elem = this.element.querySelector( option );
8327    } else if ( option instanceof HTMLElement ) {
8328      elem = option;
8329    }
8330    // use size of element, if element
8331    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
8332  }
8333};
8334
8335/**
8336 * layout a collection of item elements
8337 * @api public
8338 */
8339proto.layoutItems = function( items, isInstant ) {
8340  items = this._getItemsForLayout( items );
8341
8342  this._layoutItems( items, isInstant );
8343
8344  this._postLayout();
8345};
8346
8347/**
8348 * get the items to be laid out
8349 * you may want to skip over some items
8350 * @param {Array} items
8351 * @returns {Array} items
8352 */
8353proto._getItemsForLayout = function( items ) {
8354  return items.filter( function( item ) {
8355    return !item.isIgnored;
8356  });
8357};
8358
8359/**
8360 * layout items
8361 * @param {Array} items
8362 * @param {Boolean} isInstant
8363 */
8364proto._layoutItems = function( items, isInstant ) {
8365  this._emitCompleteOnItems( 'layout', items );
8366
8367  if ( !items || !items.length ) {
8368    // no items, emit event with empty array
8369    return;
8370  }
8371
8372  var queue = [];
8373
8374  items.forEach( function( item ) {
8375    // get x/y object from method
8376    var position = this._getItemLayoutPosition( item );
8377    // enqueue
8378    position.item = item;
8379    position.isInstant = isInstant || item.isLayoutInstant;
8380    queue.push( position );
8381  }, this );
8382
8383  this._processLayoutQueue( queue );
8384};
8385
8386/**
8387 * get item layout position
8388 * @param {Outlayer.Item} item
8389 * @returns {Object} x and y position
8390 */
8391proto._getItemLayoutPosition = function( /* item */ ) {
8392  return {
8393    x: 0,
8394    y: 0
8395  };
8396};
8397
8398/**
8399 * iterate over array and position each item
8400 * Reason being - separating this logic prevents 'layout invalidation'
8401 * thx @paul_irish
8402 * @param {Array} queue
8403 */
8404proto._processLayoutQueue = function( queue ) {
8405  this.updateStagger();
8406  queue.forEach( function( obj, i ) {
8407    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
8408  }, this );
8409};
8410
8411// set stagger from option in milliseconds number
8412proto.updateStagger = function() {
8413  var stagger = this.options.stagger;
8414  if ( stagger === null || stagger === undefined ) {
8415    this.stagger = 0;
8416    return;
8417  }
8418  this.stagger = getMilliseconds( stagger );
8419  return this.stagger;
8420};
8421
8422/**
8423 * Sets position of item in DOM
8424 * @param {Outlayer.Item} item
8425 * @param {Number} x - horizontal position
8426 * @param {Number} y - vertical position
8427 * @param {Boolean} isInstant - disables transitions
8428 */
8429proto._positionItem = function( item, x, y, isInstant, i ) {
8430  if ( isInstant ) {
8431    // if not transition, just set CSS
8432    item.goTo( x, y );
8433  } else {
8434    item.stagger( i * this.stagger );
8435    item.moveTo( x, y );
8436  }
8437};
8438
8439/**
8440 * Any logic you want to do after each layout,
8441 * i.e. size the container
8442 */
8443proto._postLayout = function() {
8444  this.resizeContainer();
8445};
8446
8447proto.resizeContainer = function() {
8448  var isResizingContainer = this._getOption('resizeContainer');
8449  if ( !isResizingContainer ) {
8450    return;
8451  }
8452  var size = this._getContainerSize();
8453  if ( size ) {
8454    this._setContainerMeasure( size.width, true );
8455    this._setContainerMeasure( size.height, false );
8456  }
8457};
8458
8459/**
8460 * Sets width or height of container if returned
8461 * @returns {Object} size
8462 *   @param {Number} width
8463 *   @param {Number} height
8464 */
8465proto._getContainerSize = noop;
8466
8467/**
8468 * @param {Number} measure - size of width or height
8469 * @param {Boolean} isWidth
8470 */
8471proto._setContainerMeasure = function( measure, isWidth ) {
8472  if ( measure === undefined ) {
8473    return;
8474  }
8475
8476  var elemSize = this.size;
8477  // add padding and border width if border box
8478  if ( elemSize.isBorderBox ) {
8479    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
8480      elemSize.borderLeftWidth + elemSize.borderRightWidth :
8481      elemSize.paddingBottom + elemSize.paddingTop +
8482      elemSize.borderTopWidth + elemSize.borderBottomWidth;
8483  }
8484
8485  measure = Math.max( measure, 0 );
8486  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
8487};
8488
8489/**
8490 * emit eventComplete on a collection of items events
8491 * @param {String} eventName
8492 * @param {Array} items - Outlayer.Items
8493 */
8494proto._emitCompleteOnItems = function( eventName, items ) {
8495  var _this = this;
8496  function onComplete() {
8497    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
8498  }
8499
8500  var count = items.length;
8501  if ( !items || !count ) {
8502    onComplete();
8503    return;
8504  }
8505
8506  var doneCount = 0;
8507  function tick() {
8508    doneCount++;
8509    if ( doneCount == count ) {
8510      onComplete();
8511    }
8512  }
8513
8514  // bind callback
8515  items.forEach( function( item ) {
8516    item.once( eventName, tick );
8517  });
8518};
8519
8520/**
8521 * emits events via EvEmitter and jQuery events
8522 * @param {String} type - name of event
8523 * @param {Event} event - original event
8524 * @param {Array} args - extra arguments
8525 */
8526proto.dispatchEvent = function( type, event, args ) {
8527  // add original event to arguments
8528  var emitArgs = event ? [ event ].concat( args ) : args;
8529  this.emitEvent( type, emitArgs );
8530
8531  if ( jQuery ) {
8532    // set this.$element
8533    this.$element = this.$element || jQuery( this.element );
8534    if ( event ) {
8535      // create jQuery event
8536      var $event = jQuery.Event( event );
8537      $event.type = type;
8538      this.$element.trigger( $event, args );
8539    } else {
8540      // just trigger with type if no event available
8541      this.$element.trigger( type, args );
8542    }
8543  }
8544};
8545
8546// -------------------------- ignore & stamps -------------------------- //
8547
8548
8549/**
8550 * keep item in collection, but do not lay it out
8551 * ignored items do not get skipped in layout
8552 * @param {Element} elem
8553 */
8554proto.ignore = function( elem ) {
8555  var item = this.getItem( elem );
8556  if ( item ) {
8557    item.isIgnored = true;
8558  }
8559};
8560
8561/**
8562 * return item to layout collection
8563 * @param {Element} elem
8564 */
8565proto.unignore = function( elem ) {
8566  var item = this.getItem( elem );
8567  if ( item ) {
8568    delete item.isIgnored;
8569  }
8570};
8571
8572/**
8573 * adds elements to stamps
8574 * @param {NodeList, Array, Element, or String} elems
8575 */
8576proto.stamp = function( elems ) {
8577  elems = this._find( elems );
8578  if ( !elems ) {
8579    return;
8580  }
8581
8582  this.stamps = this.stamps.concat( elems );
8583  // ignore
8584  elems.forEach( this.ignore, this );
8585};
8586
8587/**
8588 * removes elements to stamps
8589 * @param {NodeList, Array, or Element} elems
8590 */
8591proto.unstamp = function( elems ) {
8592  elems = this._find( elems );
8593  if ( !elems ){
8594    return;
8595  }
8596
8597  elems.forEach( function( elem ) {
8598    // filter out removed stamp elements
8599    utils.removeFrom( this.stamps, elem );
8600    this.unignore( elem );
8601  }, this );
8602};
8603
8604/**
8605 * finds child elements
8606 * @param {NodeList, Array, Element, or String} elems
8607 * @returns {Array} elems
8608 */
8609proto._find = function( elems ) {
8610  if ( !elems ) {
8611    return;
8612  }
8613  // if string, use argument as selector string
8614  if ( typeof elems == 'string' ) {
8615    elems = this.element.querySelectorAll( elems );
8616  }
8617  elems = utils.makeArray( elems );
8618  return elems;
8619};
8620
8621proto._manageStamps = function() {
8622  if ( !this.stamps || !this.stamps.length ) {
8623    return;
8624  }
8625
8626  this._getBoundingRect();
8627
8628  this.stamps.forEach( this._manageStamp, this );
8629};
8630
8631// update boundingLeft / Top
8632proto._getBoundingRect = function() {
8633  // get bounding rect for container element
8634  var boundingRect = this.element.getBoundingClientRect();
8635  var size = this.size;
8636  this._boundingRect = {
8637    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
8638    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
8639    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
8640    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
8641  };
8642};
8643
8644/**
8645 * @param {Element} stamp
8646**/
8647proto._manageStamp = noop;
8648
8649/**
8650 * get x/y position of element relative to container element
8651 * @param {Element} elem
8652 * @returns {Object} offset - has left, top, right, bottom
8653 */
8654proto._getElementOffset = function( elem ) {
8655  var boundingRect = elem.getBoundingClientRect();
8656  var thisRect = this._boundingRect;
8657  var size = getSize( elem );
8658  var offset = {
8659    left: boundingRect.left - thisRect.left - size.marginLeft,
8660    top: boundingRect.top - thisRect.top - size.marginTop,
8661    right: thisRect.right - boundingRect.right - size.marginRight,
8662    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
8663  };
8664  return offset;
8665};
8666
8667// -------------------------- resize -------------------------- //
8668
8669// enable event handlers for listeners
8670// i.e. resize -> onresize
8671proto.handleEvent = utils.handleEvent;
8672
8673/**
8674 * Bind layout to window resizing
8675 */
8676proto.bindResize = function() {
8677  window.addEventListener( 'resize', this );
8678  this.isResizeBound = true;
8679};
8680
8681/**
8682 * Unbind layout to window resizing
8683 */
8684proto.unbindResize = function() {
8685  window.removeEventListener( 'resize', this );
8686  this.isResizeBound = false;
8687};
8688
8689proto.onresize = function() {
8690  this.resize();
8691};
8692
8693utils.debounceMethod( Outlayer, 'onresize', 100 );
8694
8695proto.resize = function() {
8696  // don't trigger if size did not change
8697  // or if resize was unbound. See #9
8698  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
8699    return;
8700  }
8701
8702  this.layout();
8703};
8704
8705/**
8706 * check if layout is needed post layout
8707 * @returns Boolean
8708 */
8709proto.needsResizeLayout = function() {
8710  var size = getSize( this.element );
8711  // check that this.size and size are there
8712  // IE8 triggers resize on body size change, so they might not be
8713  var hasSizes = this.size && size;
8714  return hasSizes && size.innerWidth !== this.size.innerWidth;
8715};
8716
8717// -------------------------- methods -------------------------- //
8718
8719/**
8720 * add items to Outlayer instance
8721 * @param {Array or NodeList or Element} elems
8722 * @returns {Array} items - Outlayer.Items
8723**/
8724proto.addItems = function( elems ) {
8725  var items = this._itemize( elems );
8726  // add items to collection
8727  if ( items.length ) {
8728    this.items = this.items.concat( items );
8729  }
8730  return items;
8731};
8732
8733/**
8734 * Layout newly-appended item elements
8735 * @param {Array or NodeList or Element} elems
8736 */
8737proto.appended = function( elems ) {
8738  var items = this.addItems( elems );
8739  if ( !items.length ) {
8740    return;
8741  }
8742  // layout and reveal just the new items
8743  this.layoutItems( items, true );
8744  this.reveal( items );
8745};
8746
8747/**
8748 * Layout prepended elements
8749 * @param {Array or NodeList or Element} elems
8750 */
8751proto.prepended = function( elems ) {
8752  var items = this._itemize( elems );
8753  if ( !items.length ) {
8754    return;
8755  }
8756  // add items to beginning of collection
8757  var previousItems = this.items.slice(0);
8758  this.items = items.concat( previousItems );
8759  // start new layout
8760  this._resetLayout();
8761  this._manageStamps();
8762  // layout new stuff without transition
8763  this.layoutItems( items, true );
8764  this.reveal( items );
8765  // layout previous items
8766  this.layoutItems( previousItems );
8767};
8768
8769/**
8770 * reveal a collection of items
8771 * @param {Array of Outlayer.Items} items
8772 */
8773proto.reveal = function( items ) {
8774  this._emitCompleteOnItems( 'reveal', items );
8775  if ( !items || !items.length ) {
8776    return;
8777  }
8778  var stagger = this.updateStagger();
8779  items.forEach( function( item, i ) {
8780    item.stagger( i * stagger );
8781    item.reveal();
8782  });
8783};
8784
8785/**
8786 * hide a collection of items
8787 * @param {Array of Outlayer.Items} items
8788 */
8789proto.hide = function( items ) {
8790  this._emitCompleteOnItems( 'hide', items );
8791  if ( !items || !items.length ) {
8792    return;
8793  }
8794  var stagger = this.updateStagger();
8795  items.forEach( function( item, i ) {
8796    item.stagger( i * stagger );
8797    item.hide();
8798  });
8799};
8800
8801/**
8802 * reveal item elements
8803 * @param {Array}, {Element}, {NodeList} items
8804 */
8805proto.revealItemElements = function( elems ) {
8806  var items = this.getItems( elems );
8807  this.reveal( items );
8808};
8809
8810/**
8811 * hide item elements
8812 * @param {Array}, {Element}, {NodeList} items
8813 */
8814proto.hideItemElements = function( elems ) {
8815  var items = this.getItems( elems );
8816  this.hide( items );
8817};
8818
8819/**
8820 * get Outlayer.Item, given an Element
8821 * @param {Element} elem
8822 * @param {Function} callback
8823 * @returns {Outlayer.Item} item
8824 */
8825proto.getItem = function( elem ) {
8826  // loop through items to get the one that matches
8827  for ( var i=0; i < this.items.length; i++ ) {
8828    var item = this.items[i];
8829    if ( item.element == elem ) {
8830      // return item
8831      return item;
8832    }
8833  }
8834};
8835
8836/**
8837 * get collection of Outlayer.Items, given Elements
8838 * @param {Array} elems
8839 * @returns {Array} items - Outlayer.Items
8840 */
8841proto.getItems = function( elems ) {
8842  elems = utils.makeArray( elems );
8843  var items = [];
8844  elems.forEach( function( elem ) {
8845    var item = this.getItem( elem );
8846    if ( item ) {
8847      items.push( item );
8848    }
8849  }, this );
8850
8851  return items;
8852};
8853
8854/**
8855 * remove element(s) from instance and DOM
8856 * @param {Array or NodeList or Element} elems
8857 */
8858proto.remove = function( elems ) {
8859  var removeItems = this.getItems( elems );
8860
8861  this._emitCompleteOnItems( 'remove', removeItems );
8862
8863  // bail if no items to remove
8864  if ( !removeItems || !removeItems.length ) {
8865    return;
8866  }
8867
vendor: 38,285 bytes, lines 8868-10291
8868  removeItems.forEach( function( item ) {
8869    item.remove();
8870    // remove item from collection
8871    utils.removeFrom( this.items, item );
8872  }, this );
8873};
8874
8875// ----- destroy ----- //
8876
8877// remove and disable Outlayer instance
8878proto.destroy = function() {
8879  // clean up dynamic styles
8880  var style = this.element.style;
8881  style.height = '';
8882  style.position = '';
8883  style.width = '';
8884  // destroy items
8885  this.items.forEach( function( item ) {
8886    item.destroy();
8887  });
8888
8889  this.unbindResize();
8890
8891  var id = this.element.outlayerGUID;
8892  delete instances[ id ]; // remove reference to instance by id
8893  delete this.element.outlayerGUID;
8894  // remove data for jQuery
8895  if ( jQuery ) {
8896    jQuery.removeData( this.element, this.constructor.namespace );
8897  }
8898
8899};
8900
8901// -------------------------- data -------------------------- //
8902
8903/**
8904 * get Outlayer instance from element
8905 * @param {Element} elem
8906 * @returns {Outlayer}
8907 */
8908Outlayer.data = function( elem ) {
8909  elem = utils.getQueryElement( elem );
8910  var id = elem && elem.outlayerGUID;
8911  return id && instances[ id ];
8912};
8913
8914
8915// -------------------------- create Outlayer class -------------------------- //
8916
8917/**
8918 * create a layout class
8919 * @param {String} namespace
8920 */
8921Outlayer.create = function( namespace, options ) {
8922  // sub-class Outlayer
8923  var Layout = subclass( Outlayer );
8924  // apply new options and compatOptions
8925  Layout.defaults = utils.extend( {}, Outlayer.defaults );
8926  utils.extend( Layout.defaults, options );
8927  Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );
8928
8929  Layout.namespace = namespace;
8930
8931  Layout.data = Outlayer.data;
8932
8933  // sub-class Item
8934  Layout.Item = subclass( Item );
8935
8936  // -------------------------- declarative -------------------------- //
8937
8938  utils.htmlInit( Layout, namespace );
8939
8940  // -------------------------- jQuery bridge -------------------------- //
8941
8942  // make into jQuery plugin
8943  if ( jQuery && jQuery.bridget ) {
8944    jQuery.bridget( namespace, Layout );
8945  }
8946
8947  return Layout;
8948};
8949
8950function subclass( Parent ) {
8951  function SubClass() {
8952    Parent.apply( this, arguments );
8953  }
8954
8955  SubClass.prototype = Object.create( Parent.prototype );
8956  SubClass.prototype.constructor = SubClass;
8957
8958  return SubClass;
8959}
8960
8961// ----- helpers ----- //
8962
8963// how many milliseconds are in each unit
8964var msUnits = {
8965  ms: 1,
8966  s: 1000
8967};
8968
8969// munge time-like parameter into millisecond number
8970// '0.4s' -> 40
8971function getMilliseconds( time ) {
8972  if ( typeof time == 'number' ) {
8973    return time;
8974  }
8975  var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
8976  var num = matches && matches[1];
8977  var unit = matches && matches[2];
8978  if ( !num.length ) {
8979    return 0;
8980  }
8981  num = parseFloat( num );
8982  var mult = msUnits[ unit ] || 1;
8983  return num * mult;
8984}
8985
8986// ----- fin ----- //
8987
8988// back in global
8989Outlayer.Item = Item;
8990
8991return Outlayer;
8992
8993}));
8994
8995/**
8996 * Isotope Item
8997**/
8998
8999( function( window, factory ) {
9000  // universal module definition
9001  /* jshint strict: false */ /*globals define, module, require */
9002  if ( typeof define == 'function' && define.amd ) {
9003    // AMD
9004    define( 'isotope-layout/js/item',[
9005        'outlayer/outlayer'
9006      ],
9007      factory );
9008  } else if ( typeof module == 'object' && module.exports ) {
9009    // CommonJS
9010    module.exports = factory(
9011      require('outlayer')
9012    );
9013  } else {
9014    // browser global
9015    window.Isotope = window.Isotope || {};
9016    window.Isotope.Item = factory(
9017      window.Outlayer
9018    );
9019  }
9020
9021}( window, function factory( Outlayer ) {
9022'use strict';
9023
9024// -------------------------- Item -------------------------- //
9025
9026// sub-class Outlayer Item
9027function Item() {
9028  Outlayer.Item.apply( this, arguments );
9029}
9030
9031var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
9032
9033var _create = proto._create;
9034proto._create = function() {
9035  // assign id, used for original-order sorting
9036  this.id = this.layout.itemGUID++;
9037  _create.call( this );
9038  this.sortData = {};
9039};
9040
9041proto.updateSortData = function() {
9042  if ( this.isIgnored ) {
9043    return;
9044  }
9045  // default sorters
9046  this.sortData.id = this.id;
9047  // for backward compatibility
9048  this.sortData['original-order'] = this.id;
9049  this.sortData.random = Math.random();
9050  // go thru getSortData obj and apply the sorters
9051  var getSortData = this.layout.options.getSortData;
9052  var sorters = this.layout._sorters;
9053  for ( var key in getSortData ) {
9054    var sorter = sorters[ key ];
9055    this.sortData[ key ] = sorter( this.element, this );
9056  }
9057};
9058
9059var _destroy = proto.destroy;
9060proto.destroy = function() {
9061  // call super
9062  _destroy.apply( this, arguments );
9063  // reset display, #741
9064  this.css({
9065    display: ''
9066  });
9067};
9068
9069return Item;
9070
9071}));
9072
9073/**
9074 * Isotope LayoutMode
9075 */
9076
9077( function( window, factory ) {
9078  // universal module definition
9079  /* jshint strict: false */ /*globals define, module, require */
9080  if ( typeof define == 'function' && define.amd ) {
9081    // AMD
9082    define( 'isotope-layout/js/layout-mode',[
9083        'get-size/get-size',
9084        'outlayer/outlayer'
9085      ],
9086      factory );
9087  } else if ( typeof module == 'object' && module.exports ) {
9088    // CommonJS
9089    module.exports = factory(
9090      require('get-size'),
9091      require('outlayer')
9092    );
9093  } else {
9094    // browser global
9095    window.Isotope = window.Isotope || {};
9096    window.Isotope.LayoutMode = factory(
9097      window.getSize,
9098      window.Outlayer
9099    );
9100  }
9101
9102}( window, function factory( getSize, Outlayer ) {
9103  'use strict';
9104
9105  // layout mode class
9106  function LayoutMode( isotope ) {
9107    this.isotope = isotope;
9108    // link properties
9109    if ( isotope ) {
9110      this.options = isotope.options[ this.namespace ];
9111      this.element = isotope.element;
9112      this.items = isotope.filteredItems;
9113      this.size = isotope.size;
9114    }
9115  }
9116
9117  var proto = LayoutMode.prototype;
9118
9119  /**
9120   * some methods should just defer to default Outlayer method
9121   * and reference the Isotope instance as `this`
9122  **/
9123  var facadeMethods = [
9124    '_resetLayout',
9125    '_getItemLayoutPosition',
9126    '_manageStamp',
9127    '_getContainerSize',
9128    '_getElementOffset',
9129    'needsResizeLayout',
9130    '_getOption'
9131  ];
9132
9133  facadeMethods.forEach( function( methodName ) {
9134    proto[ methodName ] = function() {
9135      return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
9136    };
9137  });
9138
9139  // -----  ----- //
9140
9141  // for horizontal layout modes, check vertical size
9142  proto.needsVerticalResizeLayout = function() {
9143    // don't trigger if size did not change
9144    var size = getSize( this.isotope.element );
9145    // check that this.size and size are there
9146    // IE8 triggers resize on body size change, so they might not be
9147    var hasSizes = this.isotope.size && size;
9148    return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
9149  };
9150
9151  // ----- measurements ----- //
9152
9153  proto._getMeasurement = function() {
9154    this.isotope._getMeasurement.apply( this, arguments );
9155  };
9156
9157  proto.getColumnWidth = function() {
9158    this.getSegmentSize( 'column', 'Width' );
9159  };
9160
9161  proto.getRowHeight = function() {
9162    this.getSegmentSize( 'row', 'Height' );
9163  };
9164
9165  /**
9166   * get columnWidth or rowHeight
9167   * segment: 'column' or 'row'
9168   * size 'Width' or 'Height'
9169  **/
9170  proto.getSegmentSize = function( segment, size ) {
9171    var segmentName = segment + size;
9172    var outerSize = 'outer' + size;
9173    // columnWidth / outerWidth // rowHeight / outerHeight
9174    this._getMeasurement( segmentName, outerSize );
9175    // got rowHeight or columnWidth, we can chill
9176    if ( this[ segmentName ] ) {
9177      return;
9178    }
9179    // fall back to item of first element
9180    var firstItemSize = this.getFirstItemSize();
9181    this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
9182      // or size of container
9183      this.isotope.size[ 'inner' + size ];
9184  };
9185
9186  proto.getFirstItemSize = function() {
9187    var firstItem = this.isotope.filteredItems[0];
9188    return firstItem && firstItem.element && getSize( firstItem.element );
9189  };
9190
9191  // ----- methods that should reference isotope ----- //
9192
9193  proto.layout = function() {
9194    this.isotope.layout.apply( this.isotope, arguments );
9195  };
9196
9197  proto.getSize = function() {
9198    this.isotope.getSize();
9199    this.size = this.isotope.size;
9200  };
9201
9202  // -------------------------- create -------------------------- //
9203
9204  LayoutMode.modes = {};
9205
9206  LayoutMode.create = function( namespace, options ) {
9207
9208    function Mode() {
9209      LayoutMode.apply( this, arguments );
9210    }
9211
9212    Mode.prototype = Object.create( proto );
9213    Mode.prototype.constructor = Mode;
9214
9215    // default options
9216    if ( options ) {
9217      Mode.options = options;
9218    }
9219
9220    Mode.prototype.namespace = namespace;
9221    // register in Isotope
9222    LayoutMode.modes[ namespace ] = Mode;
9223
9224    return Mode;
9225  };
9226
9227  return LayoutMode;
9228
9229}));
9230
9231/*!
9232 * Masonry v4.2.1
9233 * Cascading grid layout library
9234 * https://masonry.desandro.com
9235 * MIT License
9236 * by David DeSandro
9237 */
9238
9239( function( window, factory ) {
9240  // universal module definition
9241  /* jshint strict: false */ /*globals define, module, require */
9242  if ( typeof define == 'function' && define.amd ) {
9243    // AMD
9244    define( 'masonry-layout/masonry',[
9245        'outlayer/outlayer',
9246        'get-size/get-size'
9247      ],
9248      factory );
9249  } else if ( typeof module == 'object' && module.exports ) {
9250    // CommonJS
9251    module.exports = factory(
9252      require('outlayer'),
9253      require('get-size')
9254    );
9255  } else {
9256    // browser global
9257    window.Masonry = factory(
9258      window.Outlayer,
9259      window.getSize
9260    );
9261  }
9262
9263}( window, function factory( Outlayer, getSize ) {
9264
9265
9266
9267// -------------------------- masonryDefinition -------------------------- //
9268
9269  // create an Outlayer layout class
9270  var Masonry = Outlayer.create('masonry');
9271  // isFitWidth -> fitWidth
9272  Masonry.compatOptions.fitWidth = 'isFitWidth';
9273
9274  var proto = Masonry.prototype;
9275
9276  proto._resetLayout = function() {
9277    this.getSize();
9278    this._getMeasurement( 'columnWidth', 'outerWidth' );
9279    this._getMeasurement( 'gutter', 'outerWidth' );
9280    this.measureColumns();
9281
9282    // reset column Y
9283    this.colYs = [];
9284    for ( var i=0; i < this.cols; i++ ) {
9285      this.colYs.push( 0 );
9286    }
9287
9288    this.maxY = 0;
9289    this.horizontalColIndex = 0;
9290  };
9291
9292  proto.measureColumns = function() {
9293    this.getContainerWidth();
9294    // if columnWidth is 0, default to outerWidth of first item
9295    if ( !this.columnWidth ) {
9296      var firstItem = this.items[0];
9297      var firstItemElem = firstItem && firstItem.element;
9298      // columnWidth fall back to item of first element
9299      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
9300        // if first elem has no width, default to size of container
9301        this.containerWidth;
9302    }
9303
9304    var columnWidth = this.columnWidth += this.gutter;
9305
9306    // calculate columns
9307    var containerWidth = this.containerWidth + this.gutter;
9308    var cols = containerWidth / columnWidth;
9309    // fix rounding errors, typically with gutters
9310    var excess = columnWidth - containerWidth % columnWidth;
9311    // if overshoot is less than a pixel, round up, otherwise floor it
9312    var mathMethod = excess && excess < 1 ? 'round' : 'floor';
9313    cols = Math[ mathMethod ]( cols );
9314    this.cols = Math.max( cols, 1 );
9315  };
9316
9317  proto.getContainerWidth = function() {
9318    // container is parent if fit width
9319    var isFitWidth = this._getOption('fitWidth');
9320    var container = isFitWidth ? this.element.parentNode : this.element;
9321    // check that this.size and size are there
9322    // IE8 triggers resize on body size change, so they might not be
9323    var size = getSize( container );
9324    this.containerWidth = size && size.innerWidth;
9325  };
9326
9327  proto._getItemLayoutPosition = function( item ) {
9328    item.getSize();
9329    // how many columns does this brick span
9330    var remainder = item.size.outerWidth % this.columnWidth;
9331    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
9332    // round if off by 1 pixel, otherwise use ceil
9333    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
9334    colSpan = Math.min( colSpan, this.cols );
9335    // use horizontal or top column position
9336    var colPosMethod = this.options.horizontalOrder ?
9337      '_getHorizontalColPosition' : '_getTopColPosition';
9338    var colPosition = this[ colPosMethod ]( colSpan, item );
9339    // position the brick
9340    var position = {
9341      x: this.columnWidth * colPosition.col,
9342      y: colPosition.y
9343    };
9344    // apply setHeight to necessary columns
9345    var setHeight = colPosition.y + item.size.outerHeight;
9346    var setMax = colSpan + colPosition.col;
9347    for ( var i = colPosition.col; i < setMax; i++ ) {
9348      this.colYs[i] = setHeight;
9349    }
9350
9351    return position;
9352  };
9353
9354  proto._getTopColPosition = function( colSpan ) {
9355    var colGroup = this._getTopColGroup( colSpan );
9356    // get the minimum Y value from the columns
9357    var minimumY = Math.min.apply( Math, colGroup );
9358
9359    return {
9360      col: colGroup.indexOf( minimumY ),
9361      y: minimumY,
9362    };
9363  };
9364
9365  /**
9366   * @param {Number} colSpan - number of columns the element spans
9367   * @returns {Array} colGroup
9368   */
9369  proto._getTopColGroup = function( colSpan ) {
9370    if ( colSpan < 2 ) {
9371      // if brick spans only one column, use all the column Ys
9372      return this.colYs;
9373    }
9374
9375    var colGroup = [];
9376    // how many different places could this brick fit horizontally
9377    var groupCount = this.cols + 1 - colSpan;
9378    // for each group potential horizontal position
9379    for ( var i = 0; i < groupCount; i++ ) {
9380      colGroup[i] = this._getColGroupY( i, colSpan );
9381    }
9382    return colGroup;
9383  };
9384
9385  proto._getColGroupY = function( col, colSpan ) {
9386    if ( colSpan < 2 ) {
9387      return this.colYs[ col ];
9388    }
9389    // make an array of colY values for that one group
9390    var groupColYs = this.colYs.slice( col, col + colSpan );
9391    // and get the max value of the array
9392    return Math.max.apply( Math, groupColYs );
9393  };
9394
9395  // get column position based on horizontal index. #873
9396  proto._getHorizontalColPosition = function( colSpan, item ) {
9397    var col = this.horizontalColIndex % this.cols;
9398    var isOver = colSpan > 1 && col + colSpan > this.cols;
9399    // shift to next row if item can't fit on current row
9400    col = isOver ? 0 : col;
9401    // don't let zero-size items take up space
9402    var hasSize = item.size.outerWidth && item.size.outerHeight;
9403    this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;
9404
9405    return {
9406      col: col,
9407      y: this._getColGroupY( col, colSpan ),
9408    };
9409  };
9410
9411  proto._manageStamp = function( stamp ) {
9412    var stampSize = getSize( stamp );
9413    var offset = this._getElementOffset( stamp );
9414    // get the columns that this stamp affects
9415    var isOriginLeft = this._getOption('originLeft');
9416    var firstX = isOriginLeft ? offset.left : offset.right;
9417    var lastX = firstX + stampSize.outerWidth;
9418    var firstCol = Math.floor( firstX / this.columnWidth );
9419    firstCol = Math.max( 0, firstCol );
9420    var lastCol = Math.floor( lastX / this.columnWidth );
9421    // lastCol should not go over if multiple of columnWidth #425
9422    lastCol -= lastX % this.columnWidth ? 0 : 1;
9423    lastCol = Math.min( this.cols - 1, lastCol );
9424    // set colYs to bottom of the stamp
9425
9426    var isOriginTop = this._getOption('originTop');
9427    var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
9428      stampSize.outerHeight;
9429    for ( var i = firstCol; i <= lastCol; i++ ) {
9430      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
9431    }
9432  };
9433
9434  proto._getContainerSize = function() {
9435    this.maxY = Math.max.apply( Math, this.colYs );
9436    var size = {
9437      height: this.maxY
9438    };
9439
9440    if ( this._getOption('fitWidth') ) {
9441      size.width = this._getContainerFitWidth();
9442    }
9443
9444    return size;
9445  };
9446
9447  proto._getContainerFitWidth = function() {
9448    var unusedCols = 0;
9449    // count unused columns
9450    var i = this.cols;
9451    while ( --i ) {
9452      if ( this.colYs[i] !== 0 ) {
9453        break;
9454      }
9455      unusedCols++;
9456    }
9457    // fit container to columns that have been used
9458    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
9459  };
9460
9461  proto.needsResizeLayout = function() {
9462    var previousWidth = this.containerWidth;
9463    this.getContainerWidth();
9464    return previousWidth != this.containerWidth;
9465  };
9466
9467  return Masonry;
9468
9469}));
9470
9471/*!
9472 * Masonry layout mode
9473 * sub-classes Masonry
9474 * https://masonry.desandro.com
9475 */
9476
9477( function( window, factory ) {
9478  // universal module definition
9479  /* jshint strict: false */ /*globals define, module, require */
9480  if ( typeof define == 'function' && define.amd ) {
9481    // AMD
9482    define( 'isotope-layout/js/layout-modes/masonry',[
9483        '../layout-mode',
9484        'masonry-layout/masonry'
9485      ],
9486      factory );
9487  } else if ( typeof module == 'object' && module.exports ) {
9488    // CommonJS
9489    module.exports = factory(
9490      require('../layout-mode'),
9491      require('masonry-layout')
9492    );
9493  } else {
9494    // browser global
9495    factory(
9496      window.Isotope.LayoutMode,
9497      window.Masonry
9498    );
9499  }
9500
9501}( window, function factory( LayoutMode, Masonry ) {
9502'use strict';
9503
9504// -------------------------- masonryDefinition -------------------------- //
9505
9506  // create an Outlayer layout class
9507  var MasonryMode = LayoutMode.create('masonry');
9508
9509  var proto = MasonryMode.prototype;
9510
9511  var keepModeMethods = {
9512    _getElementOffset: true,
9513    layout: true,
9514    _getMeasurement: true
9515  };
9516
9517  // inherit Masonry prototype
9518  for ( var method in Masonry.prototype ) {
9519    // do not inherit mode methods
9520    if ( !keepModeMethods[ method ] ) {
9521      proto[ method ] = Masonry.prototype[ method ];
9522    }
9523  }
9524
9525  var measureColumns = proto.measureColumns;
9526  proto.measureColumns = function() {
9527    // set items, used if measuring first item
9528    this.items = this.isotope.filteredItems;
9529    measureColumns.call( this );
9530  };
9531
9532  // point to mode options for fitWidth
9533  var _getOption = proto._getOption;
9534  proto._getOption = function( option ) {
9535    if ( option == 'fitWidth' ) {
9536      return this.options.isFitWidth !== undefined ?
9537        this.options.isFitWidth : this.options.fitWidth;
9538    }
9539    return _getOption.apply( this.isotope, arguments );
9540  };
9541
9542  return MasonryMode;
9543
9544}));
9545
9546/**
9547 * fitRows layout mode
9548 */
9549
9550( function( window, factory ) {
9551  // universal module definition
9552  /* jshint strict: false */ /*globals define, module, require */
9553  if ( typeof define == 'function' && define.amd ) {
9554    // AMD
9555    define( 'isotope-layout/js/layout-modes/fit-rows',[
9556        '../layout-mode'
9557      ],
9558      factory );
9559  } else if ( typeof exports == 'object' ) {
9560    // CommonJS
9561    module.exports = factory(
9562      require('../layout-mode')
9563    );
9564  } else {
9565    // browser global
9566    factory(
9567      window.Isotope.LayoutMode
9568    );
9569  }
9570
9571}( window, function factory( LayoutMode ) {
9572'use strict';
9573
9574var FitRows = LayoutMode.create('fitRows');
9575
9576var proto = FitRows.prototype;
9577
9578proto._resetLayout = function() {
9579  this.x = 0;
9580  this.y = 0;
9581  this.maxY = 0;
9582  this._getMeasurement( 'gutter', 'outerWidth' );
9583};
9584
9585proto._getItemLayoutPosition = function( item ) {
9586  item.getSize();
9587
9588  var itemWidth = item.size.outerWidth + this.gutter;
9589  // if this element cannot fit in the current row
9590  var containerWidth = this.isotope.size.innerWidth + this.gutter;
9591  if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
9592    this.x = 0;
9593    this.y = this.maxY;
9594  }
9595
9596  var position = {
9597    x: this.x,
9598    y: this.y
9599  };
9600
9601  this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
9602  this.x += itemWidth;
9603
9604  return position;
9605};
9606
9607proto._getContainerSize = function() {
9608  return { height: this.maxY };
9609};
9610
9611return FitRows;
9612
9613}));
9614
9615/**
9616 * vertical layout mode
9617 */
9618
9619( function( window, factory ) {
9620  // universal module definition
9621  /* jshint strict: false */ /*globals define, module, require */
9622  if ( typeof define == 'function' && define.amd ) {
9623    // AMD
9624    define( 'isotope-layout/js/layout-modes/vertical',[
9625        '../layout-mode'
9626      ],
9627      factory );
9628  } else if ( typeof module == 'object' && module.exports ) {
9629    // CommonJS
9630    module.exports = factory(
9631      require('../layout-mode')
9632    );
9633  } else {
9634    // browser global
9635    factory(
9636      window.Isotope.LayoutMode
9637    );
9638  }
9639
9640}( window, function factory( LayoutMode ) {
9641'use strict';
9642
9643var Vertical = LayoutMode.create( 'vertical', {
9644  horizontalAlignment: 0
9645});
9646
9647var proto = Vertical.prototype;
9648
9649proto._resetLayout = function() {
9650  this.y = 0;
9651};
9652
9653proto._getItemLayoutPosition = function( item ) {
9654  item.getSize();
9655  var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
9656    this.options.horizontalAlignment;
9657  var y = this.y;
9658  this.y += item.size.outerHeight;
9659  return { x: x, y: y };
9660};
9661
9662proto._getContainerSize = function() {
9663  return { height: this.y };
9664};
9665
9666return Vertical;
9667
9668}));
9669
9670/*!
9671 * Isotope v3.0.6
9672 *
9673 * Licensed GPLv3 for open source use
9674 * or Isotope Commercial License for commercial use
9675 *
9676 * https://isotope.metafizzy.co
9677 * Copyright 2010-2018 Metafizzy
9678 */
9679
9680( function( window, factory ) {
9681  // universal module definition
9682  /* jshint strict: false */ /*globals define, module, require */
9683  if ( typeof define == 'function' && define.amd ) {
9684    // AMD
9685    define( [
9686        'outlayer/outlayer',
9687        'get-size/get-size',
9688        'desandro-matches-selector/matches-selector',
9689        'fizzy-ui-utils/utils',
9690        'isotope-layout/js/item',
9691        'isotope-layout/js/layout-mode',
9692        // include default layout modes
9693        'isotope-layout/js/layout-modes/masonry',
9694        'isotope-layout/js/layout-modes/fit-rows',
9695        'isotope-layout/js/layout-modes/vertical'
9696      ],
9697      function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
9698        return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
9699      });
9700  } else if ( typeof module == 'object' && module.exports ) {
9701    // CommonJS
9702    module.exports = factory(
9703      window,
9704      require('outlayer'),
9705      require('get-size'),
9706      require('desandro-matches-selector'),
9707      require('fizzy-ui-utils'),
9708      require('isotope-layout/js/item'),
9709      require('isotope-layout/js/layout-mode'),
9710      // include default layout modes
9711      require('isotope-layout/js/layout-modes/masonry'),
9712      require('isotope-layout/js/layout-modes/fit-rows'),
9713      require('isotope-layout/js/layout-modes/vertical')
9714    );
9715  } else {
9716    // browser global
9717    window.Isotope = factory(
9718      window,
9719      window.Outlayer,
9720      window.getSize,
9721      window.matchesSelector,
9722      window.fizzyUIUtils,
9723      window.Isotope.Item,
9724      window.Isotope.LayoutMode
9725    );
9726  }
9727
9728}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
9729  Item, LayoutMode ) {
9730
9731
9732
9733// -------------------------- vars -------------------------- //
9734
9735var jQuery = window.jQuery;
9736
9737// -------------------------- helpers -------------------------- //
9738
9739var trim = String.prototype.trim ?
9740  function( str ) {
9741    return str.trim();
9742  } :
9743  function( str ) {
9744    return str.replace( /^\s+|\s+$/g, '' );
9745  };
9746
9747// -------------------------- isotopeDefinition -------------------------- //
9748
9749  // create an Outlayer layout class
9750  var Isotope = Outlayer.create( 'isotope', {
9751    layoutMode: 'masonry',
9752    isJQueryFiltering: true,
9753    sortAscending: true
9754  });
9755
9756  Isotope.Item = Item;
9757  Isotope.LayoutMode = LayoutMode;
9758
9759  var proto = Isotope.prototype;
9760
9761  proto._create = function() {
9762    this.itemGUID = 0;
9763    // functions that sort items
9764    this._sorters = {};
9765    this._getSorters();
9766    // call super
9767    Outlayer.prototype._create.call( this );
9768
9769    // create layout modes
9770    this.modes = {};
9771    // start filteredItems with all items
9772    this.filteredItems = this.items;
9773    // keep of track of sortBys
9774    this.sortHistory = [ 'original-order' ];
9775    // create from registered layout modes
9776    for ( var name in LayoutMode.modes ) {
9777      this._initLayoutMode( name );
9778    }
9779  };
9780
9781  proto.reloadItems = function() {
9782    // reset item ID counter
9783    this.itemGUID = 0;
9784    // call super
9785    Outlayer.prototype.reloadItems.call( this );
9786  };
9787
9788  proto._itemize = function() {
9789    var items = Outlayer.prototype._itemize.apply( this, arguments );
9790    // assign ID for original-order
9791    for ( var i=0; i < items.length; i++ ) {
9792      var item = items[i];
9793      item.id = this.itemGUID++;
9794    }
9795    this._updateItemsSortData( items );
9796    return items;
9797  };
9798
9799
9800  // -------------------------- layout -------------------------- //
9801
9802  proto._initLayoutMode = function( name ) {
9803    var Mode = LayoutMode.modes[ name ];
9804    // set mode options
9805    // HACK extend initial options, back-fill in default options
9806    var initialOpts = this.options[ name ] || {};
9807    this.options[ name ] = Mode.options ?
9808      utils.extend( Mode.options, initialOpts ) : initialOpts;
9809    // init layout mode instance
9810    this.modes[ name ] = new Mode( this );
9811  };
9812
9813
9814  proto.layout = function() {
9815    // if first time doing layout, do all magic
9816    if ( !this._isLayoutInited && this._getOption('initLayout') ) {
9817      this.arrange();
9818      return;
9819    }
9820    this._layout();
9821  };
9822
9823  // private method to be used in layout() & magic()
9824  proto._layout = function() {
9825    // don't animate first layout
9826    var isInstant = this._getIsInstant();
9827    // layout flow
9828    this._resetLayout();
9829    this._manageStamps();
9830    this.layoutItems( this.filteredItems, isInstant );
9831
9832    // flag for initalized
9833    this._isLayoutInited = true;
9834  };
9835
9836  // filter + sort + layout
9837  proto.arrange = function( opts ) {
9838    // set any options pass
9839    this.option( opts );
9840    this._getIsInstant();
9841    // filter, sort, and layout
9842
9843    // filter
9844    var filtered = this._filter( this.items );
9845    this.filteredItems = filtered.matches;
9846
9847    this._bindArrangeComplete();
9848
9849    if ( this._isInstant ) {
9850      this._noTransition( this._hideReveal, [ filtered ] );
9851    } else {
9852      this._hideReveal( filtered );
9853    }
9854
9855    this._sort();
9856    this._layout();
9857  };
9858  // alias to _init for main plugin method
9859  proto._init = proto.arrange;
9860
9861  proto._hideReveal = function( filtered ) {
9862    this.reveal( filtered.needReveal );
9863    this.hide( filtered.needHide );
9864  };
9865
9866  // HACK
9867  // Don't animate/transition first layout
9868  // Or don't animate/transition other layouts
9869  proto._getIsInstant = function() {
9870    var isLayoutInstant = this._getOption('layoutInstant');
9871    var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
9872      !this._isLayoutInited;
9873    this._isInstant = isInstant;
9874    return isInstant;
9875  };
9876
9877  // listen for layoutComplete, hideComplete and revealComplete
9878  // to trigger arrangeComplete
9879  proto._bindArrangeComplete = function() {
9880    // listen for 3 events to trigger arrangeComplete
9881    var isLayoutComplete, isHideComplete, isRevealComplete;
9882    var _this = this;
9883    function arrangeParallelCallback() {
9884      if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
9885        _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
9886      }
9887    }
9888    this.once( 'layoutComplete', function() {
9889      isLayoutComplete = true;
9890      arrangeParallelCallback();
9891    });
9892    this.once( 'hideComplete', function() {
9893      isHideComplete = true;
9894      arrangeParallelCallback();
9895    });
9896    this.once( 'revealComplete', function() {
9897      isRevealComplete = true;
9898      arrangeParallelCallback();
9899    });
9900  };
9901
9902  // -------------------------- filter -------------------------- //
9903
9904  proto._filter = function( items ) {
9905    var filter = this.options.filter;
9906    filter = filter || '*';
9907    var matches = [];
9908    var hiddenMatched = [];
9909    var visibleUnmatched = [];
9910
9911    var test = this._getFilterTest( filter );
9912
9913    // test each item
9914    for ( var i=0; i < items.length; i++ ) {
9915      var item = items[i];
9916      if ( item.isIgnored ) {
9917        continue;
9918      }
9919      // add item to either matched or unmatched group
9920      var isMatched = test( item );
9921      // item.isFilterMatched = isMatched;
9922      // add to matches if its a match
9923      if ( isMatched ) {
9924        matches.push( item );
9925      }
9926      // add to additional group if item needs to be hidden or revealed
9927      if ( isMatched && item.isHidden ) {
9928        hiddenMatched.push( item );
9929      } else if ( !isMatched && !item.isHidden ) {
9930        visibleUnmatched.push( item );
9931      }
9932    }
9933
9934    // return collections of items to be manipulated
9935    return {
9936      matches: matches,
9937      needReveal: hiddenMatched,
9938      needHide: visibleUnmatched
9939    };
9940  };
9941
9942  // get a jQuery, function, or a matchesSelector test given the filter
9943  proto._getFilterTest = function( filter ) {
9944    if ( jQuery && this.options.isJQueryFiltering ) {
9945      // use jQuery
9946      return function( item ) {
9947        return jQuery( item.element ).is( filter );
9948      };
9949    }
9950    if ( typeof filter == 'function' ) {
9951      // use filter as function
9952      return function( item ) {
9953        return filter( item.element );
9954      };
9955    }
9956    // default, use filter as selector string
9957    return function( item ) {
9958      return matchesSelector( item.element, filter );
9959    };
9960  };
9961
9962  // -------------------------- sorting -------------------------- //
9963
9964  /**
9965   * @params {Array} elems
9966   * @public
9967   */
9968  proto.updateSortData = function( elems ) {
9969    // get items
9970    var items;
9971    if ( elems ) {
9972      elems = utils.makeArray( elems );
9973      items = this.getItems( elems );
9974    } else {
9975      // update all items if no elems provided
9976      items = this.items;
9977    }
9978
9979    this._getSorters();
9980    this._updateItemsSortData( items );
9981  };
9982
9983  proto._getSorters = function() {
9984    var getSortData = this.options.getSortData;
9985    for ( var key in getSortData ) {
9986      var sorter = getSortData[ key ];
9987      this._sorters[ key ] = mungeSorter( sorter );
9988    }
9989  };
9990
9991  /**
9992   * @params {Array} items - of Isotope.Items
9993   * @private
9994   */
9995  proto._updateItemsSortData = function( items ) {
9996    // do not update if no items
9997    var len = items && items.length;
9998
9999    for ( var i=0; len && i < len; i++ ) {
10000      var item = items[i];
10001      item.updateSortData();
10002    }
10003  };
10004
10005  // ----- munge sorter ----- //
10006
10007  // encapsulate this, as we just need mungeSorter
10008  // other functions in here are just for munging
10009  var mungeSorter = ( function() {
10010    // add a magic layer to sorters for convienent shorthands
10011    // `.foo-bar` will use the text of .foo-bar querySelector
10012    // `[foo-bar]` will use attribute
10013    // you can also add parser
10014    // `.foo-bar parseInt` will parse that as a number
10015    function mungeSorter( sorter ) {
10016      // if not a string, return function or whatever it is
10017      if ( typeof sorter != 'string' ) {
10018        return sorter;
10019      }
10020      // parse the sorter string
10021      var args = trim( sorter ).split(' ');
10022      var query = args[0];
10023      // check if query looks like [an-attribute]
10024      var attrMatch = query.match( /^\[(.+)\]$/ );
10025      var attr = attrMatch && attrMatch[1];
10026      var getValue = getValueGetter( attr, query );
10027      // use second argument as a parser
10028      var parser = Isotope.sortDataParsers[ args[1] ];
10029      // parse the value, if there was a parser
10030      sorter = parser ? function( elem ) {
10031        return elem && parser( getValue( elem ) );
10032      } :
10033      // otherwise just return value
10034      function( elem ) {
10035        return elem && getValue( elem );
10036      };
10037
10038      return sorter;
10039    }
10040
10041    // get an attribute getter, or get text of the querySelector
10042    function getValueGetter( attr, query ) {
10043      // if query looks like [foo-bar], get attribute
10044      if ( attr ) {
10045        return function getAttribute( elem ) {
10046          return elem.getAttribute( attr );
10047        };
10048      }
10049
10050      // otherwise, assume its a querySelector, and get its text
10051      return function getChildText( elem ) {
10052        var child = elem.querySelector( query );
10053        return child && child.textContent;
10054      };
10055    }
10056
10057    return mungeSorter;
10058  })();
10059
10060  // parsers used in getSortData shortcut strings
10061  Isotope.sortDataParsers = {
10062    'parseInt': function( val ) {
10063      return parseInt( val, 10 );
10064    },
10065    'parseFloat': function( val ) {
10066      return parseFloat( val );
10067    }
10068  };
10069
10070  // ----- sort method ----- //
10071
10072  // sort filteredItem order
10073  proto._sort = function() {
10074    if ( !this.options.sortBy ) {
10075      return;
10076    }
10077    // keep track of sortBy History
10078    var sortBys = utils.makeArray( this.options.sortBy );
10079    if ( !this._getIsSameSortBy( sortBys ) ) {
10080      // concat all sortBy and sortHistory, add to front, oldest goes in last
10081      this.sortHistory = sortBys.concat( this.sortHistory );
10082    }
10083    // sort magic
10084    var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending );
10085    this.filteredItems.sort( itemSorter );
10086  };
10087
10088  // check if sortBys is same as start of sortHistory
10089  proto._getIsSameSortBy = function( sortBys ) {
10090    for ( var i=0; i < sortBys.length; i++ ) {
10091      if ( sortBys[i] != this.sortHistory[i] ) {
10092        return false;
10093      }
10094    }
10095    return true;
10096  };
10097
10098  // returns a function used for sorting
10099  function getItemSorter( sortBys, sortAsc ) {
10100    return function sorter( itemA, itemB ) {
10101      // cycle through all sortKeys
10102      for ( var i = 0; i < sortBys.length; i++ ) {
10103        var sortBy = sortBys[i];
10104        var a = itemA.sortData[ sortBy ];
10105        var b = itemB.sortData[ sortBy ];
10106        if ( a > b || a < b ) {
10107          // if sortAsc is an object, use the value given the sortBy key
10108          var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
10109          var direction = isAscending ? 1 : -1;
10110          return ( a > b ? 1 : -1 ) * direction;
10111        }
10112      }
10113      return 0;
10114    };
10115  }
10116
10117  // -------------------------- methods -------------------------- //
10118
10119  // get layout mode
10120  proto._mode = function() {
10121    var layoutMode = this.options.layoutMode;
10122    var mode = this.modes[ layoutMode ];
10123    if ( !mode ) {
10124      // TODO console.error
10125      throw new Error( 'No layout mode: ' + layoutMode );
10126    }
10127    // HACK sync mode's options
10128    // any options set after init for layout mode need to be synced
10129    mode.options = this.options[ layoutMode ];
10130    return mode;
10131  };
10132
10133  proto._resetLayout = function() {
10134    // trigger original reset layout
10135    Outlayer.prototype._resetLayout.call( this );
10136    this._mode()._resetLayout();
10137  };
10138
10139  proto._getItemLayoutPosition = function( item  ) {
10140    return this._mode()._getItemLayoutPosition( item );
10141  };
10142
10143  proto._manageStamp = function( stamp ) {
10144    this._mode()._manageStamp( stamp );
10145  };
10146
10147  proto._getContainerSize = function() {
10148    return this._mode()._getContainerSize();
10149  };
10150
10151  proto.needsResizeLayout = function() {
10152    return this._mode().needsResizeLayout();
10153  };
10154
10155  // -------------------------- adding & removing -------------------------- //
10156
10157  // HEADS UP overwrites default Outlayer appended
10158  proto.appended = function( elems ) {
10159    var items = this.addItems( elems );
10160    if ( !items.length ) {
10161      return;
10162    }
10163    // filter, layout, reveal new items
10164    var filteredItems = this._filterRevealAdded( items );
10165    // add to filteredItems
10166    this.filteredItems = this.filteredItems.concat( filteredItems );
10167  };
10168
10169  // HEADS UP overwrites default Outlayer prepended
10170  proto.prepended = function( elems ) {
10171    var items = this._itemize( elems );
10172    if ( !items.length ) {
10173      return;
10174    }
10175    // start new layout
10176    this._resetLayout();
10177    this._manageStamps();
10178    // filter, layout, reveal new items
10179    var filteredItems = this._filterRevealAdded( items );
10180    // layout previous items
10181    this.layoutItems( this.filteredItems );
10182    // add to items and filteredItems
10183    this.filteredItems = filteredItems.concat( this.filteredItems );
10184    this.items = items.concat( this.items );
10185  };
10186
10187  proto._filterRevealAdded = function( items ) {
10188    var filtered = this._filter( items );
10189    this.hide( filtered.needHide );
10190    // reveal all new items
10191    this.reveal( filtered.matches );
10192    // layout new items, no transition
10193    this.layoutItems( filtered.matches, true );
10194    return filtered.matches;
10195  };
10196
10197  /**
10198   * Filter, sort, and layout newly-appended item elements
10199   * @param {Array or NodeList or Element} elems
10200   */
10201  proto.insert = function( elems ) {
10202    var items = this.addItems( elems );
10203    if ( !items.length ) {
10204      return;
10205    }
10206    // append item elements
10207    var i, item;
10208    var len = items.length;
10209    for ( i=0; i < len; i++ ) {
10210      item = items[i];
10211      this.element.appendChild( item.element );
10212    }
10213    // filter new stuff
10214    var filteredInsertItems = this._filter( items ).matches;
10215    // set flag
10216    for ( i=0; i < len; i++ ) {
10217      items[i].isLayoutInstant = true;
10218    }
10219    this.arrange();
10220    // reset flag
10221    for ( i=0; i < len; i++ ) {
10222      delete items[i].isLayoutInstant;
10223    }
10224    this.reveal( filteredInsertItems );
10225  };
10226
10227  var _remove = proto.remove;
10228  proto.remove = function( elems ) {
10229    elems = utils.makeArray( elems );
10230    var removeItems = this.getItems( elems );
10231    // do regular thing
10232    _remove.call( this, elems );
10233    // bail if no items to remove
10234    var len = removeItems && removeItems.length;
10235    // remove elems from filteredItems
10236    for ( var i=0; len && i < len; i++ ) {
10237      var item = removeItems[i];
10238      // remove item from collection
10239      utils.removeFrom( this.filteredItems, item );
10240    }
10241  };
10242
10243  proto.shuffle = function() {
10244    // update random sortData
10245    for ( var i=0; i < this.items.length; i++ ) {
10246      var item = this.items[i];
10247      item.sortData.random = Math.random();
10248    }
10249    this.options.sortBy = 'random';
10250    this._sort();
10251    this._layout();
10252  };
10253
10254  /**
10255   * trigger fn without transition
10256   * kind of hacky to have this in the first place
10257   * @param {Function} fn
10258   * @param {Array} args
10259   * @returns ret
10260   * @private
10261   */
10262  proto._noTransition = function( fn, args ) {
10263    // save transitionDuration before disabling
10264    var transitionDuration = this.options.transitionDuration;
10265    // disable transition
10266    this.options.transitionDuration = 0;
10267    // do it
10268    var returnValue = fn.apply( this, args );
10269    // re-enable transition for reveal
10270    this.options.transitionDuration = transitionDuration;
10271    return returnValue;
10272  };
10273
10274  // ----- helper methods ----- //
10275
10276  /**
10277   * getter method for getting filtered item elements
10278   * @returns {Array} elems - collection of item elements
10279   */
10280  proto.getFilteredItemElements = function() {
10281    return this.filteredItems.map( function( item ) {
10282      return item.element;
10283    });
10284  };
10285
10286  // -----  ----- //
10287
10288  return Isotope;
10289
10290}));
10291
10292/*!
10293 * Packery layout mode PACKAGED v2.0.1
10294 * sub-classes Packery
10295 */
10296
10297/**
10298 * Rect
10299 * low-level utility class for basic geometry
10300 */
10301
10302( function( window, factory ) {
10303  // universal module definition
10304  /* jshint strict: false */ /* globals define, module */
10305  if ( typeof define == 'function' && define.amd ) {
10306    // AMD
10307    define( 'packery/js/rect',factory );
10308  } else if ( typeof module == 'object' && module.exports ) {
10309    // CommonJS
10310    module.exports = factory();
10311  } else {
10312    // browser global
10313    window.Packery = window.Packery || {};
10314    window.Packery.Rect = factory();
10315  }
10316
10317}( window, function factory() {
10318
10319
10320// -------------------------- Rect -------------------------- //
10321
10322function Rect( props ) {
10323  // extend properties from defaults
10324  for ( var prop in Rect.defaults ) {
10325    this[ prop ] = Rect.defaults[ prop ];
10326  }
10327
10328  for ( prop in props ) {
10329    this[ prop ] = props[ prop ];
10330  }
10331
10332}
10333
10334Rect.defaults = {
10335  x: 0,
10336  y: 0,
10337  width: 0,
10338  height: 0
10339};
10340
10341var proto = Rect.prototype;
10342
10343/**
10344 * Determines whether or not this rectangle wholly encloses another rectangle or point.
10345 * @param {Rect} rect
10346 * @returns {Boolean}
10347**/
10348proto.contains = function( rect ) {
10349  // points don't have width or height
10350  var otherWidth = rect.width || 0;
10351  var otherHeight = rect.height || 0;
10352  return this.x <= rect.x &&
10353    this.y <= rect.y &&
10354    this.x + this.width >= rect.x + otherWidth &&
10355    this.y + this.height >= rect.y + otherHeight;
10356};
10357
10358/**
10359 * Determines whether or not the rectangle intersects with another.
10360 * @param {Rect} rect
10361 * @returns {Boolean}
10362**/
10363proto.overlaps = function( rect ) {
10364  var thisRight = this.x + this.width;
10365  var thisBottom = this.y + this.height;
10366  var rectRight = rect.x + rect.width;
10367  var rectBottom = rect.y + rect.height;
10368
10369  // http://stackoverflow.com/a/306332
10370  return this.x < rectRight &&
10371    thisRight > rect.x &&
10372    this.y < rectBottom &&
10373    thisBottom > rect.y;
10374};
10375
10376/**
10377 * @param {Rect} rect - the overlapping rect
10378 * @returns {Array} freeRects - rects representing the area around the rect
10379**/
10380proto.getMaximalFreeRects = function( rect ) {
10381
10382  // if no intersection, return false
10383  if ( !this.overlaps( rect ) ) {
10384    return false;
10385  }
10386
10387  var freeRects = [];
10388  var freeRect;
10389
10390  var thisRight = this.x + this.width;
10391  var thisBottom = this.y + this.height;
10392  var rectRight = rect.x + rect.width;
10393  var rectBottom = rect.y + rect.height;
10394
10395  // top
10396  if ( this.y < rect.y ) {
10397    freeRect = new Rect({
10398      x: this.x,
10399      y: this.y,
10400      width: this.width,
10401      height: rect.y - this.y
10402    });
10403    freeRects.push( freeRect );
10404  }
10405
10406  // right
10407  if ( thisRight > rectRight ) {
10408    freeRect = new Rect({
10409      x: rectRight,
10410      y: this.y,
10411      width: thisRight - rectRight,
10412      height: this.height
10413    });
10414    freeRects.push( freeRect );
10415  }
10416
10417  // bottom
10418  if ( thisBottom > rectBottom ) {
10419    freeRect = new Rect({
10420      x: this.x,
10421      y: rectBottom,
10422      width: this.width,
10423      height: thisBottom - rectBottom
10424    });
10425    freeRects.push( freeRect );
10426  }
10427
10428  // left
10429  if ( this.x < rect.x ) {
10430    freeRect = new Rect({
10431      x: this.x,
10432      y: this.y,
10433      width: rect.x - this.x,
10434      height: this.height
10435    });
10436    freeRects.push( freeRect );
10437  }
10438
10439  return freeRects;
10440};
10441
10442proto.canFit = function( rect ) {
10443  return this.width >= rect.width && this.height >= rect.height;
10444};
10445
10446return Rect;
10447
10448}));
10449
10450/**
10451 * Packer
10452 * bin-packing algorithm
10453 */
10454
10455( function( window, factory ) {
10456  // universal module definition
10457  /* jshint strict: false */ /* globals define, module, require */
10458  if ( typeof define == 'function' && define.amd ) {
10459    // AMD
10460    define( 'packery/js/packer',[ './rect' ], factory );
10461  } else if ( typeof module == 'object' && module.exports ) {
10462    // CommonJS
10463    module.exports = factory(
10464      require('./rect')
10465    );
10466  } else {
10467    // browser global
10468    var Packery = window.Packery = window.Packery || {};
10469    Packery.Packer = factory( Packery.Rect );
10470  }
10471
10472}( window, function factory( Rect ) {
10473
10474
10475// -------------------------- Packer -------------------------- //
10476
10477/**
10478 * @param {Number} width
10479 * @param {Number} height
10480 * @param {String} sortDirection
10481 *   topLeft for vertical, leftTop for horizontal
10482 */
10483function Packer( width, height, sortDirection ) {
10484  this.width = width || 0;
10485  this.height = height || 0;
10486  this.sortDirection = sortDirection || 'downwardLeftToRight';
10487
10488  this.reset();
10489}
10490
10491var proto = Packer.prototype;
10492
10493proto.reset = function() {
10494  this.spaces = [];
10495
10496  var initialSpace = new Rect({
10497    x: 0,
10498    y: 0,
10499    width: this.width,
10500    height: this.height
10501  });
10502
10503  this.spaces.push( initialSpace );
10504  // set sorter
10505  this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight;
10506};
10507
10508// change x and y of rect to fit with in Packer's available space
10508s
10509proto.pack = function( rect ) {
10510  for ( var i=0; i < this.spaces.length; i++ ) {
10511    var space = this.spaces[i];
10512    if ( space.canFit( rect ) ) {
10513      this.placeInSpace( rect, space );
10514      break;
10515    }
10516  }
10517};
10518
10519proto.columnPack = function( rect ) {
10520  for ( var i=0; i < this.spaces.length; i++ ) {
10521    var space = this.spaces[i];
10522    var canFitInSpaceColumn = space.x <= rect.x &&
10523      space.x + space.width >= rect.x + rect.width &&
10524      space.height >= rect.height - 0.01; // fudge number for rounding error
10525    if ( canFitInSpaceColumn ) {
10526      rect.y = space.y;
10527      this.placed( rect );
10528      break;
10529    }
10530  }
10531};
10532
10533proto.rowPack = function( rect ) {
10534  for ( var i=0; i < this.spaces.length; i++ ) {
10535    var space = this.spaces[i];
10536    var canFitInSpaceRow = space.y <= rect.y &&
10537      space.y + space.height >= rect.y + rect.height &&
10538      space.width >= rect.width - 0.01; // fudge number for rounding error
10539    if ( canFitInSpaceRow ) {
10540      rect.x = space.x;
10541      this.placed( rect );
10542      break;
10543    }
10544  }
10545};
10546
10547proto.placeInSpace = function( rect, space ) {
10548  // place rect in space
10549  rect.x = space.x;
10550  rect.y = space.y;
10551
10552  this.placed( rect );
10553};
10554
10555// update spaces with placed rect
10556proto.placed = function( rect ) {
10557  // update spaces
10558  var revisedSpaces = [];
10559  for ( var i=0; i < this.spaces.length; i++ ) {
10560    var space = this.spaces[i];
10561    var newSpaces = space.getMaximalFreeRects( rect );
10562    // add either the original space or the new spaces to the revised spaces
10563    if ( newSpaces ) {
10564      revisedSpaces.push.apply( revisedSpaces, newSpaces );
10565    } else {
10566      revisedSpaces.push( space );
10567    }
10568  }
10569
10570  this.spaces = revisedSpaces;
10571
10572  this.mergeSortSpaces();
10573};
10574
10575proto.mergeSortSpaces = function() {
10576  // remove redundant spaces
10577  Packer.mergeRects( this.spaces );
10578  this.spaces.sort( this.sorter );
10579};
10580
10581// add a space back
10582proto.addSpace = function( rect ) {
10583  this.spaces.push( rect );
10584  this.mergeSortSpaces();
10585};
10586
10587// -------------------------- utility functions -------------------------- //
10588
10589/**
10590 * Remove redundant rectangle from array of rectangles
10591 * @param {Array} rects: an array of Rects
10592 * @returns {Array} rects: an array of Rects
10593**/
10594Packer.mergeRects = function( rects ) {
10595  var i = 0;
10596  var rect = rects[i];
10597
10598  rectLoop:
10599  while ( rect ) {
10600    var j = 0;
10601    var compareRect = rects[ i + j ];
10602
10603    while ( compareRect ) {
10604      if  ( compareRect == rect ) {
10605        j++; // next
10606      } else if ( compareRect.contains( rect ) ) {
10607        // remove rect
10608        rects.splice( i, 1 );
10609        rect = rects[i]; // set next rect
10610        continue rectLoop; // bail on compareLoop
10611      } else if ( rect.contains( compareRect ) ) {
10612        // remove compareRect
10613        rects.splice( i + j, 1 );
10614      } else {
10615        j++;
10616      }
10617      compareRect = rects[ i + j ]; // set next compareRect
10618    }
10619    i++;
10620    rect = rects[i];
10621  }
10622
10623  return rects;
10624};
10625
10626
10627// -------------------------- sorters -------------------------- //
10628
10629// functions for sorting rects in order
10630var sorters = {
10631  // top down, then left to right
10632  downwardLeftToRight: function( a, b ) {
10633    return a.y - b.y || a.x - b.x;
10634  },
10635  // left to right, then top down
10636  rightwardTopToBottom: function( a, b ) {
10637    return a.x - b.x || a.y - b.y;
10638  }
10639};
10640
10641
10642// --------------------------  -------------------------- //
10643
10644return Packer;
10645
10646}));
10647
10648/**
10649 * Packery Item Element
10650**/
10651
10652( function( window, factory ) {
10653  // universal module definition
10654  /* jshint strict: false */ /* globals define, module, require */
10655  if ( typeof define == 'function' && define.amd ) {
10656    // AMD
10657    define( 'packery/js/item',[
10658        'outlayer/outlayer',
10659        './rect'
10660      ],
10661      factory );
10662  } else if ( typeof module == 'object' && module.exports ) {
10663    // CommonJS
10664    module.exports = factory(
10665      require('outlayer'),
10666      require('./rect')
10667    );
10668  } else {
10669    // browser global
10670    window.Packery.Item = factory(
10671      window.Outlayer,
10672      window.Packery.Rect
10673    );
10674  }
10675
10676}( window, function factory( Outlayer, Rect ) {
10677
10678
10679// -------------------------- Item -------------------------- //
10680
10681var docElemStyle = document.documentElement.style;
10682
10683var transformProperty = typeof docElemStyle.transform == 'string' ?
10684  'transform' : 'WebkitTransform';
10685
10686// sub-class Item
10687var Item = function PackeryItem() {
10688  Outlayer.Item.apply( this, arguments );
10689};
10690
10691var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
10692
10693var __create = proto._create;
10694proto._create = function() {
10695  // call default _create logic
10696  __create.call( this );
10697  this.rect = new Rect();
10698};
10699
10700var _moveTo = proto.moveTo;
10701proto.moveTo = function( x, y ) {
10702  // don't shift 1px while dragging
10703  var dx = Math.abs( this.position.x - x );
10704  var dy = Math.abs( this.position.y - y );
10705
10706  var canHackGoTo = this.layout.dragItemCount && !this.isPlacing &&
10707    !this.isTransitioning && dx < 1 && dy < 1;
10708  if ( canHackGoTo ) {
10709    this.goTo( x, y );
10710    return;
10711  }
10712  _moveTo.apply( this, arguments );
10713};
10714
10715// -------------------------- placing -------------------------- //
10716
10717proto.enablePlacing = function() {
10718  this.removeTransitionStyles();
10719  // remove transform property from transition
10720  if ( this.isTransitioning && transformProperty ) {
10721    this.element.style[ transformProperty ] = 'none';
10722  }
10723  this.isTransitioning = false;
10724  this.getSize();
10725  this.layout._setRectSize( this.element, this.rect );
10726  this.isPlacing = true;
10727};
10728
10729proto.disablePlacing = function() {
10730  this.isPlacing = false;
10731};
10732
10733// -----  ----- //
10734
10735// remove element from DOM
10736proto.removeElem = function() {
10737  this.element.parentNode.removeChild( this.element );
10738  // add space back to packer
10739  this.layout.packer.addSpace( this.rect );
10740  this.emitEvent( 'remove', [ this ] );
10741};
10742
10743// ----- dropPlaceholder ----- //
10744
10745proto.showDropPlaceholder = function() {
10746  var dropPlaceholder = this.dropPlaceholder;
10747  if ( !dropPlaceholder ) {
10748    // create dropPlaceholder
10749    dropPlaceholder = this.dropPlaceholder = document.createElement('div');
10750    dropPlaceholder.className = 'packery-drop-placeholder';
10751    dropPlaceholder.style.position = 'absolute';
10752  }
10753
10754  dropPlaceholder.style.width = this.size.width + 'px';
10755  dropPlaceholder.style.height = this.size.height + 'px';
10756  this.positionDropPlaceholder();
10757  this.layout.element.appendChild( dropPlaceholder );
10758};
10759
10760proto.positionDropPlaceholder = function() {
10761  this.dropPlaceholder.style[ transformProperty ] = 'translate(' +
10762    this.rect.x + 'px, ' + this.rect.y + 'px)';
10763};
10764
10765proto.hideDropPlaceholder = function() {
10766  this.layout.element.removeChild( this.dropPlaceholder );
10767};
10768
10769// -----  ----- //
10770
10771return Item;
10772
10773}));
10774
10775/*!
10776 * Packery v2.0.0
10777 * Gapless, draggable grid layouts
10778 *
10779 * Licensed GPLv3 for open source use
10780 * or Packery Commercial License for commercial use
10781 *
10782 * http://packery.metafizzy.co
10783 * Copyright 2016 Metafizzy
10784 */
10785
10786( function( window, factory ) {
10787  // universal module definition
10788  /* jshint strict: false */ /* globals define, module, require */
10789  if ( typeof define == 'function' && define.amd ) {
10790    // AMD
10791    define( 'packery/js/packery',[
10792        'get-size/get-size',
10793        'outlayer/outlayer',
10794        './rect',
10795        './packer',
10796        './item'
10797      ],
10798      factory );
10799  } else if ( typeof module == 'object' && module.exports ) {
10800    // CommonJS
10801    module.exports = factory(
10802      require('get-size'),
10803      require('outlayer'),
10804      require('./rect'),
10805      require('./packer'),
10806      require('./item')
10807    );
10808  } else {
10809    // browser global
10810    window.Packery = factory(
10811      window.getSize,
10812      window.Outlayer,
10813      window.Packery.Rect,
10814      window.Packery.Packer,
10815      window.Packery.Item
10816    );
10817  }
10818
10819}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) {
10820
10821
10822// ----- Rect ----- //
10823
10824// allow for pixel rounding errors IE8-IE11 & Firefox; #227
10825Rect.prototype.canFit = function( rect ) {
10826  return this.width >= rect.width - 1 && this.height >= rect.height - 1;
10827};
10828
10829// -------------------------- Packery -------------------------- //
10830
10831// create an Outlayer layout class
10832var Packery = Outlayer.create('packery');
10833Packery.Item = Item;
10834
10835var proto = Packery.prototype;
10836
10837proto._create = function() {
10838  // call super
10839  Outlayer.prototype._create.call( this );
10840
10841  // initial properties
10842  this.packer = new Packer();
10843  // packer for drop targets
10844  this.shiftPacker = new Packer();
10845  this.isEnabled = true;
10846
10847  this.dragItemCount = 0;
10848
10849  // create drag handlers
10850  var _this = this;
10851  this.handleDraggabilly = {
10852    dragStart: function() {
10853      _this.itemDragStart( this.element );
10854    },
10855    dragMove: function() {
10856      _this.itemDragMove( this.element, this.position.x, this.position.y );
10857    },
10858    dragEnd: function() {
10859      _this.itemDragEnd( this.element );
10860    }
10861  };
10862
10863  this.handleUIDraggable = {
10864    start: function handleUIDraggableStart( event, ui ) {
10865      // HTML5 may trigger dragstart, dismiss HTML5 dragging
10866      if ( !ui ) {
10867        return;
10868      }
10869      _this.itemDragStart( event.currentTarget );
10870    },
10871    drag: function handleUIDraggableDrag( event, ui ) {
10872      if ( !ui ) {
10873        return;
10874      }
10875      _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top );
10876    },
10877    stop: function handleUIDraggableStop( event, ui ) {
10878      if ( !ui ) {
10879        return;
10880      }
10881      _this.itemDragEnd( event.currentTarget );
10882    }
10883  };
10884
10885};
10886
10887
10888// ----- init & layout ----- //
10889
10890/**
10891 * logic before any new layout
10892 */
10893proto._resetLayout = function() {
10894  this.getSize();
10895
10896  this._getMeasurements();
10897
10898  // reset packer
10899  var width, height, sortDirection;
10900  // packer settings, if horizontal or vertical
10901  if ( this._getOption('horizontal') ) {
10902    width = Infinity;
10903    height = this.size.innerHeight + this.gutter;
10904    sortDirection = 'rightwardTopToBottom';
10905  } else {
10906    width = this.size.innerWidth + this.gutter;
10907    height = Infinity;
10908    sortDirection = 'downwardLeftToRight';
10909  }
10910
10911  this.packer.width = this.shiftPacker.width = width;
10912  this.packer.height = this.shiftPacker.height = height;
10913  this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection;
10914
10915  this.packer.reset();
10916
10917  // layout
10918  this.maxY = 0;
10919  this.maxX = 0;
10920};
10921
10922/**
10923 * update columnWidth, rowHeight, & gutter
10924 * @private
10925 */
10926proto._getMeasurements = function() {
10927  this._getMeasurement( 'columnWidth', 'width' );
10928  this._getMeasurement( 'rowHeight', 'height' );
10929  this._getMeasurement( 'gutter', 'width' );
10930};
10931
10932proto._getItemLayoutPosition = function( item ) {
10933  this._setRectSize( item.element, item.rect );
10934  if ( this.isShifting || this.dragItemCount > 0 ) {
10935    var packMethod = this._getPackMethod();
10936    this.packer[ packMethod ]( item.rect );
10937  } else {
10938    this.packer.pack( item.rect );
10939  }
10940
10941  this._setMaxXY( item.rect );
10942  return item.rect;
10943};
10944
10945proto.shiftLayout = function() {
10946  this.isShifting = true;
10947  this.layout();
10948  delete this.isShifting;
10949};
10950
10951proto._getPackMethod = function() {
10952  return this._getOption('horizontal') ? 'rowPack' : 'columnPack';
10953};
10954
10955
10956/**
10957 * set max X and Y value, for size of container
10958 * @param {Packery.Rect} rect
10959 * @private
10960 */
10961proto._setMaxXY = function( rect ) {
10962  this.maxX = Math.max( rect.x + rect.width, this.maxX );
10963  this.maxY = Math.max( rect.y + rect.height, this.maxY );
10964};
10965
10966/**
10967 * set the width and height of a rect, applying columnWidth and rowHeight
10968 * @param {Element} elem
10969 * @param {Packery.Rect} rect
10970 */
10971proto._setRectSize = function( elem, rect ) {
10972  var size = getSize( elem );
10973  var w = size.outerWidth;
10974  var h = size.outerHeight;
10975  // size for columnWidth and rowHeight, if available
10976  // only check if size is non-zero, #177
10977  if ( w || h ) {
10978    w = this._applyGridGutter( w, this.columnWidth );
10979    h = this._applyGridGutter( h, this.rowHeight );
10980  }
10981  // rect must fit in packer
10982  rect.width = Math.min( w, this.packer.width );
10983  rect.height = Math.min( h, this.packer.height );
10984};
10985
10986/**
10987 * fits item to columnWidth/rowHeight and adds gutter
10988 * @param {Number} measurement - item width or height
10989 * @param {Number} gridSize - columnWidth or rowHeight
10990 * @returns measurement
10991 */
10992proto._applyGridGutter = function( measurement, gridSize ) {
10993  // just add gutter if no gridSize
10994  if ( !gridSize ) {
10995    return measurement + this.gutter;
10996  }
10997  gridSize += this.gutter;
10998  // fit item to columnWidth/rowHeight
10999  var remainder = measurement % gridSize;
11000  var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
11001  measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize;
11002  return measurement;
11003};
11004
11005proto._getContainerSize = function() {
11006  if ( this._getOption('horizontal') ) {
11007    return {
11008      width: this.maxX - this.gutter
11009    };
11010  } else {
11011    return {
11012      height: this.maxY - this.gutter
11013    };
11014  }
11015};
11016
11017
11018// -------------------------- stamp -------------------------- //
11019
11020/**
11021 * makes space for element
11022 * @param {Element} elem
11023 */
11024proto._manageStamp = function( elem ) {
11025
11026  var item = this.getItem( elem );
11027  var rect;
11028  if ( item && item.isPlacing ) {
11029    rect = item.rect;
11030  } else {
11031    var offset = this._getElementOffset( elem );
11032    rect = new Rect({
11033      x: this._getOption('originLeft') ? offset.left : offset.right,
11034      y: this._getOption('originTop') ? offset.top : offset.bottom
11035    });
11036  }
11037
11038  this._setRectSize( elem, rect );
11039  // save its space in the packer
11040  this.packer.placed( rect );
11041  this._setMaxXY( rect );
11042};
11043
11044// -------------------------- methods -------------------------- //
11045
11046function verticalSorter( a, b ) {
11047  return a.position.y - b.position.y || a.position.x - b.position.x;
11048}
11049
11050function horizontalSorter( a, b ) {
11051  return a.position.x - b.position.x || a.position.y - b.position.y;
11052}
11053
11054proto.sortItemsByPosition = function() {
11055  var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter;
11056  this.items.sort( sorter );
11057};
11058
11059/**
11060 * Fit item element in its current position
11061 * Packery will position elements around it
11062 * useful for expanding elements
11063 *
11064 * @param {Element} elem
11065 * @param {Number} x - horizontal destination position, optional
11066 * @param {Number} y - vertical destination position, optional
11067 */
11068proto.fit = function( elem, x, y ) {
11069  var item = this.getItem( elem );
11070  if ( !item ) {
11071    return;
11072  }
11073
11074  // stamp item to get it out of layout
11075  this.stamp( item.element );
11076  // set placing flag
11077  item.enablePlacing();
11078  this.updateShiftTargets( item );
11079  // fall back to current position for fitting
11080  x = x === undefined ? item.rect.x: x;
11081  y = y === undefined ? item.rect.y: y;
11082  // position it best at its destination
11083  this.shift( item, x, y );
11084  this._bindFitEvents( item );
11085  item.moveTo( item.rect.x, item.rect.y );
11086  // layout everything else
11087  this.shiftLayout();
11088  // return back to regularly scheduled programming
11089  this.unstamp( item.element );
11090  this.sortItemsByPosition();
11091  item.disablePlacing();
11092};
11093
11094/**
11095 * emit event when item is fit and other items are laid out
11096 * @param {Packery.Item} item
11097 * @private
11098 */
11099proto._bindFitEvents = function( item ) {
11100  var _this = this;
11101  var ticks = 0;
11102  function onLayout() {
11103    ticks++;
11104    if ( ticks != 2 ) {
11105      return;
11106    }
11107    _this.dispatchEvent( 'fitComplete', null, [ item ] );
11108  }
11109  // when item is laid out
11110  item.once( 'layout', onLayout );
11111  // when all items are laid out
11112  this.once( 'layoutComplete', onLayout );
11113};
11114
11115// -------------------------- resize -------------------------- //
11116
11117// debounced, layout on resize
11118proto.resize = function() {
11119  // don't trigger if size did not change
11120  // or if resize was unbound. See #285, outlayer#9
11121  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
11122    return;
11123  }
11124
11125  if ( this.options.shiftPercentResize ) {
11126    this.resizeShiftPercentLayout();
11127  } else {
11128    this.layout();
11129  }
11130};
11131
11132/**
11133 * check if layout is needed post layout
11134 * @returns Boolean
11135 */
11136proto.needsResizeLayout = function() {
11137  var size = getSize( this.element );
11138  var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth';
11139  return size[ innerSize ] != this.size[ innerSize ];
11140};
11141
11142proto.resizeShiftPercentLayout = function() {
11143  var items = this._getItemsForLayout( this.items );
11144
11145  var isHorizontal = this._getOption('horizontal');
11146  var coord = isHorizontal ? 'y' : 'x';
11147  var measure = isHorizontal ? 'height' : 'width';
11148  var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';
11149  var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth';
11150
11151  // proportional re-align items
11152  var previousSegment = this[ segmentName ];
11153  previousSegment = previousSegment && previousSegment + this.gutter;
11154
11155  if ( previousSegment ) {
11156    this._getMeasurements();
11157    var currentSegment = this[ segmentName ] + this.gutter;
11158    items.forEach( function( item ) {
11159      var seg = Math.round( item.rect[ coord ] / previousSegment );
11160      item.rect[ coord ] = seg * currentSegment;
11161    });
11162  } else {
11163    var currentSize = getSize( this.element )[ innerSize ] + this.gutter;
11164    var previousSize = this.packer[ measure ];
11165    items.forEach( function( item ) {
11166      item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize;
11167    });
11168  }
11169
11170  this.shiftLayout();
11171};
11172
11173// -------------------------- drag -------------------------- //
11174
11175/**
11176 * handle an item drag start event
11177 * @param {Element} elem
11178 */
11179proto.itemDragStart = function( elem ) {
11180  if ( !this.isEnabled ) {
11181    return;
11182  }
11183  this.stamp( elem );
11184  // this.ignore( elem );
11185  var item = this.getItem( elem );
11186  if ( !item ) {
11187    return;
11188  }
11189
11190  item.enablePlacing();
11191  item.showDropPlaceholder();
11192  this.dragItemCount++;
11193  this.updateShiftTargets( item );
11194};
11195
11196proto.updateShiftTargets = function( dropItem ) {
11197  this.shiftPacker.reset();
11198
11199  // pack stamps
11200  this._getBoundingRect();
11201  var isOriginLeft = this._getOption('originLeft');
11202  var isOriginTop = this._getOption('originTop');
11203  this.stamps.forEach( function( stamp ) {
11204    // ignore dragged item
11205    var item = this.getItem( stamp );
11206    if ( item && item.isPlacing ) {
11207      return;
11208    }
11209    var offset = this._getElementOffset( stamp );
11210    var rect = new Rect({
11211      x: isOriginLeft ? offset.left : offset.right,
11212      y: isOriginTop ? offset.top : offset.bottom
11213    });
11214    this._setRectSize( stamp, rect );
11215    // save its space in the packer
11216    this.shiftPacker.placed( rect );
11217  }, this );
11218
11219  // reset shiftTargets
11220  var isHorizontal = this._getOption('horizontal');
11221  var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';
11222  var measure = isHorizontal ? 'height' : 'width';
11223
11224  this.shiftTargetKeys = [];
11225  this.shiftTargets = [];
11226  var boundsSize;
11227  var segment = this[ segmentName ];
11228  segment = segment && segment + this.gutter;
11229
11230  if ( segment ) {
11231    var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment );
11232    var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment );
11233    boundsSize = ( segs - segmentSpan ) * segment;
11234    // add targets on top
11235    for ( var i=0; i < segs; i++ ) {
11236      this._addShiftTarget( i * segment, 0, boundsSize );
11237    }
11238  } else {
11239    boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ];
11240    this._addShiftTarget( 0, 0, boundsSize );
11241  }
11242
11243  // pack each item to measure where shiftTargets are
11244  var items = this._getItemsForLayout( this.items );
11245  var packMethod = this._getPackMethod();
11246  items.forEach( function( item ) {
11247    var rect = item.rect;
11248    this._setRectSize( item.element, rect );
11249    this.shiftPacker[ packMethod ]( rect );
11250
11251    // add top left corner
11252    this._addShiftTarget( rect.x, rect.y, boundsSize );
11253    // add bottom left / top right corner
11254    var cornerX = isHorizontal ? rect.x + rect.width : rect.x;
11255    var cornerY = isHorizontal ? rect.y : rect.y + rect.height;
11256    this._addShiftTarget( cornerX, cornerY, boundsSize );
11257
11258    if ( segment ) {
11259      // add targets for each column on bottom / row on right
11260      var segSpan = Math.round( rect[ measure ] / segment );
11261      for ( var i=1; i < segSpan; i++ ) {
11262        var segX = isHorizontal ? cornerX : rect.x + segment * i;
11263        var segY = isHorizontal ? rect.y + segment * i : cornerY;
11264        this._addShiftTarget( segX, segY, boundsSize );
11265      }
11266    }
11267  }, this );
11268
11269};
11270
11271proto._addShiftTarget = function( x, y, boundsSize ) {
11272  var checkCoord = this._getOption('horizontal') ? y : x;
11273  if ( checkCoord !== 0 && checkCoord > boundsSize ) {
11274    return;
11275  }
11276  // create string for a key, easier to keep track of what targets
11277  var key = x + ',' + y;
11278  var hasKey = this.shiftTargetKeys.indexOf( key ) != -1;
11279  if ( hasKey ) {
11280    return;
11281  }
11282  this.shiftTargetKeys.push( key );
11283  this.shiftTargets.push({ x: x, y: y });
11284};
11285
11286// -------------------------- drop -------------------------- //
11287
11288proto.shift = function( item, x, y ) {
11289  var shiftPosition;
11290  var minDistance = Infinity;
11291  var position = { x: x, y: y };
11292  this.shiftTargets.forEach( function( target ) {
11293    var distance = getDistance( target, position );
11294    if ( distance < minDistance ) {
11295      shiftPosition = target;
11296      minDistance = distance;
11297    }
11298  });
11299  item.rect.x = shiftPosition.x;
11300  item.rect.y = shiftPosition.y;
11301};
11302
11303function getDistance( a, b ) {
11304  var dx = b.x - a.x;
11305  var dy = b.y - a.y;
11306  return Math.sqrt( dx * dx + dy * dy );
11307}
11308
11309// -------------------------- drag move -------------------------- //
11310
11311var DRAG_THROTTLE_TIME = 120;
11312
11313/**
11314 * handle an item drag move event
11315 * @param {Element} elem
11316 * @param {Number} x - horizontal change in position
11317 * @param {Number} y - vertical change in position
11318 */
11319proto.itemDragMove = function( elem, x, y ) {
11320  var item = this.isEnabled && this.getItem( elem );
11321  if ( !item ) {
11322    return;
11323  }
11324
11325  x -= this.size.paddingLeft;
11326  y -= this.size.paddingTop;
11327
11328  var _this = this;
11329  function onDrag() {
11330    _this.shift( item, x, y );
11331    item.positionDropPlaceholder();
11332    _this.layout();
11333  }
11334
11335  // throttle
11336  var now = new Date();
11337  if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) {
11338    clearTimeout( this.dragTimeout );
11339    this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME );
11340  } else {
11341    onDrag();
11342    this._itemDragTime = now;
11343  }
11344};
11345
11346// -------------------------- drag end -------------------------- //
11347
11348/**
11349 * handle an item drag end event
11350 * @param {Element} elem
11351 */
11352proto.itemDragEnd = function( elem ) {
11353  var item = this.isEnabled && this.getItem( elem );
11354  if ( !item ) {
11355    return;
11356  }
11357
11358  clearTimeout( this.dragTimeout );
11359  item.element.classList.add('is-positioning-post-drag');
11360
11361  var completeCount = 0;
11362  var _this = this;
11363  function onDragEndLayoutComplete() {
11364    completeCount++;
11365    if ( completeCount != 2 ) {
11366      return;
11367    }
11368    // reset drag item
11369    item.element.classList.remove('is-positioning-post-drag');
11370    item.hideDropPlaceholder();
11371    _this.dispatchEvent( 'dragItemPositioned', null, [ item ] );
11372  }
11373
11374  item.once( 'layout', onDragEndLayoutComplete );
11375  this.once( 'layoutComplete', onDragEndLayoutComplete );
11376  item.moveTo( item.rect.x, item.rect.y );
11377  this.layout();
11378  this.dragItemCount = Math.max( 0, this.dragItemCount - 1 );
11379  this.sortItemsByPosition();
11380  item.disablePlacing();
11381  this.unstamp( item.element );
11382};
11383
11384/**
11385 * binds Draggabilly events
11386 * @param {Draggabilly} draggie
11387 */
11388proto.bindDraggabillyEvents = function( draggie ) {
11389  this._bindDraggabillyEvents( draggie, 'on' );
11390};
11391
11392proto.unbindDraggabillyEvents = function( draggie ) {
11393  this._bindDraggabillyEvents( draggie, 'off' );
11394};
11395
11396proto._bindDraggabillyEvents = function( draggie, method ) {
11397  var handlers = this.handleDraggabilly;
11398  draggie[ method ]( 'dragStart', handlers.dragStart );
11399  draggie[ method ]( 'dragMove', handlers.dragMove );
11400  draggie[ method ]( 'dragEnd', handlers.dragEnd );
11401};
11402
11403/**
11404 * binds jQuery UI Draggable events
11405 * @param {jQuery} $elems
11406 */
11407proto.bindUIDraggableEvents = function( $elems ) {
11408  this._bindUIDraggableEvents( $elems, 'on' );
11409};
11410
11411proto.unbindUIDraggableEvents = function( $elems ) {
11412  this._bindUIDraggableEvents( $elems, 'off' );
11413};
11414
11415proto._bindUIDraggableEvents = function( $elems, method ) {
11416  var handlers = this.handleUIDraggable;
11417  $elems
11418    [ method ]( 'dragstart', handlers.start )
11419    [ method ]( 'drag', handlers.drag )
11420    [ method ]( 'dragstop', handlers.stop );
11421};
11422
11423// ----- destroy ----- //
11424
11425var _destroy = proto.destroy;
11426proto.destroy = function() {
11427  _destroy.apply( this, arguments );
11428  // disable flag; prevent drag events from triggering. #72
11429  this.isEnabled = false;
11430};
11431
11432// -----  ----- //
11433
11434Packery.Rect = Rect;
11435Packery.Packer = Packer;
11436
11437return Packery;
11438
11439}));
11440
11441/*!
11442 * Packery layout mode v2.0.1
11443 * sub-classes Packery
11444 */
11445
11446/*jshint browser: true, strict: true, undef: true, unused: true */
11447
11448( function( window, factory ) {
11449
11450  // universal module definition
11451  if ( typeof define == 'function' && define.amd ) {
11452    // AMD
11453    define( [
11454        'isotope-layout/js/layout-mode',
11455        'packery/js/packery'
11456      ],
11457      factory );
11458  } else if ( typeof module == 'object' && module.exports ) {
11459    // CommonJS
11460    module.exports = factory(
11461      require('isotope-layout/js/layout-mode'),
11462      require('packery')
11463    );
11464  } else {
11465    // browser global
11466    factory(
11467      window.Isotope.LayoutMode,
11468      window.Packery
11469    );
11470  }
11471
11472}( window, function factor( LayoutMode, Packery ) {
11473
11474
11475  // create an Outlayer layout class
11476  var PackeryMode = LayoutMode.create('packery');
11477  var proto = PackeryMode.prototype;
11478
11479  var keepModeMethods = {
11480    _getElementOffset: true,
11481    _getMeasurement: true
11482  };
11483
11484  // inherit Packery prototype
11485  for ( var method in Packery.prototype ) {
11486    // do not inherit mode methods
11487    if ( !keepModeMethods[ method ] ) {
11488      proto[ method ] = Packery.prototype[ method ];
11489    }
11490  }
11491
11492  // set packer in _resetLayout
11493  var _resetLayout = proto._resetLayout;
11494  proto._resetLayout = function() {
11495    this.packer = this.packer || new Packery.Packer();
11496    this.shiftPacker = this.shiftPacker || new Packery.Packer();
11497    _resetLayout.apply( this, arguments );
11498  };
11499
11500  var _getItemLayoutPosition = proto._getItemLayoutPosition;
11501  proto._getItemLayoutPosition = function( item ) {
11502    // set packery rect
11503    item.rect = item.rect || new Packery.Rect();
11504    return _getItemLayoutPosition.call( this, item );
11505  };
11506
11507  // needsResizeLayout for vertical or horizontal
11508  var _needsResizeLayout = proto.needsResizeLayout;
11509  proto.needsResizeLayout = function() {
11510    if ( this._getOption('horizontal') ) {
11511      return this.needsVerticalResizeLayout();
11512    } else {
11513      return _needsResizeLayout.call( this );
11514    }
11515  };
11516
11517  // point to mode options for horizontal
11518  var _getOption = proto._getOption;
11519  proto._getOption = function( option ) {
11520    if ( option == 'horizontal' ) {
11521      return this.options.isHorizontal !== undefined ?
11522        this.options.isHorizontal : this.options.horizontal;
11523    }
11524    return _getOption.apply( this.isotope, arguments );
11525  };
11526
11527  return PackeryMode;
11528
11529}));
11530
11531/*!
11532 * cellsByRows layout mode for Isotope
11533 * v1.1.3
11534 * http://isotope.metafizzy.co/layout-modes/cellsbyrow.html
11535 */
11536
11537/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */
11538
11539( function( window, factory ) {
11540  // universal module definition
11541  /* jshint strict: false */ /*globals define, module, require */
11542  if ( typeof define === 'function' && define.amd ) {
11543    // AMD
11544    define( [
11545        'isotope/js/layout-mode'
11546      ],
11547      factory );
11548  } else if ( typeof exports === 'object' ) {
11549    // CommonJS
11550    module.exports = factory(
11551      require('isotope-layout/js/layout-mode')
11552    );
11553  } else {
11554    // browser global
11555    factory(
11556      window.Isotope.LayoutMode
11557    );
11558  }
11559
11560}( window, function factory( LayoutMode ) {
11561  'use strict';
11562
11563  var CellsByRow = LayoutMode.create( 'cellsByRow' );
11564  var proto = CellsByRow.prototype;
11565
11566  proto._resetLayout = function() {
11567    // reset properties
11568    this.itemIndex = 0;
11569    // measurements
11570    this.getColumnWidth();
11571    this.getRowHeight();
11572    // set cols
11573    this.cols = Math.floor( this.isotope.size.innerWidth / this.columnWidth );
11574    this.cols = Math.max( this.cols, 1 );
11575  };
11576
11577  proto._getItemLayoutPosition = function( item ) {
11578    item.getSize();
11579    var col = this.itemIndex % this.cols;
11580    var row = Math.floor( this.itemIndex / this.cols );
11581    // center item within cell
11582    var x = ( col + 0.5 ) * this.columnWidth - item.size.outerWidth / 2;
11583    var y = ( row + 0.5 ) * this.rowHeight - item.size.outerHeight / 2;
11584    this.itemIndex++;
11585    return { x: x, y: y };
11586  };
11587
11588  proto._getContainerSize = function() {
11589    return {
11590      height: Math.ceil( this.itemIndex / this.cols ) * this.rowHeight
11591    };
11592  };
11593
11594  return CellsByRow;
11595
11596}));
11597/*global jQuery: true */
11598
11599/*!
11600   --------------------------------
11601   Infinite Scroll
11602   --------------------------------
11603   + https://github.com/paulirish/infinite-scroll
11604   + version 2.1.0
11605   + Copyright 2011/12 Paul Irish & Luke Shumard
11606   + Licensed under the MIT license
11607
11608   + Documentation: http://infinite-scroll.com/
11609*/
11610
11611// Uses AMD or browser globals to create a jQuery plugin.
11612(function (factory) {
11613	if (typeof define === 'function' && define.amd) {
11614		// AMD. Register as an anonymous module.
11615		define(['jquery'], factory);
11616	} else {
11617		// Browser globals
11618		factory(jQuery);
11619	}
11620}(function ($, undefined) {
11621	'use strict';
11622
11623	$.infinitescroll = function infscr(options, callback, element) {
11624		this.element = $(element);
11625
11626		// Flag the object in the event of a failed creation
11627		if (!this._create(options, callback)) {
11628			this.failed = true;
11629		}
11630	};
11631
11632	$.infinitescroll.defaults = {
11633		loading: {
11634			finished: undefined,
11635			finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>",
11636			img: 'data:image/gif;base64,R0lGODlh3AATAPQeAPDy+MnQ6LW/4N3h8MzT6rjC4sTM5r/I5NHX7N7j8c7U6tvg8OLl8uXo9Ojr9b3G5MfP6Ovu9tPZ7PT1+vX2+tbb7vf4+8/W69jd7rC73vn5/O/x+K243ai02////wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQECgD/ACwAAAAA3AATAAAF/6AnjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEj0BAScpHLJbDqf0Kh0Sq1ar9isdioItAKGw+MAKYMFhbF63CW438f0mg1R2O8EuXj/aOPtaHx7fn96goR4hmuId4qDdX95c4+RBIGCB4yAjpmQhZN0YGYGXitdZBIVGAsLoq4BBKQDswm1CQRkcG6ytrYKubq8vbfAcMK9v7q7EMO1ycrHvsW6zcTKsczNz8HZw9vG3cjTsMIYqQkCLBwHCgsMDQ4RDAYIqfYSFxDxEfz88/X38Onr16+Bp4ADCco7eC8hQYMAEe57yNCew4IVBU7EGNDiRn8Z831cGLHhSIgdFf9chIeBg7oA7gjaWUWTVQAGE3LqBDCTlc9WOHfm7PkTqNCh54rePDqB6M+lR536hCpUqs2gVZM+xbrTqtGoWqdy1emValeXKzggYBBB5y1acFNZmEvXAoN2cGfJrTv3bl69Ffj2xZt3L1+/fw3XRVw4sGDGcR0fJhxZsF3KtBTThZxZ8mLMgC3fRatCbYMNFCzwLEqLgE4NsDWs/tvqdezZf13Hvk2A9Szdu2X3pg18N+68xXn7rh1c+PLksI/Dhe6cuO3ow3NfV92bdArTqC2Ebd3A8vjf5QWfH6Bg7Nz17c2fj69+fnq+8N2Lty+fuP78/eV2X13neIcCeBRwxorbZrA1ANoCDGrgoG8RTshahQ9iSKEEzUmYIYfNWViUhheCGJyIP5E4oom7WWjgCeBFAJNv1DVV01MAdJhhjdkplWNzO/5oXI846njjVEIqR2OS2B1pE5PVscajkxhMycqLJghQSwT40PgfAl4GqNSXYdZXJn5gSkmmmmJu1aZYb14V51do+pTOCmA40AqVCIhG5IJ9PvYnhIFOxmdqhpaI6GeHCtpooisuutmg+Eg62KOMKuqoTaXgicQWoIYq6qiklmoqFV0UoeqqrLbq6quwxirrrLTWauutJ4QAACH5BAUKABwALAcABADOAAsAAAX/IPd0D2dyRCoUp/k8gpHOKtseR9yiSmGbuBykler9XLAhkbDavXTL5k2oqFqNOxzUZPU5YYZd1XsD72rZpBjbeh52mSNnMSC8lwblKZGwi+0QfIJ8CncnCoCDgoVnBHmKfByGJimPkIwtiAeBkH6ZHJaKmCeVnKKTHIihg5KNq4uoqmEtcRUtEREMBggtEr4QDrjCuRC8h7/BwxENeicSF8DKy82pyNLMOxzWygzFmdvD2L3P0dze4+Xh1Arkyepi7dfFvvTtLQkZBC0T/FX3CRgCMOBHsJ+EHYQY7OinAGECgQsB+Lu3AOK+CewcWjwxQeJBihtNGHSoQOE+iQ3//4XkwBBhRZMcUS6YSXOAwIL8PGqEaSJCiYt9SNoCmnJPAgUVLChdaoFBURN8MAzl2PQphwQLfDFd6lTowglHve6rKpbjhK7/pG5VinZP1qkiz1rl4+tr2LRwWU64cFEihwEtZgbgR1UiHaMVvxpOSwBA37kzGz9e8G+B5MIEKLutOGEsAH2ATQwYfTmuX8aETWdGPZmiZcccNSzeTCA1Sw0bdiitC7LBWgu8jQr8HRzqgpK6gX88QbrB14z/kF+ELpwB8eVQj/JkqdylAudji/+ts3039vEEfK8Vz2dlvxZKG0CmbkKDBvllRd6fCzDvBLKBDSCeffhRJEFebFk1k/Mv9jVIoIJZSeBggwUaNeB+Qk34IE0cXlihcfRxkOAJFFhwGmKlmWDiakZhUJtnLBpnWWcnKaAZcxI0piFGGLBm1mc90kajSCveeBVWKeYEoU2wqeaQi0PetoE+rr14EpVC7oAbAUHqhYExbn2XHHsVqbcVew9tx8+XJKk5AZsqqdlddGpqAKdbAYBn1pcczmSTdWvdmZ17c1b3FZ99vnTdCRFM8OEcAhLwm1NdXnWcBBSMRWmfkWZqVlsmLIiAp/o1gGV2vpS4lalGYsUOqXrddcKCmK61aZ8SjEpUpVFVoCpTj4r661Km7kBHjrDyc1RAIQAAIfkEBQoAGwAsBwAEAM4ACwAABf/gtmUCd4goQQgFKj6PYKi0yrrbc8i4ohQt12EHcal+MNSQiCP8gigdz7iCioaCIvUmZLp8QBzW0EN2vSlCuDtFKaq4RyHzQLEKZNdiQDhRDVooCwkbfm59EAmKi4SGIm+AjIsKjhsqB4mSjT2IOIOUnICeCaB/mZKFNTSRmqVpmJqklSqskq6PfYYCDwYHDC4REQwGCBLGxxIQDsHMwhAIX8bKzcENgSLGF9PU1j3Sy9zX2NrgzQziChLk1BHWxcjf7N046tvN82715czn9Pryz6Ilc4ACj4EBOCZM8KEnAYYADBRKnACAYUMFv1wotIhCEcaJCisqwJFgAUSQGyX/kCSVUUTIdKMwJlyo0oXHlhskwrTJciZHEXsgaqS4s6PJiCAr1uzYU8kBBSgnWFqpoMJMUjGtDmUwkmfVmVypakWhEKvXsS4nhLW5wNjVroJIoc05wSzTr0PtiigpYe4EC2vj4iWrFu5euWIMRBhacaVJhYQBEFjA9jHjyQ0xEABwGceGAZYjY0YBOrRLCxUp29QM+bRkx5s7ZyYgVbTqwwti2ybJ+vLtDYpycyZbYOlptxdx0kV+V7lC5iJAyyRrwYKxAdiz82ng0/jnAdMJFz0cPi104Ec1Vj9/M6F173vKL/feXv156dw11tlqeMMnv4V5Ap53GmjQQH97nFfg+IFiucfgRX5Z8KAgbUlQ4IULIlghhhdOSB6AgX0IVn8eReghen3NRIBsRgnH4l4LuEidZBjwRpt6NM5WGwoW0KSjCwX6yJSMab2GwwAPDXfaBCtWpluRTQqC5JM5oUZAjUNS+VeOLWpJEQ7VYQANW0INJSZVDFSnZphjSikfmzE5N4EEbQI1QJmnWXCmHulRp2edwDXF43txukenJwvI9xyg9Q26Z3MzGUcBYFEChZh6DVTq34AU8Iflh51Sd+CnKFYQ6mmZkhqfBKfSxZWqA9DZanWjxmhrWwi0qtCrt/43K6WqVjjpmhIqgEGvculaGKklKstAACEAACH5BAUKABwALAcABADOAAsAAAX/ICdyQmaMYyAUqPgIBiHPxNpy79kqRXH8wAPsRmDdXpAWgWdEIYm2llCHqjVHU+jjJkwqBTecwItShMXkEfNWSh8e1NGAcLgpDGlRgk7EJ/6Ae3VKfoF/fDuFhohVeDeCfXkcCQqDVQcQhn+VNDOYmpSWaoqBlUSfmowjEA+iEAEGDRGztAwGCDcXEA60tXEiCrq8vREMEBLIyRLCxMWSH
11636MzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/Cpk3ABwSLQkYAQwT/P309vcI7OvXr94jBQMJ/nskkGA/BQBRLNDncAIAiDcG6LsxAWOLiQzmeURBKWSLCQbv/1F0eDGinJUKR47YY1IEgQASKk7Yc7ACRwZm7mHweRJoz59BJUogisKCUaFMR0x4SlJBVBFTk8pZivTR0K73rN5wqlXEAq5Fy3IYgHbEzQ0nLy4QSoCjXLoom96VOJEeCosK5n4kkFfqXjl94wa+l1gvAcGICbewAOAxY8l/Ky/QhAGz4cUkGxu2HNozhwMGBnCUqUdBg9UuW9eUynqSwLHIBujePef1ZGQZXcM+OFuEBeBhi3OYgLyqcuaxbT9vLkf4SeqyWxSQpKGB2gQpm1KdWbu72rPRzR9Ne2Nu9Kzr/1Jqj0yD/fvqP4aXOt5sW/5qsXXVcv1Nsp8IBUAmgswGF3llGgeU1YVXXKTN1FlhWFXW3gIE+DVChApysACHHo7Q4A35lLichh+ROBmLKAzgYmYEYDAhCgxKGOOMn4WR4kkDaoBBOxJtdNKQxFmg5JIWIBnQc07GaORfUY4AEkdV6jHlCEISSZ5yTXpp1pbGZbkWmcuZmQCaE6iJ0FhjMaDjTMsgZaNEHFRAQVp3bqXnZED1qYcECOz5V6BhSWCoVJQIKuKQi2KFKEkEFAqoAo7uYSmO3jk61wUUMKmknJ4SGimBmAa0qVQBhAAAIfkEBQoAGwAsBwAEAM4ACwAABf/gJm5FmRlEqhJC+bywgK5pO4rHI0D3pii22+Mg6/0Ej96weCMAk7cDkXf7lZTTnrMl7eaYoy10JN0ZFdco0XAuvKI6qkgVFJXYNwjkIBcNBgR8TQoGfRsJCRuCYYQQiI+ICosiCoGOkIiKfSl8mJkHZ4U9kZMbKaI3pKGXmJKrngmug4WwkhA0lrCBWgYFCCMQFwoQDRHGxwwGCBLMzRLEx8iGzMMO0cYNeCMKzBDW19lnF9DXDIY/48Xg093f0Q3s1dcR8OLe8+Y91OTv5wrj7o7B+7VNQqABIoRVCMBggsOHE36kSoCBIcSH3EbFangxogJYFi8CkJhqQciLJEf/LDDJEeJIBT0GsOwYUYJGBS0fjpQAMidGmyVP6sx4Y6VQhzs9VUwkwqaCCh0tmKoFtSMDmBOf9phg4SrVrROuasRQAaxXpVUhdsU6IsECZlvX3kwLUWzRt0BHOLTbNlbZG3vZinArge5Dvn7wbqtQkSYAAgtKmnSsYKVKo2AfW048uaPmG386i4Q8EQMBAIAnfB7xBxBqvapJ9zX9WgRS2YMpnvYMGdPK3aMjt/3dUcNI4blpj7iwkMFWDXDvSmgAlijrt9RTR78+PS6z1uAJZIe93Q8g5zcsWCi/4Y+C8bah5zUv3vv89uft30QP23punGCx5954oBBwnwYaNCDY/wYrsYeggnM9B2Fpf8GG2CEUVWhbWAtGouEGDy7Y4IEJVrbSiXghqGKIo7z1IVcXIkKWWR361QOLWWnIhwERpLaaCCee5iMBGJQmJGyPFTnbkfHVZGRtIGrg5HALEJAZbu39BuUEUmq1JJQIPtZilY5hGeSWsSk52G9XqsmgljdIcABytq13HyIM6RcUA+r1qZ4EBF3WHWB29tBgAzRhEGhig8KmqKFv8SeCeo+mgsF7YFXa1qWSbkDpom/mqR1PmHCqJ3fwNRVXjC7S6CZhFVCQ2lWvZiirhQq42SACt25IK2hv8TprriUV1usGgeka7LFcNmCldMLi6qZMgFLgpw16Cipb7bC1knXsBiEAACH5BAUKABsALAcABADOAAsAAAX/4FZsJPkUmUGsLCEUTywXglFuSg7fW1xAvNWLF6sFFcPb42C8EZCj24EJdCp2yoegWsolS0Uu6fmamg8n8YYcLU2bXSiRaXMGvqV6/KAeJAh8VgZqCX+BexCFioWAYgqNi4qAR4ORhRuHY408jAeUhAmYYiuVlpiflqGZa5CWkzc5fKmbbhIpsAoQDRG8vQwQCBLCwxK6vb5qwhfGxxENahvCEA7NzskSy7vNzzzK09W/PNHF1NvX2dXcN8K55cfh69Luveol3vO8zwi4Yhj+AQwmCBw4IYclDAAJDlQggVOChAoLKkgFkSCAHDwWLKhIEOONARsDKryogFPIiAUb/95gJNIiw4wnI778GFPhzBKFOAq8qLJEhQpiNArjMcHCmlTCUDIouTKBhApELSxFWiGiVKY4E2CAekPgUphDu0742nRrVLJZnyrFSqKQ2ohoSYAMW6IoDpNJ4bLdILTnAj8KUF7UeENjAKuDyxIgOuGiOI0EBBMgLNew5AUrDTMGsFixwBIaNCQuAXJB57qNJ2OWm2Aj4skwCQCIyNkhhtMkdsIuodE0AN4LJDRgfLPtn5YDLdBlraAByuUbBgxQwICxMOnYpVOPej074OFdlfc0TqC62OIbcppHjV4o+LrieWhfT8JC/I/T6W8oCl29vQ0XjLdBaA3s1RcPBO7lFvpX8BVoG4O5jTXRQRDuJ6FDTzEWF1/BCZhgbyAKE9qICYLloQYOFtahVRsWYlZ4KQJHlwHS/IYaZ6sZd9tmu5HQm2xi1UaTbzxYwJk/wBF5g5EEYOBZeEfGZmNdFyFZmZIR4jikbLThlh5kUUVJGmRT7sekkziRWUIACABk3T4qCsedgO4xhgGcY7q5pHJ4klBBTQRJ0CeHcoYHHUh6wgfdn9uJdSdMiebGJ0zUPTcoS286FCkrZxnYoYYKWLkBowhQoBeaOlZAgVhLidrXqg2G
11636iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/oGFw2WZuT5oZROsSQnGaKjRvilI893MItlNOJ5v5gDcFrHhKIWcEYu/xFEqNv6B1N62aclysF7fsZYe5aOx2yL5aAUGSaT1oTYMBwQ5VGCAJgYIJCnx1gIOBhXdwiIl7d0p2iYGQUAQBjoOFSQR/lIQHnZ+Ue6OagqYzSqSJi5eTpTxGcjcSChANEbu8DBAIEsHBChe5vL13G7fFuscRDcnKuM3H0La3EA7Oz8kKEsXazr7Cw9/Gztar5uHHvte47MjktznZ2w0G1+D3BgirAqJmJMAQgMGEgwgn5Ei0gKDBhBMALGRYEOJBb5QcWlQo4cbAihZz3GgIMqFEBSM1/4ZEOWPAgpIIJXYU+PIhRG8ja1qU6VHlzZknJNQ6UanCjQkWCIGSUGEjAwVLjc44+DTqUQtPPS5gejUrTa5TJ3g9sWCr1BNUWZI161StiQUDmLYdGfesibQ3XMq1OPYthrwuA2yU2LBs2cBHIypYQPPlYAKFD5cVvNPtW8eVGbdcQADATsiNO4cFAPkvHpedPzc8kUcPgNGgZ5RNDZG05reoE9s2vSEP79MEGiQGy1qP8LA4ZcdtsJE48ONoLTBtTV0B9LsTnPceoIDBDQvS7W7vfjVY3q3eZ4A339J4eaAmKqU/sV58HvJh2RcnIBsDUw0ABqhBA5aV5V9XUFGiHfVeAiWwoFgJJrIXRH1tEMiDFV4oHoAEGlaWhgIGSGBO2nFomYY3mKjVglidaNYJGJDkWW2xxTfbjCbVaOGNqoX2GloR8ZeTaECS9pthRGJH2g0b3Agbk6hNANtteHD2GJUucfajCQBy5OOTQ25ZgUPvaVVQmbKh9510/qQpwXx3SQdfk8tZJOd5b6JJFplT3ZnmmX3qd5l1eg5q00HrtUkUn0AKaiGjClSAgKLYZcgWXwocGRcCFGCKwSB6ceqphwmYRUFYT/1WKlOdUpipmxW0mlCqHjYkAaeoZlqrqZ4qd+upQKaapn/AmgAegZ8KUtYtFAQQAgAh+QQFCgAbACwHAAQAzgALAAAF/+C2PUcmiCiZGUTrEkKBis8jQEquKwU5HyXIbEPgyX7BYa5wTNmEMwWsSXsqFbEh8DYs9mrgGjdK6GkPY5GOeU6ryz7UFopSQEzygOGhJBjoIgMDBAcBM0V/CYqLCQqFOwobiYyKjn2TlI6GKC2YjJZknouaZAcQlJUHl6eooJwKooobqoewrJSEmyKdt59NhRKFMxLEEA4RyMkMEAjDEhfGycqAG8TQx9IRDRDE3d3R2ctD1RLg0ttKEnbY5wZD3+zJ6M7X2RHi9Oby7u/r9g38UFjTh2xZJBEBMDAboogAgwkQI07IMUORwocSJwCgWDFBAIwZOaJIsOBjRogKJP8wTODw5ESVHVtm3AhzpEeQElOuNDlTZ0ycEUWKWFASqEahGwYUPbnxoAgEdlYSqDBkgoUNClAlIHbSAoOsqCRQnQHxq1axVb06FWFxLIqyaze0Tft1JVqyE+pWXMD1pF6bYl3+HTqAWNW8cRUFzmih0ZAAB2oGKukSAAGGRHWJgLiR6AylBLpuHKKUMlMCngMpDSAa9QIUggZVVvDaJobLeC3XZpvgNgCmtPcuwP3WgmXSq4do0DC6o2/guzcseECtUoO0hmcsGKDgOt7ssBd07wqesAIGZC1YIBa7PQHvb1+SFo+++HrJSQfB33xfav3i5eX3Hnb4CTJgegEq8tH/YQEOcIJzbm2G2EoYRLgBXFpVmFYDcREV4HIcnmUhiGBRouEMJGJGzHIspqgdXxK0yCKHRNXoIX4uorCdTyjkyNtdPWrA4Up82EbAbzMRxxZRR54WXVLDIRmRcag5d2R6ugl3ZXzNhTecchpMhIGVAKAYpgJjjsSklBEd99maZoo535ZvdamjBEpusJyctg3h4X8XqodBMx0tiNeg/oGJaKGABpogS40KSqiaEgBqlQWLUtqoVQnytekEjzo0hHqhRorppOZt2p923M2AAV+oBtpAnnPNoB6HaU6mAAIU+IXmi3j2mtFXuUoHKwXpzVrsjcgGOauKEjQrwq157hitGq2NoWmjh7z6Wmxb0m5w66+2VRAuXN/yFUAIACH5BAUKABsALAcABADOAAsAAAX/4CZuRiaM45MZqBgIRbs9AqTcuFLE7VHLOh7KB5ERdjJaEaU4ClO/lgKWjKKcMiJQ8KgumcieVdQMD8cbBeuAkkC6LYLhOxoQ2PF5Ys9PKPBMen17f0CCg4VSh32JV4t8jSNqEIOEgJKPlkYBlJWRInKdiJdkmQlvKAsLBxdABA4RsbIMBggtEhcQsLKxDBC2TAS6vLENdJLDxMZAubu8vjIbzcQRtMzJz79S08oQEt/guNiyy7fcvMbh4OezdAvGrakLAQwyABsELQkY9BP+//ckyPDD4J9BfAMh1GsBoImMeQUN+lMgUJ9CiRMa5msxoB9Gh/o8GmxYMZXIgxtR/yQ46S/gQAURR0pDwYDfywoyLPip5AdnCwsMFPBU4BPFhKBDi444quCmDKZOfwZ9KEGpCKgcN1jdALSpPqIYsabS+nSqvqplvYqQYAeDPgwKwjaMtiDl0oaqUAyo+3TuWwUAMPpVCfee0cEjVBGQq2ABx7oTWmQk4FglZMGN9fGVDMCuiH2AOVOu/PmyxM630gwM0CCn6q8LjVJ8GXvpa5Uwn95OTC/nNxkda1/dLSK475IjCD6dHbK1ZOa4hXP9DXs5chJ00UpVm5xo2qRpoxptwF2E4/IbJpB/SDz9+q9b1aNfQH08+p4a8uvX8B53fLP+ycAfemjsRUBgp1H20K+BghHgVgt1GXZXZpZ5lt4ECjxYR4ScUWiShEtZqBiIInRGWnERNnjiBglw+JyGnxUmGowsyiiZg189lNtPGACjV2+S9UjbU0JWF6SPvEk3QZEqsZYTk3UAaRSUnznJI5LmESCdBVSyaOWUWLK4I5gDUYVeV1T9l+FZClCAUVA09uSmRHBCKAECFEhW51ht6rnmWBXkaR+NjuHpJ40D3DmnQXt2F+ihZxlqVKOfQRACACH5BAUKABwALAcABADOAAsAAAX/ICdyUCkUo/g8mUG8MCGkKgspeC6j6XEIEBpBUeCNfECaglBcOVfJFK7YQwZHQ6JRZBUqTrSuVEuD3nI45pYjFuWKvjjSkCoRaBUMWxkwBGgJCXspQ36Bh4EEB0oKhoiBgyNLjo8Ki4QElIiWfJqHnISNEI+Ql5J9o6SgkqKkgqYihamPkW6oNBgSfiMMDQkGCBLCwxIQDhHIyQwQCGMKxsnKVyPCF9DREQ3MxMPX0cu4wt7J2uHWx9jlKd3o39MiuefYEcvNkuLt5O8c1ePI2tyELXGQwoGDAQf+iEC2xByDCRAjTlAgIUWCBRgCPJQ4AQBFXAs0coT40WLIjRxL/47AcHLkxIomRXL0CHPERZkpa4q4iVKiyp0tR/7kwHMkTUBBJR5dOCEBAVcKKtCAyOHpowXCpk7goABqBZdcvWploACpBKkpIJI1q5OD2rIWE0R1uTZu1LFwbWL9OlKuWb4c6+o9i3dEgw0RCGDUG9KlRw56gDY2qmCByZBaASi+TACA0TucAaTteCcy0ZuOK3N2vJlx58+LRQyY3Xm0ZsgjZg+oPQLi7dUcNXi0LOJw1pgNtB7XG6CBy+U75SYfPTSQAgZTNUDnQHt67wnbZyvwLgKiMN3oCZB3C76tdewpLFgIP2C88rbi4Y+QT3+8S5USMICZXWj1pkEDeUU3lOYGB3alSoEiMIjgX4WlgNF2EibIwQIXauWXSRg2SAOHIU5IIIMoZkhhWiJaiFVbKo6AQEgQXrTAazO1JhkBrBG3Y2Y6EsUhaGn95hprSN0oWpFE7rhkeaQBchGOEWnwEmc0uKWZj0LeuNV3W4Y2lZHFlQCSRjTIl8uZ+kG5HU/3sRlnTG2ytyadytnD3HrmuRcSn+0h1dycexIK1KCjYaCnjCCVqOFFJTZ5GkUUjESWaUIKU2lgCmAKKQIUjHapXRKE+t2og1VgankNYnohqKJ2CmKplso6GKz7WYCgqxeuyoF8u9IQAgA7',
11637			msg: null,
11638			msgText: '<em>Loading the next set of posts...</em>',
11639			selector: null,
11640			speed: 'fast',
11641			start: undefined
11642		},
11643		state: {
11644			isDuringAjax: false,
11645			isInvalidPage: false,
11646			isDestroyed: false,
11647			isDone: false, // For when it goes all the way through the archive.
11648			isPaused: false,
11649			isBeyondMaxPage: false,
11650			currPage: 1
11651		},
11652		debug: false,
11653		behavior: undefined,
11654		binder: $(window), // used to cache the selector
11655		nextSelector: 'div.navigation a:first',
11656		navSelector: 'div.navigation',
11657		contentSelector: null, // rename to pageFragment
11658		extraScrollPx: 150,
11659		itemSelector: 'div.post',
11660		animate: false,
11661		pathParse: undefined,
11662		dataType: 'html',
11663		appendCallback: true,
11664		bufferPx: 40,
11665		errorCallback: function () { },
11666		infid: 0, //Instance ID
11667		pixelsFromNavToBottom: undefined,
11668		path: undefined, // Either parts of a URL as an array (e.g. ["/page/", "/"] or a function that takes in the page number and returns a URL
11669		prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted
11670		maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work)
11671	};
11672
11673	$.infinitescroll.prototype = {
11674
11675		/*
11676			----------------------------
11677			Private methods
11678			----------------------------
11679			*/
11680
11681		// Bind or unbind from scroll
11682		_binding: function infscr_binding(binding) {
11683
11684			var instance = this,
11685				opts = instance.options;
11686
11687			opts.v = '2.0b2.120520';
11688
11689			// if behavior is defined and this function is extended, call that instead of default
11690			if (!!opts.behavior && this['_binding_' + opts.behavior] !== undefined) {
11691				this['_binding_' + opts.behavior].call(this);
11692				return;
11693			}
11694
11695			if (binding !== 'bind' && binding !== 'unbind') {
11696				this._debug('Binding value  ' + binding + ' not valid');
11697				return false;
11698			}
11699
11700			if (binding === 'unbind') {
11701				(this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid);
11702			} else {
11703				(this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () {
11704					instance.scroll();
11705				});
11706			}
11707
11708			this._debug('Binding', binding);
11709		},
11710
11711		// Fundamental aspects of the plugin are initialized
11712		_create: function infscr_create(options, callback) {
11713
11714			// Add custom options to defaults
11715			var opts = $.extend(true, {}, $.infinitescroll.defaults, options);
11716			this.options = opts;
11717			var $window = $(window);
11718			var instance = this;
11719
11720			// Validate selectors
11721			if (!instance._validate(options)) {
11722				return false;
11723			}
11724
11725			// Validate page fragment path
11726			var path = $(opts.nextSelector).attr('href');
11727			if (!path) {
11728				this._debug('Navigation selector not found');
11729				return false;
11730			}
11731
11732			// Set the path to be a relative URL from root.
11733			opts.path = opts.path || this._determinepath(path);
11734
11735			// contentSelector is 'page fragment' option for .load() / .ajax() calls
11736			opts.contentSelector = opts.contentSelector || this.element;
11737
11738			// loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector
11739			opts.loading.selector = opts.loading.selector || opts.contentSelector;
11740
11741			// Define loading.msg
11742			opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>');
11743
11744			// Preload loading.img
11745			(new Image()).src = opts.loading.img;
11746
11747			// distance from nav links to bottom
11748			// computed as: height of the document + top offset of container - top offset of nav link
11749			if (opts.pixelsFromNavToBottom === undefined) {
11750				opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top;
11751				this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom);
11752			}
11753
11754			var self = this;
11755
11756			// determine loading.start actions
11757			opts.loading.start = opts.loading.start || function () {
11758				$(opts.navSelector).hide();
11759				opts.loading.msg
11760					.appendTo(opts.loading.selector)
11761					.show(opts.loading.speed, $.proxy(function () {
11762						this.beginAjax(opts);
11763					}, self));
11764			};
11765
11766			// determine loading.finished actions
11767			opts.loading.finished = opts.loading.finished || function () {
11768				if (!opts.state.isBeyondMaxPage)
11769					opts.loading.msg.fadeOut(opts.loading.speed);
11770			};
11771
11772			// callback loading
11773			opts.callback = function (instance, data, url) {
11774				if (!!opts.behavior && instance['_callback_' + opts.behavior] !== undefined) {
11775					instance['_callback_' + opts.behavior].call($(opts.contentSelector)[0], data, url);
11776				}
11777
11778				if (callback) {
11779					callback.call($(opts.contentSelector)[0], data, opts, url);
11780				}
11781
11782				if (opts.prefill) {
11783					$window.bind('resize.infinite-scroll', instance._prefill);
11784				}
11785			};
11786
11787			if (options.debug) {
11788				// Tell IE9 to use its built-in console
11789				if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') {
11790					['log', 'info', 'warn', 'error', 'assert', 'dir', 'clear', 'profile', 'profileEnd']
11791						.forEach(function (method) {
11792							console[method] = this.call(console[method], console);
11793						}, Function.prototype.bind);
11794				}
11795			}
11796
11797			this._setup();
11798
11799			// Setups the prefill method for use
11800			if (opts.prefill) {
11801				this._prefill();
11802			}
11803
11804			// Return true to indicate successful creation
11805			return true;
11806		},
11807
11808		_prefill: function infscr_prefill() {
11809			var instance = this;
11810			var $window = $(window);
11811
11812			function needsPrefill() {
11813				return ($(instance.options.contentSelector).height() <= $window.height());
11814			}
11815
11816			this._prefill = function () {
11817				if (needsPrefill()) {
11818					instance.scroll();
11819				}
11820
11821				$window.bind('resize.infinite-scroll', function () {
11822					if (needsPrefill()) {
11823						$window.unbind('resize.infinite-scroll');
11824						instance.scroll();
11825					}
11826				});
11827			};
11828
11829			// Call self after setting up the new function
11830			this._prefill();
11831		},
11832
11833		// Console log wrapper
11834		_debug: function infscr_debug() {
11835			if (true !== this.options.debug) {
11836				return;
11837			}
11838
11839			if (typeof console !== 'undefined' && typeof console.log === 'function') {
11840				// Modern browsers
11841				// Single argument, which is a string
11842				if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') {
11843					console.log((Array.prototype.slice.call(arguments)).toString());
11844				} else {
11845					console.log(Array.prototype.slice.call(arguments));
11846				}
11847			} else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') {
11848				// IE8
11849				Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
11850			}
11851		},
11852
11853		// find the number to increment in the path.
11854		_determinepath: function infscr_determinepath(path) {
11855
11856			var opts = this.options;
11857
11858			// if behavior is defined and this function is extended, call that instead of default
11859			if (!!opts.behavior && this['_determinepath_' + opts.behavior] !== undefined) {
11860				return this['_determinepath_' + opts.behavior].call(this, path);
11861			}
11862
11863			var url = new URL(path);
11864			var pathname = url.pathname;
11865			var hasNumber = /\d/.test(pathname);
11866
11867			if (!!opts.pathParse) {
11868				this._debug('pathParse manual');
11869				return opts.pathParse(path, this.options.state.currPage + 1);
11870            } else if (hasNumber && path.match(/(\?|\&)(upage=)(\d+)/)) {
11871				var parts = path.split(/(\?|\&)(upage=)(\d+)/);
11872				return [parts[0] + parts[1] + parts[2], parts[4]];
11873            } else if (path.match(/^(.*?)\b2\b(.*?$)/)) {
11874				path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);
11875
11876                // if there is any 2 in the url at all.
11877            } else if (path.match(/^(.*?)2(.*?$)/)) {
11878                // page= is used in django:
11879                // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127
11880                if (path.match(/^(.*?page=)2(\/.*|$)/)) {
11881                    path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);
11882                    return path;
11883                }
11884
11885                path = path.match(/^(.*?)2(.*?$)/).slice(1);
11886
11887            } else {
11888                // page= is used in drupal too but second page is page=1 not page=2:
11889                // thx Jerod Fritz, vladikoff
11890                if (path.match(/^(.*?page=)1(\/.*|$)/)) {
11891                    path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);
11892                    return path;
11893                } else {
11894                    this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.");
11895                    // Get rid of isInvalidPage to allow permalink to state
11896                    opts.state.isInvalidPage = true;  //prevent it from running on this page.
11897                }
11898            }
11899            this._debug('determinePath', path);
11900            return path;
11901
11902        },
11903
11904        // Custom error
11905        _error: function infscr_error(xhr) {
11906
11907            var opts = this.options;
11908
11909            // if behavior is defined and this function is extended, call that instead of default
11910            if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) {
11911                this['_error_'+opts.behavior].call(this,xhr);
11912                return;
11913            }
11914
11915            if (xhr !== 'destroy' && xhr !== 'end') {
11916                xhr = 'unknown';
11917            }
11918
11919            this._debug('Error', xhr);
11920
11921            if (xhr === 'end' || opts.state.isBeyondMaxPage) {
11922                this._showdonemsg();
11923            }
11924
11925            opts.state.isDone = true;
11926            opts.state.currPage = 1; // if you need to go back to this instance
11927            opts.state.isPaused = false;
11928            opts.state.isBeyondMaxPage = false;
11929            this._binding('unbind');
11930
11931        },
11932
11933        // Load Callback
11934        _loadcallback: function infscr_loadcallback(box, data, url) {
11935            var opts = this.options,
11936            callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK
11937            result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append',
11938            frag;
11939
11940            // if behavior is defined and this function is extended, call that instead of default
11941            if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) {
11942                this['_loadcallback_'+opts.behavior].call(this,box,data);
11943                return;
11944            }
11945
11946            switch (result) {
11947                case 'done':
11948                    this._showdonemsg();
11949                    return false;
11950
11951                case 'no-append':
11952                    if (opts.dataType === 'html') {
11953                        data = '<div>' + data + '</div>';
11954                        data = $(data).find(opts.itemSelector);
11955                    }
11956
11957                    // if it didn't return anything
11958                    if (data.length === 0) {
11959                        return this._error('end');
11960                    }
11961
11962                    break;
11963
11964                case 'append':
11965                    var children = box.children();
11966                    // if it didn't return anything
11967                    if (children.length === 0) {
11968                        return this._error('end');
11969                    }
11970
11971                    // use a documentFragment because it works when content is going into a table or UL
11972                    frag = document.createDocumentFragment();
11973                    while (box[0].firstChild) {
11974                        frag.appendChild(box[0].firstChild);
11975                    }
11976
11977                    this._debug('contentSelector', $(opts.contentSelector)[0]);
11978                    $(opts.contentSelector)[0].appendChild(frag);
11979                    // previously, we would pass in the new DOM element as context for the callback
11980                    // however we're now using a documentfragment, which doesn't have parents or children,
11981                    // so the context is the contentContainer guy, and we pass in an array
11982                    // of the elements collected as the first argument.
11983
11984                    data = children.get();
11985                    break;
11986            }
11987
11988            // loadingEnd function
11989            opts.loading.finished.call($(opts.contentSelector)[0],opts);
11990
11991            // smooth scroll to ease in the new content
11992            if (opts.animate) {
11993                var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px';
11994                $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; });
11995            }
11996
11997            if (!opts.animate) {
11998                // once the call is done, we can allow it again.
11999                opts.state.isDuringAjax = false;
12000            }
12001
12002            callback(this, data, url);
12003
12004            if (opts.prefill) {
12005                this._prefill();
12006            }
12007        },
12008
12009        _nearbottom: function infscr_nearbottom() {
12010
12011            var opts = this.options,
12012            pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height();
12013
12014            // if behavior is defined and this function is extended, call that instead of default
12015            if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) {
12016                return this['_nearbottom_'+opts.behavior].call(this);
12017            }
12018
12019            this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom);
12020
12021            // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....
12022            return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom);
12023
12024        },
12025
12026        // Pause / temporarily disable plugin from firing
12027        _pausing: function infscr_pausing(pause) {
12028
12029            var opts = this.options;
12030
12031            // if behavior is defined and this function is extended, call that instead of default
12032            if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) {
12033                this['_pausing_'+opts.behavior].call(this,pause);
12034                return;
12035            }
12036
12037            // If pause is not 'pause' or 'resume', toggle it's value
12038            if (pause !== 'pause' && pause !== 'resume' && pause !== null) {
12039                this._debug('Invalid argument. Toggling pause value instead');
12040            }
12041
12042            pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle';
12043
12044            switch (pause) {
12045                case 'pause':
12046                    opts.state.isPaused = true;
12047                break;
12048
12049                case 'resume':
12050                    opts.state.isPaused = false;
12051                break;
12052
12053                case 'toggle':
12054                    opts.state.isPaused = !opts.state.isPaused;
12055                break;
12056            }
12057
12058            this._debug('Paused', opts.state.isPaused);
12059            return false;
12060
12061        },
12062
12063        // Behavior is determined
12064        // If the behavior option is undefined, it will set to default and bind to scroll
12065        _setup: function infscr_setup() {
12066
12067            var opts = this.options;
12068
12069            // if behavior is defined and this function is extended, call that instead of default
12070            if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) {
12071                this['_setup_'+opts.behavior].call(this);
12072                return;
12073            }
12074
12075            this._binding('bind');
12076
12077            return false;
12078
12079        },
12080
12081        // Show done message
12082        _showdonemsg: function infscr_showdonemsg() {
12083
12084            var opts = this.options;
12085
12086            // if behavior is defined and this function is extended, call that instead of default
12087            if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) {
12088                this['_showdonemsg_'+opts.behavior].call(this);
12089                return;
12090            }
12091
12092            opts.loading.msg
12093            .find('img')
12094            .hide()
12095            .parent()
12096            .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () {
12097                $(this).parent().fadeOut(opts.loading.speed);
12098            });
12099
12100            // user provided callback when done
12101            opts.errorCallback.call($(opts.contentSelector)[0],'done');
12102        },
12103
12104        // grab each selector option and see if any fail
12105        _validate: function infscr_validate(opts) {
12106            for (var key in opts) {
12107                if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) {
12108                    this._debug('Your ' + key + ' found no elements.');
12109                    return false;
12110                }
12111            }
12112
12113            return true;
12114        },
12115
12116        /*
12117            ----------------------------
12118            Public methods
12119            ----------------------------
12120            */
12121
12122        // Bind to scroll
12123        bind: function infscr_bind() {
12124            this._binding('bind');
12125        },
12126
12127        // Destroy current instance of plugin
12128        destroy: function infscr_destroy() {
12129            this.options.state.isDestroyed = true;
12130            this.options.loading.finished();
12131            return this._error('destroy');
12132        },
12133
12134        // Set pause value to false
12135        pause: function infscr_pause() {
12136            this._pausing('pause');
12137        },
12138
12139        // Set pause value to false
12140        resume: function infscr_resume() {
12141            this._pausing('resume');
12142        },
12143
12144        beginAjax: function infscr_ajax(opts) {
12145            var instance = this,
12146                path = opts.path,
12147                box, desturl, method, condition;
12148
12149			// increment the URL bit. e.g. /page/3/
12150            opts.state.currPage++;
12151
12152            // Manually control maximum page
12153            if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){
12154                opts.state.isBeyondMaxPage = true;
12155                this.destroy();
12156                return;
12157            }
12158
12159            // if we're dealing with a table we can't use DIVs
12160            box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>');
12161
12162			desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage);
12163
12164            instance._debug('heading into ajax', desturl);
12165
12166            method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback';
12167            if (opts.appendCallback && opts.dataType === 'html') {
12168                method += '+callback';
12169            }
12170
12171            switch (method) {
12172                case 'html+callback':
12173                    instance._debug('Using HTML via .load() method');
12174                    box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) {
12175                        instance._loadcallback(box, responseText, desturl);
12176                    });
12177
12178                    break;
12179
12180                case 'html':
12181                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
12182                    $.ajax({
12183                        // params
12184                        url: desturl,
12185                        dataType: opts.dataType,
12186                        complete: function infscr_ajax_callback(jqXHR, textStatus) {
12187                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');
12188                            if (condition) {
12189                                instance._loadcallback(box, jqXHR.responseText, desturl);
12190                            } else {
12191                                instance._error('end');
12192                            }
12193                        }
12194                    });
12195
12196                    break;
12197                case 'json':
12198                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
12199                    $.ajax({
12200                        dataType: 'json',
12201                        type: 'GET',
12202                        url: desturl,
12203                        success: function (data, textStatus, jqXHR) {
12204                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');
12205                            if (opts.appendCallback) {
12206                                // if appendCallback is true, you must defined template in options.
12207                                // note that data passed into _loadcallback is already an html (after processed in opts.template(data)).
12208                                if (opts.template !== undefined) {
12209                                    var theData = opts.template(data);
12210                                    box.append(theData);
12211                                    if (condition) {
12212                                        instance._loadcallback(box, theData);
12213                                    } else {
12214                                        instance._error('end');
12215                                    }
12216                                } else {
12217                                    instance._debug('template must be defined.');
12218                                    instance._error('end');
12219                                }
12220                            } else {
12221                                // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback.
12222                                if (condition) {
12223                                    instance._loadcallback(box, data, desturl);
12224                                } else {
12225                                    instance._error('end');
12226                                }
12227                            }
12228                        },
12229                        error: function() {
12230                            instance._debug('JSON ajax request failed.');
12231                            instance._error('end');
12232                        }
12233                    });
12234
12235                    break;
12236            }
12237        },
12238
12239        // Retrieve next set of content items
12240        retrieve: function infscr_retrieve(pageNum) {
12241            pageNum = pageNum || null;
12242
12243            var instance = this,
12244            opts = instance.options;
12245
12246            // if behavior is defined and this function is extended, call that instead of default
12247            if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) {
12248                this['retrieve_'+opts.behavior].call(this,pageNum);
12249                return;
12250            }
12251
12252            // for manual triggers, if destroyed, get out of here
12253            if (opts.state.isDestroyed) {
12254                this._debug('Instance is destroyed');
12255                return false;
12256            }
12257
12258            // we dont want to fire the ajax multiple times
12259            opts.state.isDuringAjax = true;
12260
12261            opts.loading.start.call($(opts.contentSelector)[0],opts);
12262        },
12263
12264        // Check to see next page is needed
12265        scroll: function infscr_scroll() {
12266
12267            var opts = this.options,
12268            state = opts.state;
12269
12270            // if behavior is defined and this function is extended, call that instead of default
12271            if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) {
12272                this['scroll_'+opts.behavior].call(this);
12273                return;
12274            }
12275
12276            if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) {
12277                return;
12278            }
12279
12280            if (!this._nearbottom()) {
12281                return;
12282            }
12283
12284            this.retrieve();
12285
12286        },
12287
12288        // Toggle pause value
12289        toggle: function infscr_toggle() {
12290            this._pausing();
12291        },
12292
12293        // Unbind from scroll
12294        unbind: function infscr_unbind() {
12295            this._binding('unbind');
12296        },
12297
12298        // update options
12299        update: function infscr_options(key) {
12300            if ($.isPlainObject(key)) {
12301                this.options = $.extend(true,this.options,key);
12302            }
12303        }
12304    };
12305
12306
12307    /*
12308        ----------------------------
12309        Infinite Scroll function
12310        ----------------------------
12311
12312        Borrowed logic from the following...
12313
12314        jQuery UI
12315        - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js
12316
12317        jCarousel
12318        - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js
12319
12320        Masonry
12321        - https://github.com/desandro/masonry/blob/master/jquery.masonry.js
12322
12323*/
12324
12325    $.fn.infinitescroll = function infscr_init(options, callback) {
12326
12327
12328        var thisCall = typeof options;
12329
12330        switch (thisCall) {
12331
12332            // method
12333            case 'string':
12334                var args = Array.prototype.slice.call(arguments, 1);
12335
12336                this.each(function () {
12337                    var instance = $.data(this, 'infinitescroll');
12338
12339                    if (!instance) {
12340                        // not setup yet
12341                        // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup');
12342                        return false;
12343                    }
12344
12345                    if (!$.isFunction(instance[options]) || options.charAt(0) === '_') {
12346                        // return $.error('No such method ' + options + ' for Infinite Scroll');
12347                        return false;
12348                    }
12349
12350                    // no errors!
12351                    instance[options].apply(instance, args);
12352                });
12353
12354            break;
12355
12356            // creation
12357            case 'object':
12358
12359                this.each(function () {
12360
12361                var instance = $.data(this, 'infinitescroll');
12362
12363                if (instance) {
12364
12365                    // update options of current instance
12366                    instance.update(options);
12367
12368                } else {
12369
12370                    // initialize new instance
12371                    instance = new $.infinitescroll(options, callback, this);
12372
12373                    // don't attach if instantiation failed
12374                    if (!instance.failed) {
12375                        $.data(this, 'infinitescroll', instance);
12376                    }
12377
12378                }
12379
12380            });
12381
12382            break;
12383
12384        }
12385
12386        return this;
12387    };
12388
12389
12390
12391    /*
12392     * smartscroll: debounced scroll event for jQuery *
12393     * https://github.com/lukeshumard/smartscroll
12394     * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js *
12395     * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. *
12396     */
12397
12398    var event = $.event,
12399    scrollTimeout;
12400
12401    event.special.smartscroll = {
12402        setup: function () {
12403            $(this).bind('scroll', event.special.smartscroll.handler);
12404        },
12405        teardown: function () {
12406            $(this).unbind('scroll', event.special.smartscroll.handler);
12407        },
12408        handler: function (event, execAsap) {
12409            // Save the context
12410            var context = this,
12411            args = arguments;
12412
12413            // set correct event type
12414            event.type = 'smartscroll';
12415
12416            if (scrollTimeout) { clearTimeout(scrollTimeout); }
12417            scrollTimeout = setTimeout(function () {
12418                $(context).trigger('smartscroll', args);
12419            }, execAsap === 'execAsap' ? 0 : 100);
12420        }
12421    };
12422
12423    $.fn.smartscroll = function (fn) {
12424        return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']);
12425    };
12426
12427}));
12428
12429/*!
12430Waypoints - 4.0.1
12431Copyright © 2011-2016 Caleb Troughton
12432Licensed under the MIT license.
12433https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
12434*/
12435(function() {
12436  'use strict'
12437
12438  var keyCounter = 0
12439  var allWaypoints = {}
12440
12441  /* http://imakewebthings.com/waypoints/api/waypoint */
12442  function Waypoint(options) {
12443    if (!options) {
12444      throw new Error('No options passed to Waypoint constructor')
12445    }
12446    if (!options.element) {
12447      throw new Error('No element option passed to Waypoint constructor')
12448    }
12449    if (!options.handler) {
12450      throw new Error('No handler option passed to Waypoint constructor')
12451    }
12452
12453    this.key = 'waypoint-' + keyCounter
12454    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
12455    this.element = this.options.element
12456    this.adapter = new Waypoint.Adapter(this.element)
12457    this.callback = options.handler
12458    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
12459    this.enabled = this.options.enabled
12460    this.triggerPoint = null
12461    this.group = Waypoint.Group.findOrCreate({
12462      name: this.options.group,
12463      axis: this.axis
12464    })
12465    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
12466
12467    if (Waypoint.offsetAliases[this.options.offset]) {
12468      this.options.offset = Waypoint.offsetAliases[this.options.offset]
12469    }
12470    this.group.add(this)
12471    this.context.add(this)
12472    allWaypoints[this.key] = this
12473    keyCounter += 1
12474  }
12475
12476  /* Private */
12477  Waypoint.prototype.queueTrigger = function(direction) {
12478    this.group.queueTrigger(this, direction)
12479  }
12480
12481  /* Private */
12482  Waypoint.prototype.trigger = function(args) {
12483    if (!this.enabled) {
12484      return
12485    }
12486    if (this.callback) {
12487      this.callback.apply(this, args)
12488    }
12489  }
12490
12491  /* Public */
12492  /* http://imakewebthings.com/waypoints/api/destroy */
12493  Waypoint.prototype.destroy = function() {
12494    this.context.remove(this)
12495    this.group.remove(this)
12496    delete allWaypoints[this.key]
12497  }
12498
12499  /* Public */
12500  /* http://imakewebthings.com/waypoints/api/disable */
12501  Waypoint.prototype.disable = function() {
12502    this.enabled = false
12503    return this
12504  }
12505
12506  /* Public */
12507  /* http://imakewebthings.com/waypoints/api/enable */
12508  Waypoint.prototype.enable = function() {
12509    this.context.refresh()
12510    this.enabled = true
12511    return this
12512  }
12513
12514  /* Public */
12515  /* http://imakewebthings.com/waypoints/api/next */
12516  Waypoint.prototype.next = function() {
12517    return this.group.next(this)
12518  }
12519
12520  /* Public */
12521  /* http://imakewebthings.com/waypoints/api/previous */
12522  Waypoint.prototype.previous = function() {
12523    return this.group.previous(this)
12524  }
12525
12526  /* Private */
12527  Waypoint.invokeAll = function(method) {
12528    var allWaypointsArray = []
12529    for (var waypointKey in allWaypoints) {
12530      allWaypointsArray.push(allWaypoints[waypointKey])
12531    }
12532    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
12533      allWaypointsArray[i][method]()
12534    }
12535  }
12536
12537  /* Public */
12538  /* http://imakewebthings.com/waypoints/api/destroy-all */
12539  Waypoint.destroyAll = function() {
12540    Waypoint.invokeAll('destroy')
12541  }
12542
12543  /* Public */
12544  /* http://imakewebthings.com/waypoints/api/disable-all */
12545  Waypoint.disableAll = function() {
12546    Waypoint.invokeAll('disable')
12547  }
12548
12549  /* Public */
12550  /* http://imakewebthings.com/waypoints/api/enable-all */
12551  Waypoint.enableAll = function() {
12552    Waypoint.Context.refreshAll()
12553    for (var waypointKey in allWaypoints) {
12554      allWaypoints[waypointKey].enabled = true
12555    }
12556    return this
12557  }
12558
12559  /* Public */
12560  /* http://imakewebthings.com/waypoints/api/refresh-all */
12561  Waypoint.refreshAll = function() {
12562    Waypoint.Context.refreshAll()
12563  }
12564
12565  /* Public */
12566  /* http://imakewebthings.com/waypoints/api/viewport-height */
12567  Waypoint.viewportHeight = function() {
12568    return window.innerHeight || document.documentElement.clientHeight
12569  }
12570
12571  /* Public */
12572  /* http://imakewebthings.com/waypoints/api/viewport-width */
12573  Waypoint.viewportWidth = function() {
12574    return document.documentElement.clientWidth
12575  }
12576
12577  Waypoint.adapters = []
12578
12579  Waypoint.defaults = {
12580    context: window,
12581    continuous: true,
12582    enabled: true,
12583    group: 'default',
12584    horizontal: false,
12585    offset: 0
12586  }
12587
12588  Waypoint.offsetAliases = {
12589    'bottom-in-view': function() {
12590      return this.context.innerHeight() - this.adapter.outerHeight()
12591    },
12592    'right-in-view': function() {
12593      return this.context.innerWidth() - this.adapter.outerWidth()
12594    }
12595  }
12596
12597  window.Waypoint = Waypoint
12598}())
12599;(function() {
12600  'use strict'
12601
12602  function requestAnimationFrameShim(callback) {
12603    window.setTimeout(callback, 1000 / 60)
12604  }
12605
12606  var keyCounter = 0
12607  var contexts = {}
12608  var Waypoint = window.Waypoint
12609  var oldWindowLoad = window.onload
12610
12611  /* http://imakewebthings.com/waypoints/api/context */
12612  function Context(element) {
12613    this.element = element
12614    this.Adapter = Waypoint.Adapter
12615    this.adapter = new this.Adapter(element)
12616    this.key = 'waypoint-context-' + keyCounter
12617    this.didScroll = false
12618    this.didResize = false
12619    this.oldScroll = {
12620      x: this.adapter.scrollLeft(),
12621      y: this.adapter.scrollTop()
12622    }
12623    this.waypoints = {
12624      vertical: {},
12625      horizontal: {}
12626    }
12627
12628    element.waypointContextKey = this.key
12629    contexts[element.waypointContextKey] = this
12630    keyCounter += 1
12631    if (!Waypoint.windowContext) {
12632      Waypoint.windowContext = true
12633      Waypoint.windowContext = new Context(window)
12634    }
12635
12636    this.createThrottledScrollHandler()
12637    this.createThrottledResizeHandler()
12638  }
12639
12640  /* Private */
12641  Context.prototype.add = function(waypoint) {
12642    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
12643    this.waypoints[axis][waypoint.key] = waypoint
12644    this.refresh()
12645  }
12646
12647  /* Private */
12648  Context.prototype.checkEmpty = function() {
12649    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
12650    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
12651    var isWindow = this.element == this.element.window
12652    if (horizontalEmpty && verticalEmpty && !isWindow) {
12653      this.adapter.off('.waypoints')
12654      delete contexts[this.key]
12655    }
12656  }
12657
12658  /* Private */
12659  Context.prototype.createThrottledResizeHandler = function() {
12660    var self = this
12661
12662    function resizeHandler() {
12663      self.handleResize()
12664      self.didResize = false
12665    }
12666
12667    this.adapter.on('resize.waypoints', function() {
12668      if (!self.didResize) {
12669        self.didResize = true
12670        Waypoint.requestAnimationFrame(resizeHandler)
12671      }
12672    })
12673  }
12674
12675  /* Private */
12676  Context.prototype.createThrottledScrollHandler = function() {
12677    var self = this
12678    function scrollHandler() {
12679      self.handleScroll()
12680      self.didScroll = false
12681    }
12682
12683    this.adapter.on('scroll.waypoints', function() {
12684      if (!self.didScroll || Waypoint.isTouch) {
12685        self.didScroll = true
12686        Waypoint.requestAnimationFrame(scrollHandler)
12687      }
12688    })
12689  }
12690
12691  /* Private */
12692  Context.prototype.handleResize = function() {
12693    Waypoint.Context.refreshAll()
12694  }
12695
12696  /* Private */
12697  Context.prototype.handleScroll = function() {
12698    var triggeredGroups = {}
12699    var axes = {
12700      horizontal: {
12701        newScroll: this.adapter.scrollLeft(),
12702        oldScroll: this.oldScroll.x,
12703        forward: 'right',
12704        backward: 'left'
12705      },
12706      vertical: {
12707        newScroll: this.adapter.scrollTop(),
12708        oldScroll: this.oldScroll.y,
12709        forward: 'down',
12710        backward: 'up'
12711      }
12712    }
12713
12714    for (var axisKey in axes) {
12715      var axis = axes[axisKey]
12716      var isForward = axis.newScroll > axis.oldScroll
12717      var direction = isForward ? axis.forward : axis.backward
12718
12719      for (var waypointKey in this.waypoints[axisKey]) {
12720        var waypoint = this.waypoints[axisKey][waypointKey]
12721        if (waypoint.triggerPoint === null) {
12722          continue
12723        }
12724        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
12725        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
12726        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
12727        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
12728        if (crossedForward || crossedBackward) {
12729          waypoint.queueTrigger(direction)
12730          triggeredGroups[waypoint.group.id] = waypoint.group
12731        }
12732      }
12733    }
12734
12735    for (var groupKey in triggeredGroups) {
12736      triggeredGroups[groupKey].flushTriggers()
12737    }
12738
12739    this.oldScroll = {
12740      x: axes.horizontal.newScroll,
12741      y: axes.vertical.newScroll
12742    }
12743  }
12744
12745  /* Private */
12746  Context.prototype.innerHeight = function() {
12747    /*eslint-disable eqeqeq */
12748    if (this.element == this.element.window) {
12749      return Waypoint.viewportHeight()
12750    }
12751    /*eslint-enable eqeqeq */
12752    return this.adapter.innerHeight()
12753  }
12754
12755  /* Private */
12756  Context.prototype.remove = function(waypoint) {
12757    delete this.waypoints[waypoint.axis][waypoint.key]
12758    this.checkEmpty()
12759  }
12760
12761  /* Private */
12762  Context.prototype.innerWidth = function() {
12763    /*eslint-disable eqeqeq */
12764    if (this.element == this.element.window) {
12765      return Waypoint.viewportWidth()
12766    }
12767    /*eslint-enable eqeqeq */
12768    return this.adapter.innerWidth()
12769  }
12770
12771  /* Public */
12772  /* http://imakewebthings.com/waypoints/api/context-destroy */
12773  Context.prototype.destroy = function() {
12774    var allWaypoints = []
12775    for (var axis in this.waypoints) {
12776      for (var waypointKey in this.waypoints[axis]) {
12777        allWaypoints.push(this.waypoints[axis][waypointKey])
12778      }
12779    }
12780    for (var i = 0, end = allWaypoints.length; i < end; i++) {
12781      allWaypoints[i].destroy()
12782    }
12783  }
12784
12785  /* Public */
12786  /* http://imakewebthings.com/waypoints/api/context-refresh */
12787  Context.prototype.refresh = function() {
12788    /*eslint-disable eqeqeq */
12789    var isWindow = this.element == this.element.window
12790    /*eslint-enable eqeqeq */
12791    var contextOffset = isWindow ? undefined : this.adapter.offset()
12792    var triggeredGroups = {}
12793    var axes
12794
12795    this.handleScroll()
12796    axes = {
12797      horizontal: {
12798        contextOffset: isWindow ? 0 : contextOffset.left,
12799        contextScroll: isWindow ? 0 : this.oldScroll.x,
12800        contextDimension: this.innerWidth(),
12801        oldScroll: this.oldScroll.x,
12802        forward: 'right',
12803        backward: 'left',
12804        offsetProp: 'left'
12805      },
12806      vertical: {
12807        contextOffset: isWindow ? 0 : contextOffset.top,
12808        contextScroll: isWindow ? 0 : this.oldScroll.y,
12809        contextDimension: this.innerHeight(),
12810        oldScroll: this.oldScroll.y,
12811        forward: 'down',
12812        backward: 'up',
12813        offsetProp: 'top'
12814      }
12815    }
12816
12817    for (var axisKey in axes) {
12818      var axis = axes[axisKey]
12819      for (var waypointKey in this.waypoints[axisKey]) {
12820        var waypoint = this.waypoints[axisKey][waypointKey]
12821        var adjustment = waypoint.options.offset
12822        var oldTriggerPoint = waypoint.triggerPoint
12823        var elementOffset = 0
12824        var freshWaypoint = oldTriggerPoint == null
12825        var contextModifier, wasBeforeScroll, nowAfterScroll
12826        var triggeredBackward, triggeredForward
12827
12828        if (waypoint.element !== waypoint.element.window) {
12829          elementOffset = waypoint.adapter.offset()[axis.offsetProp]
12830        }
12831
12832        if (typeof adjustment === 'function') {
12833          adjustment = adjustment.apply(waypoint)
12834        }
12835        else if (typeof adjustment === 'string') {
12836          adjustment = parseFloat(adjustment)
12837          if (waypoint.options.offset.indexOf('%') > - 1) {
12838            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
12839          }
12840        }
12841
12842        contextModifier = axis.contextScroll - axis.contextOffset
12843        waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
12844        wasBeforeScroll = oldTriggerPoint < axis.oldScroll
12845        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
12846        triggeredBackward = wasBeforeScroll && nowAfterScroll
12847        triggeredForward = !wasBeforeScroll && !nowAfterScroll
12848
12849        if (!freshWaypoint && triggeredBackward) {
12850          waypoint.queueTrigger(axis.backward)
12851          triggeredGroups[waypoint.group.id] = waypoint.group
12852        }
12853        else if (!freshWaypoint && triggeredForward) {
12854          waypoint.queueTrigger(axis.forward)
12855          triggeredGroups[waypoint.group.id] = waypoint.group
12856        }
12857        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
12858          waypoint.queueTrigger(axis.forward)
12859          triggeredGroups[waypoint.group.id] = waypoint.group
12860        }
12861      }
12862    }
12863
12864    Waypoint.requestAnimationFrame(function() {
12865      for (var groupKey in triggeredGroups) {
12866        triggeredGroups[groupKey].flushTriggers()
12867      }
12868    })
12869
12870    return this
12871  }
12872
12873  /* Private */
12874  Context.findOrCreateByElement = function(element) {
12875    return Context.findByElement(element) || new Context(element)
12876  }
12877
12878  /* Private */
12879  Context.refreshAll = function() {
12880    for (var contextId in contexts) {
12881      contexts[contextId].refresh()
12882    }
12883  }
12884
12885  /* Public */
12886  /* http://imakewebthings.com/waypoints/api/context-find-by-element */
12887  Context.findByElement = function(element) {
12888    return contexts[element.waypointContextKey]
12889  }
12890
12891  window.onload = function() {
12892    if (oldWindowLoad) {
12893      oldWindowLoad()
12894    }
12895    Context.refreshAll()
12896  }
12897
12898
12899  Waypoint.requestAnimationFrame = function(callback) {
12900    var requestFn = window.requestAnimationFrame ||
12901      window.mozRequestAnimationFrame ||
12902      window.webkitRequestAnimationFrame ||
12903      requestAnimationFrameShim
12904    requestFn.call(window, callback)
12905  }
12906  Waypoint.Context = Context
12907}())
12908;(function() {
12909  'use strict'
12910
12911  function byTriggerPoint(a, b) {
12912    return a.triggerPoint - b.triggerPoint
12913  }
12914
12915  function byReverseTriggerPoint(a, b) {
12916    return b.triggerPoint - a.triggerPoint
12917  }
12918
12919  var groups = {
12920    vertical: {},
12921    horizontal: {}
12922  }
12923  var Waypoint = window.Waypoint
12924
12925  /* http://imakewebthings.com/waypoints/api/group */
12926  function Group(options) {
12927    this.name = options.name
12928    this.axis = options.axis
12929    this.id = this.name + '-' + this.axis
12930    this.waypoints = []
12931    this.clearTriggerQueues()
12932    groups[this.axis][this.name] = this
12933  }
12934
12935  /* Private */
12936  Group.prototype.add = function(waypoint) {
12937    this.waypoints.push(waypoint)
12938  }
12939
12940  /* Private */
12941  Group.prototype.clearTriggerQueues = function() {
12942    this.triggerQueues = {
12943      up: [],
12944      down: [],
12945      left: [],
12946      right: []
12947    }
12948  }
12949
12950  /* Private */
12951  Group.prototype.flushTriggers = function() {
12952    for (var direction in this.triggerQueues) {
12953      var waypoints = this.triggerQueues[direction]
12954      var reverse = direction === 'up' || direction === 'left'
12955      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
12956      for (var i = 0, end = waypoints.length; i < end; i += 1) {
12957        var waypoint = waypoints[i]
12958        if (waypoint.options.continuous || i === waypoints.length - 1) {
12959          waypoint.trigger([direction])
12960        }
12961      }
12962    }
12963    this.clearTriggerQueues()
12964  }
12965
12966  /* Private */
12967  Group.prototype.next = function(waypoint) {
12968    this.waypoints.sort(byTriggerPoint)
12969    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
12970    var isLast = index === this.waypoints.length - 1
12971    return isLast ? null : this.waypoints[index + 1]
12972  }
12973
12974  /* Private */
12975  Group.prototype.previous = function(waypoint) {
12976    this.waypoints.sort(byTriggerPoint)
12977    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
12978    return index ? this.waypoints[index - 1] : null
12979  }
12980
12981  /* Private */
12982  Group.prototype.queueTrigger = function(waypoint, direction) {
12983    this.triggerQueues[direction].push(waypoint)
12984  }
12985
12986  /* Private */
12987  Group.prototype.remove = function(waypoint) {
12988    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
12989    if (index > -1) {
12990      this.waypoints.splice(index, 1)
12991    }
12992  }
12993
12994  /* Public */
12995  /* http://imakewebthings.com/waypoints/api/first */
12996  Group.prototype.first = function() {
12997    return this.waypoints[0]
12998  }
12999
13000  /* Public */
13001  /* http://imakewebthings.com/waypoints/api/last */
13002  Group.prototype.last = function() {
13003    return this.waypoints[this.waypoints.length - 1]
13004  }
13005
13006  /* Private */
13007  Group.findOrCreate = function(options) {
13008    return groups[options.axis][options.name] || new Group(options)
13009  }
13010
13011  Waypoint.Group = Group
13012}())
13013;(function() {
13014  'use strict'
13015
13016  var $ = window.jQuery
13017  var Waypoint = window.Waypoint
13018
13019  function JQueryAdapter(element) {
13020    this.$element = $(element)
13021  }
13022
13023  $.each([
13024    'innerHeight',
13025    'innerWidth',
13026    'off',
13027    'offset',
13028    'on',
13029    'outerHeight',
13030    'outerWidth',
13031    'scrollLeft',
13032    'scrollTop'
13033  ], function(i, method) {
13034    JQueryAdapter.prototype[method] = function() {
13035      var args = Array.prototype.slice.call(arguments)
13036      return this.$element[method].apply(this.$element, args)
13037    }
13038  })
13039
13040  $.each([
13041    'extend',
13042    'inArray',
13043    'isEmptyObject'
13044  ], function(i, method) {
13045    JQueryAdapter[method] = $[method]
13046  })
13047
13048  Waypoint.adapters.push({
13049    name: 'jquery',
13050    Adapter: JQueryAdapter
13051  })
13052  Waypoint.Adapter = JQueryAdapter
13053}())
13054;(function() {
13055  'use strict'
13056
13057  var Waypoint = window.Waypoint
13058
13059  function createExtension(framework) {
13060    return function() {
13061      var waypoints = []
13062      var overrides = arguments[0]
13063
13064      if (framework.isFunction(arguments[0])) {
13065        overrides = framework.extend({}, arguments[1])
13066        overrides.handler = arguments[0]
13067      }
13068
13069      this.each(function() {
13070        var options = framework.extend({}, overrides, {
13071          element: this
13072        })
13073        if (typeof options.context === 'string') {
13074          options.context = framework(this).closest(options.context)[0]
13075        }
13076        waypoints.push(new Waypoint(options))
13077      })
13078
13079      return waypoints
13080    }
13081  }
13082
13083  if (window.jQuery) {
13084    window.jQuery.fn.waypoint = createExtension(window.jQuery)
13085  }
13086  if (window.Zepto) {
13087    window.Zepto.fn.waypoint = createExtension(window.Zepto)
13088  }
13089}())
13090;
13091/*!
13092Waypoints Inview Shortcut - 4.0.1
13093Copyright © 2011-2016 Caleb Troughton
13094Licensed under the MIT license.
13095https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
13096*/
13097(function() {
13098  'use strict'
13099
13100  function noop() {}
13101
13102  var Waypoint = window.Waypoint
13103
13104  /* http://imakewebthings.com/waypoints/shortcuts/inview */
13105  function Inview(options) {
13106    this.options = Waypoint.Adapter.extend({}, Inview.defaults, options)
13107    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
13108    this.waypoints = []
13109    this.element = this.options.element
13110    this.createWaypoints()
13111  }
13112
13113  /* Private */
13114  Inview.prototype.createWaypoints = function() {
13115    var configs = {
13116      vertical: [{
13117        down: 'enter',
13118        up: 'exited',
13119        offset: '100%'
13120      }, {
13121        down: 'entered',
13122        up: 'exit',
13123        offset: 'bottom-in-view'
13124      }, {
13125        down: 'exit',
13126        up: 'entered',
13127        offset: 0
13128      }, {
13129        down: 'exited',
13130        up: 'enter',
13131        offset: function() {
13132          return -this.adapter.outerHeight()
13133        }
13134      }],
13135      horizontal: [{
13136        right: 'enter',
13137        left: 'exited',
13138        offset: '100%'
13139      }, {
13140        right: 'entered',
13141        left: 'exit',
13142        offset: 'right-in-view'
13143      }, {
13144        right: 'exit',
13145        left: 'entered',
13146        offset: 0
13147      }, {
13148        right: 'exited',
13149        left: 'enter',
13150        offset: function() {
13151          return -this.adapter.outerWidth()
13152        }
13153      }]
13154    }
13155
13156    for (var i = 0, end = configs[this.axis].length; i < end; i++) {
13157      var config = configs[this.axis][i]
13158      this.createWaypoint(config)
13159    }
13160  }
13161
13162  /* Private */
13163  Inview.prototype.createWaypoint = function(config) {
13164    var self = this
13165    this.waypoints.push(new Waypoint({
13166      context: this.options.context,
13167      element: this.options.element,
13168      enabled: this.options.enabled,
13169      handler: (function(config) {
13170        return function(direction) {
13171          self.options[config[direction]].call(self, direction)
13172        }
13173      }(config)),
13174      offset: config.offset,
13175      horizontal: this.options.horizontal
13176    }))
13177  }
13178
13179  /* Public */
13180  Inview.prototype.destroy = function() {
13181    for (var i = 0, end = this.waypoints.length; i < end; i++) {
13182      this.waypoints[i].destroy()
13183    }
13184    this.waypoints = []
13185  }
13186
13187  Inview.prototype.disable = function() {
13188    for (var i = 0, end = this.waypoints.length; i < end; i++) {
13189      this.waypoints[i].disable()
13190    }
13191  }
13192
13193  Inview.prototype.enable = function() {
13194    for (var i = 0, end = this.waypoints.length; i < end; i++) {
13195      this.waypoints[i].enable()
13196    }
13197  }
13198
13199  Inview.defaults = {
13200    context: window,
13201    enabled: true,
13202    enter: noop,
13203    entered: noop,
13204    exit: noop,
13205    exited: noop
13206  }
13207
13208  Waypoint.Inview = Inview
13209}())
13210;
13211
13212/*
13213 * SmartMenus jQuery v0.9.6
13214 * http://www.smartmenus.org/
13215 *
13216 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd.
13217 * http://vadikom.com/
13218 *
13219 * Released under the MIT license:
13220 * http://www.opensource.org/licenses/MIT
13221 */
13222
13223(function($) {
13224
13225	var menuTrees = [],
13226		IE = !!window.createPopup, // we need to detect it, unfortunately
13227		IElt9 = IE && !document.defaultView,
13228		IElt8 = IE && !document.querySelector,
13229		IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined',
13230		mouse = false, // optimize for touch by default - we will detect for mouse input
13231		mouseDetectionEnabled = false;
13232
13233	// Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.)
13234	function initMouseDetection(disable) {
13235		if (!mouseDetectionEnabled && !disable) {
13236			// if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present
13237			// in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events)
13238			var firstTime = true,
13239				lastMove = null;
13240			$(document).bind({
13241				'mousemove.smartmenus_mouse': function(e) {
13242					var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() };
13243					if (lastMove) {
13244						var deltaX = Math.abs(lastMove.x - thisMove.x),
13245							deltaY = Math.abs(lastMove.y - thisMove.y);
13246	 					if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) {
13247							mouse = true;
13248							// if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes
13249							if (firstTime) {
13250								var $a = $(e.target).closest('a');
13251								if ($a.is('a')) {
13252									$.each(menuTrees, function() {
13253										if ($.contains(this.$root[0], $a[0])) {
13254											this.itemEnter({ currentTarget: $a[0] });
13255											return false;
13256										}
13257									});
13258								}
13259								firstTime = false;
13260							}
13261						}
13262					}
13263					lastMove = thisMove;
13264				},
13265				'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) {
13266					if (!/^(4|mouse|pen)$/.test(e.originalEvent.pointerType)) {
13267						mouse = false;
13268					}
13269				}
13270			});
13271			mouseDetectionEnabled = true;
13272		} else if (mouseDetectionEnabled && disable) {
13273			$(document).unbind('.smartmenus_mouse');
13274			mouseDetectionEnabled = false;
13275		}
13276	};
13277
13278	$.SmartMenus = function(elm, options) {
13279		this.$root = $(elm);
13280		this.opts = options;
13281		this.rootId = ''; // internal
13282		this.$subArrow = null;
13283		this.subMenus = []; // all sub menus in the tree (UL elms) in no particular order (only real - e.g. UL's in mega sub menus won't be counted)
13284		this.activatedItems = []; // stores last activated A's for each level
13285		this.visibleSubMenus = []; // stores visible sub menus UL's
13286		this.showTimeout = 0;
13287		this.hideTimeout = 0;
13288		this.scrollTimeout = 0;
13289		this.clickActivated = false;
13290		this.zIndexInc = 0;
13291		this.$firstLink = null; // we'll use these for some tests
13292		this.$firstSub = null; // at runtime so we'll cache them
13293		this.disabled = false;
13294		this.$disableOverlay = null;
13295		this.init();
13296	};
13297
13298	$.extend($.SmartMenus, {
13299		hideAll: function() {
13300			$.each(menuTrees, function() {
13301				this.menuHideAll();
13302			});
13303		},
13304		destroy: function() {
13305			while (menuTrees.length) {
13306				menuTrees[0].destroy();
13307			}
13308			initMouseDetection(true);
13309		},
13310		prototype: {
13311			init: function(refresh) {
13312				var self = this;
13313
13314				if (!refresh) {
13315					menuTrees.push(this);
13316
13317					this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, '');
13318
13319					if (this.$root.hasClass('sm-rtl')) {
13320						this.opts.rightToLeftSubMenus = true;
13321					}
13322
13323					// init root (main menu)
13324					this.$root
13325						.data('smartmenus', this)
13326						.attr('data-smartmenus-id', this.rootId)
13327						.dataSM('level', 1)
13328						.bind({
13329							'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
13330							'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this)
13331						})
13332						.delegate('a, div.logo-container', {
13333							'mouseenter.smartmenus': $.proxy(this.itemEnter, this),
13334							'mouseleave.smartmenus': $.proxy(this.itemLeave, this),
13335							'mousedown.smartmenus': $.proxy(this.itemDown, this),
13336							'focus.smartmenus': $.proxy(this.itemFocus, this),
13337							'blur.smartmenus': $.proxy(this.itemBlur, this),
13338							'click.smartmenus': $.proxy(this.itemClick, this),
13339							'touchend.smartmenus': $.proxy(this.itemTouchEnd, this)
13340						});
13341
13342					var eNamespace = '.smartmenus' + this.rootId;
13343					// hide menus on tap or click outside the root UL
13344					if (this.opts.hideOnClick) {
13345							$(document).on('touchstart' + eNamespace, $.proxy(this.docTouchStart, this))
13346								.on('touchmove' + eNamespace, $.proxy(this.docTouchMove, this))
13347								.on('touchend' + eNamespace, $.proxy(this.docTouchEnd, this))
13348								// for Opera Mobile < 11.5, webOS browser, etc. we'll check click too
13349								.on('click' + eNamespace, $.proxy(this.docClick, this));
13350					}
13351					// hide sub menus on resize
13352					$(window).on('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
13353					var $vmenu = $('body.vmenu .vmenu-container');
13354					if ( ! $vmenu.length && UNCODE.wwidth > UNCODE.mediaQuery ) {
13355						$(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
13356					}
13357
13358					if (this.opts.subIndicators) {
13359						this.$subArrow = $('<span/>').addClass('sub-arrow');
13360						if (this.opts.subIndicatorsText) {
13361							this.$subArrow.html(this.opts.subIndicatorsText);
13362						}
13363					}
13364
13365					// make sure mouse detection is enabled
13366					initMouseDetection();
13367				}
13368
13369				// init sub menus
13370				this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0);
13371
13372				this.$firstLink = this.$root.find('a').eq(0);
13373
13374				// find current item
13375				if (this.opts.markCurrentItem) {
13376					var reDefaultDoc = /(index|default)\.[^#\?\/]*/i,
13377						reHash = /#.*/,
13378						locHref = window.location.href.replace(reDefaultDoc, ''),
13379						locHrefNoHash = locHref.replace(reHash, '');
13380					this.$root.find('a').each(function() {
13381						var href = this.href.replace(reDefaultDoc, ''),
13382							$this = $(this);
13383						if (href == locHref || href == locHrefNoHash) {
13384							$this.addClass('current');
13385							if (self.opts.markCurrentTree) {
13386								$this.parents('li').each(function() {
13387									var $this = $(this);
13388									if ($this.dataSM('sub')) {
13389										$this.children('a').addClass('current');
13390									}
13391								});
13392							}
13393						}
13394					});
13395				}
13396			},
13397			destroy: function() {
13398				this.menuHideAll();
13399				this.$root
13400					.removeData('smartmenus')
13401					.removeAttr('data-smartmenus-id')
13402					.removeDataSM('level')
13403					.unbind('.smartmenus')
13404					.undelegate('.smartmenus');
13405				var eNamespace = '.smartmenus' + this.rootId;
13406				$(document).unbind(eNamespace);
13407				$(window).unbind(eNamespace);
13408				if (this.opts.subIndicators) {
13409					this.$subArrow = null;
13410				}
13411				var self = this;
13412				$.each(this.subMenus, function() {
13413					if (this.hasClass('mega-menu')) {
13414						this.find('ul').removeDataSM('in-mega');
13415					}
13416					if (this.dataSM('shown-before')) {
13417						if (IElt8) {
13418							this.children().css({ styleFloat: '', width: '' });
13419						}
13420						if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) {
13421							if (!IE6) {
13422								this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap');
13423							} else {
13424								this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', '');
13425							}
13426						}
13427						if (this.dataSM('scroll-arrows')) {
13428							this.dataSM('scroll-arrows').remove();
13429						}
13430						this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' });
13431					}
13432					if (self.opts.subIndicators) {
13433						this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove();
13434					}
13435					this.removeDataSM('shown-before')
13436						.removeDataSM('ie-shim')
13437						.removeDataSM('scroll-arrows')
13438						.removeDataSM('parent-a')
13439						.removeDataSM('level')
13440						.removeDataSM('beforefirstshowfired')
13441						.parent().removeDataSM('sub');
13442				});
13443				if (this.opts.markCurrentItem) {
13444					this.$root.find('a.current').removeClass('current');
13445				}
13446				this.$root = null;
13447				this.$firstLink = null;
13448				this.$firstSub = null;
13449				if (this.$disableOverlay) {
13450					this.$disableOverlay.remove();
13451					this.$disableOverlay = null;
13452				}
13453				menuTrees.splice($.inArray(this, menuTrees), 1);
13454			},
13455			disable: function(noOverlay) {
13456				if (!this.disabled) {
13457					this.menuHideAll();
13458					// display overlay over the menu to prevent interaction
13459					if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) {
13460						var pos = this.$root.offset();
13461						this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({
13462							position: 'absolute',
13463							top: pos.top,
13464							left: pos.left,
13465							width: this.$root.outerWidth(),
13466							height: this.$root.outerHeight(),
13467							zIndex: this.getStartZIndex() + 1,
13468							opacity: 0
13469						}).appendTo(document.body);
13470					}
13471					this.disabled = true;
13472				}
13473			},
13474			docClick: function(e) {
13475				// hide on any click outside the menu or on a menu link
13476				if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) {
13477					this.menuHideAll($(e.target));
13478				}
13479			},
13480			docTouchEnd: function(e) {
13481				if (!this.lastTouch) {
13482					return;
13483				}
13484				if (this.visibleSubMenus.length && (this.lastTouch.x2 === undefined || this.lastTouch.x1 == this.lastTouch.x2) && (this.lastTouch.y2 === undefined || this.lastTouch.y1 == this.lastTouch.y2) && (!this.lastTouch.target || !$.contains(this.$root[0], this.lastTouch.target))) {
13485					if (this.hideTimeout) {
13486						clearTimeout(this.hideTimeout);
13487						this.hideTimeout = 0;
13488					}
13489					// hide with a delay to prevent triggering accidental unwanted click on some page element
13490					var self = this;
13491					this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350);
13492				}
13493				this.lastTouch = null;
13494			},
13495			docTouchMove: function(e) {
13496				if (!this.lastTouch) {
13497					return;
13498				}
13499				var touchPoint = e.originalEvent.touches[0];
13500				this.lastTouch.x2 = touchPoint.pageX;
13501				this.lastTouch.y2 = touchPoint.pageY;
13502			},
13503			docTouchStart: function(e) {
13504				var touchPoint = e.originalEvent.touches[0];
13505				this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target };
13506			},
13507			enable: function() {
13508				if (this.disabled) {
13509					if (this.$disableOverlay) {
13510						this.$disableOverlay.remove();
13511						this.$disableOverlay = null;
13512					}
13513					this.disabled = false;
13514				}
13515			},
13516			getHeight: function($elm) {
13517				return this.getOffset($elm, true);
13518			},
13519			// returns precise width/height float values in IE9+, FF4+, recent WebKit
13520			// http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/
13521			getOffset: function($elm, height) {
13522				var old,
13523					$win = $(window),
13524					winW = $win.width();
13525				if ($elm.css('display') == 'none') {
13526					old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility };
13527					$elm.css({ position: 'absolute', visibility: 'hidden' }).show();
13528					if ( 
13529						($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length)
13530						||
13531						(( $('body').hasClass('vmenu-offcanvas-overlay') || $('body').hasClass('vmenu') ) && winW >= 960 && $elm.closest('.main-menu-container').length && !$elm.closest('.menu-horizontal-inner').length)
13532					) {
13533						$elm.closest('li').addClass('smartmenu-open-item');
13534					}
13535				}
13536				var defaultView = $elm[0].ownerDocument.defaultView,
13537					compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null),
13538					val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']);
13539				if (val) {
13540					val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft'])
13541	 					+ parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight'])
13542	 					+ parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth'])
13543	 					+ parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']);
13544				} else {
13545					val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth;
13546				}
13547				if (old) {
13548					$elm.hide().css(old);
13549				}
13550				return val;
13551			},
13552			getWidth: function($elm) {
13553				return this.getOffset($elm);
13554			},
13555			getStartZIndex: function() {
13556				var zIndex = parseInt(this.$root.css('z-index'));
13557				return !isNaN(zIndex) ? zIndex : 1;
13558			},
13559			handleEvents: function() {
13560				return !this.disabled && this.isCSSOn();
13561			},
13562			handleItemEvents: function($a) {
13563				return this.handleEvents() && !this.isLinkInMegaMenu($a);
13564			},
13565			isCollapsible: function() {
13566				return this.$firstSub.css('position') == 'static';
13567			},
13568			isCSSOn: function() {
13569				return this.$firstLink.css('display') == 'block' || this.$firstLink.css('display') == 'flex' || this.$firstLink.css('display') == 'inline-flex' || this.$firstLink.css('display') == 'table-cell' || this.$firstLink.css('display') == 'inline';
13570			},
13571			isFixed: function() {
13572				return this.$root.css('position') == 'fixed';
13573			},
13574			isLinkInMegaMenu: function($a) {
13575				return !$a.parent().parent().dataSM('level');
13576			},
13577			isTouchMode: function() {
13578				return !mouse || this.isCollapsible();
13579			},
13580			itemActivate: function($a) {
13581				var $li = $a.parent(),
13582					$ul = $li.parent(),
13583					level = $ul.dataSM('level');
13584				// if for some reason the parent item is not activated (e.g. this is an API call to activate the item), activate all parent items first
13585				if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) {
13586					var self = this;
13587					$($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() {
13588						self.itemActivate($(this).dataSM('parent-a'));
13589					});
13590				}
13591				// hide any visible deeper level sub menus
13592				if (this.visibleSubMenus.length > level) {
13593					for (var i = this.visibleSubMenus.length - 1, l = !this.activatedItems[level - 1] || this.activatedItems[level - 1][0] != $a[0] ? level - 1 : level; i > l; i--) {
13594						//if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) {
13595							this.menuHide(this.visibleSubMenus[i]);
13596						//}
13597					}
13598				}
13599				// save new active item and sub menu for this level
13600				this.activatedItems[level - 1] = $a;
13601				this.visibleSubMenus[level - 1] = $ul;
13602				if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) {
13603					return;
13604				}
13605				// show the sub menu if this item has one
13606				var $sub = $li.dataSM('sub');
13607				if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) {
13608					this.menuShow($sub);
13609				}
13610			},
13611			itemBlur: function(e) {
13612				var $a = $(e.currentTarget);
13613				if (!this.handleItemEvents($a)) {
13614					return;
13615				}
13616				this.$root.triggerHandler('blur.smapi', $a[0]);
13617			},
13618			itemClick: function(e) {
13619				var $a = $(e.currentTarget);
13620
13621				if (!this.handleItemEvents($a)) {
13622					return;
13623				}
13624				$a.removeDataSM('mousedown');
13625				if (this.$root.triggerHandler('click.smapi', $a[0]) === false) {
13626					return false;
13627				}
13628				var $sub = $a.parent().dataSM('sub');
13629				if (this.isTouchMode()) {
13630					// undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu
13631					if ($a.dataSM('href')) {
13632						$a.attr('href', $a.dataSM('href')).removeDataSM('href');
13633					}
13634					// if the sub is not visible
13635					if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
13636						// try to activate the item and show the sub
13637						this.itemActivate($a);
13638						// if "itemActivate" showed the sub, prevent the click so that the link is not loaded
13639						// if it couldn't show it, then the sub menus are disabled with an !important declaration (e.g. via mobile styles) so let the link get loaded
13640						if ($sub.is(':visible')) {
13641							return false;
13642						}
13643					}
13644				} else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) {
13645					this.clickActivated = true;
13646					this.menuShow($sub);
13647					return false;
13648				}
13649				if ($a.hasClass('disabled')) {
13650					return false;
13651				}
13652				if (this.$root.triggerHandler('select.smapi', $a[0]) === false) {
13653					return false;
13654				}
13655			},
13656			itemDown: function(e) {
13657				var $a = $(e.currentTarget);
13658				if (!this.handleItemEvents($a)) {
13659					return;
13660				}
13661				$a.dataSM('mousedown', true);
13662			},
13663			itemEnter: function(e) {
13664				var $a = $(e.currentTarget);
13665				if (!this.handleItemEvents($a)) {
13666					return;
13667				}
13668				if (!this.isTouchMode()) {
13669					if (this.showTimeout) {
13670						clearTimeout(this.showTimeout);
13671						this.showTimeout = 0;
13672					}
13673					var self = this;
13674					this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout);
13675				}
13676				this.$root.triggerHandler('mouseenter.smapi', $a[0]);
13677			},
13678			itemFocus: function(e) {
13679				var $a = $(e.currentTarget);
13680				if (!this.handleItemEvents($a)) {
13681					return;
13682				}
13683				// fix (the mousedown check): in some browsers a tap/click produces consecutive focus + click events so we don't need to activate the item on focus
13684				if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) {
13685					this.itemActivate($a);
13686				}
13687				this.$root.triggerHandler('focus.smapi', $a[0]);
13688			},
13689			itemLeave: function(e) {
13690				var $a = $(e.currentTarget);
13691				if (!this.handleItemEvents($a)) {
13692					return;
13693				}
13694				if (!this.isTouchMode()) {
13695					if ($a[0].blur) {
13696						$a[0].blur();
13697					}
13698					if (this.showTimeout) {
13699						clearTimeout(this.showTimeout);
13700						this.showTimeout = 0;
13701					}
13702				}
13703				$a.removeDataSM('mousedown');
13704				this.$root.triggerHandler('mouseleave.smapi', $a[0]);
13705			},
13706			itemTouchEnd: function(e) {
13707				var $a = $(e.currentTarget);
13708				if (!this.handleItemEvents($a)) {
13709					return;
13710				}
13711				// prevent the address bar on iPhone from sliding down when expanding a sub menu
13712				var $sub = $a.parent().dataSM('sub');
13713				if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
13714					$a.dataSM('href', $a.attr('href'));
13715					$a.attr('href', '#');
13716				}
13717			},
13718			menuFixLayout: function($ul) {
13719				// fixes a menu that is being shown for the first time
13720				if (!$ul.dataSM('shown-before')) {
13721					$ul.hide().dataSM('shown-before', true);
13722					// fix the layout of the items in IE<8
13723					if (IElt8) {
13724						$ul.children().css({ styleFloat: 'left', width: '100%' });
13725					}
13726				}
13727			},
13728			menuHide: function($sub) {
13729				if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) {
13730					return;
13731				}
13732				$sub.stop(true, true);
13733				if ($sub.is(':visible')) {
13734					var complete = function() {
13735						// unset z-index
13736						if (IElt9) {
13737							$sub.parent().css('z-index', '');
13738						} else {
13739							$sub.css('z-index', '');
13740						}
13741					};
13742					// if sub is collapsible (mobile view)
13743					if (this.isCollapsible()) {
13744						if (this.opts.collapsibleHideFunction) {
13745							this.opts.collapsibleHideFunction.call(this, $sub, complete);
13746						} else {
13747							$sub.hide(this.opts.collapsibleHideDuration, complete);
13748						}
13749					} else {
13750						if (this.opts.hideFunction) {
13751							this.opts.hideFunction.call(this, $sub, complete);
13752						} else {
13753							$sub.hide(this.opts.hideDuration, complete);
13754						}
13755					}
13756					// remove IE iframe shim
13757					if ($sub.dataSM('ie-shim')) {
13758						$sub.dataSM('ie-shim').remove();
13759					}
13760					// deactivate scrolling if it is activated for this sub
13761					if ($sub.dataSM('scroll')) {
13762						$sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide();
13763					}
13764					// unhighlight parent item
13765					$sub.dataSM('parent-a').removeClass('highlighted');
13766					var level = $sub.dataSM('level');
13767					this.activatedItems.splice(level - 1, 1);
13768					this.visibleSubMenus.splice(level - 1, 1);
13769					this.$root.triggerHandler('hide.smapi', $sub[0]);
13770				}
13771			},
13772			menuHideAll: function($item) {
13773				if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return;
13774				var $win = $(window),
13775					winW = $win.width();
13776				if (this.showTimeout) {
13777					clearTimeout(this.showTimeout);
13778					this.showTimeout = 0;
13779				}
13780				// hide all subs
13781				for (var i = this.visibleSubMenus.length - 1; i > 0; i--) {
13782					if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) {
13783						if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) {
13784							this.menuHide(this.visibleSubMenus[i]);
13785							$(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item');
13786						} else {
13787							return;
13788						}
13789					} else {
13790						//if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) {
13791							this.menuHide(this.visibleSubMenus[i]);
13792						//}
13793					}
13794				}
13795				// hide root if it's popup
13796				if (this.opts.isPopup) {
13797					this.$root.stop(true, true);
13798					if (this.$root.is(':visible')) {
13799						if (this.opts.hideFunction) {
13800							this.opts.hideFunction.call(this, this.$root);
13801						} else {
13802							this.$root.hide(this.opts.hideDuration);
13803						}
13804						// remove IE iframe shim
13805						if (this.$root.dataSM('ie-shim')) {
13806							this.$root.dataSM('ie-shim').remove();
13807						}
13808					}
13809				}
13810				this.activatedItems = [];
13811				this.visibleSubMenus = [];
13812				this.clickActivated = false;
13813				// reset z-index increment
13814				this.zIndexInc = 0;
13815			},
13816			menuIframeShim: function($ul) {
13817				// create iframe shim for the menu
13818				if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) {
13819					$ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 })
13820						.css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' })
13821					);
13822				}
13823			},
13824			menuInit: function($ul) {
13825				if (!$ul.dataSM('in-mega')) {
13826					this.subMenus.push($ul);
13827					// mark UL's in mega drop downs (if any) so we can neglect them
13828					if ($ul.hasClass('mega-menu')) {
13829						$ul.find('ul').dataSM('in-mega', true);
13830					}
13831					// get level (much faster than, for example, using parentsUntil)
13832					var level = 2,
13833						par = $ul[0];
13834					while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) {
13835						level++;
13836					}
13837					// cache stuff
13838					$ul.dataSM('parent-a', $ul.prevAll('a').eq(-1))
13839						.dataSM('level', level)
13840						.parent().dataSM('sub', $ul);
13841					// add sub indicator to parent item
13842					if (this.opts.subIndicators) {
13843						$ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone());
13844					}
13845				}
13846			},
13847			menuPosition: function($sub) {
13848				var fixIE = $('html.ie').length;
13849				// if (fixIE) {
13850				// 	var $rowParent = $($sub).closest('.main-menu-container');
13851				// 	$rowParent.height($rowParent.height());
13852				// }
13853				var $a = $sub.dataSM('parent-a'),
13854					$li = $sub.parent(),
13855					$ul = $sub.parent().parent(),
13856					// $container = $ul.closest('.row-menu-inner').length ? ( $('body').hasClass('megamenu-side-to-side') ? ( $('body').hasClass('boxed-width') ? $ul.closest('.row-menu') : $(window) ) : $ul.closest('.row-menu-inner') ) : $ul.closest('.uncol'),
13857					$container = $ul.closest('.row-menu-inner').length ? ( $('body').hasClass('megamenu-side-to-side') ? $ul.closest('.row-menu') : $ul.closest('.row-menu-inner') ) : $ul.closest('.uncol'),
13858					level = $sub.dataSM('level'),
13859					subW = this.getWidth($sub),
13860					subH = this.getHeight($sub),
13861					itemOffset = $a.offset(),
13862					itemX = itemOffset.left,
13863					itemY = itemOffset.top,
13864					itemW = this.getWidth($a),
13865					itemH = this.getHeight($a),
13866					$win = $(window),
13867					winX = $win.scrollLeft(),
13868					winY = $win.scrollTop(),
13869					winW = $win.width(),
13870					winH = $win.height(),
13871					containerW = $container.width(),
13872					containerOffsetX = containerW + ((winW - containerW) / 2),
13873					horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'),
13874					subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX,
13875					subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY,
13876					x, y, leftPos;
13877
13878				if (horizontalParent) {
13879					x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX;
13880					y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY;
13881				} else {
13882					x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX;
13883					y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY;
13884				}
13885				if (this.opts.keepInViewport && !this.isCollapsible()) {
13886					if (this.isFixed()) {
13887						itemX -= winX;
13888						itemY -= winY;
13889						winX = winY = 0;
13890					}
13891					var absX = itemX + x,
13892						absY = itemY + y;
13893					if (this.opts.rightToLeftSubMenus && absX < winX) {
13894						x = horizontalParent ? winX - absX + x : itemW - subOffsetX;
13895					} else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) {
13896						x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW;
13897					}
13898					if (!horizontalParent) {
13899						if (subH < winH && absY + subH > winY + winH) {
13900							y += winY + winH - subH - absY;
13901						} else if (subH >= winH || absY < winY) {
13902							y += winY - absY;
13903						}
13904					}
13905					// do we need scrolling?
13906					// 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH"
13907					if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) {
13908						var self = this;
13909						if (!$sub.dataSM('scroll-arrows')) {
13910							$sub.dataSM('scroll-arrows', $([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0], $('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]])
13911								.bind({
13912									mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); },
13913									mouseleave: function(e) {
13914										self.menuScrollStop($sub);
13915										self.menuScrollOut($sub, e);
13916									},
13917									'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); }
13918								})
13919								.insertAfter($sub)
13920							);
13921						}
13922						// bind events to show/hide arrows on hover and save scrolling data for this sub
13923						var vportY = winY - (itemY + itemH);
13924						$sub.dataSM('scroll', {
13925								vportY: vportY,
13926								subH: subH,
13927								winH: winH,
13928								step: 1
13929							})
13930							.bind({
13931								'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); },
13932								'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); },
13933								'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); }
13934							})
13935							.dataSM('scroll-arrows').css({ top: 'auto', left: '0', marginLeft: x + (parseInt($sub.css('border-left-width')) || 0), width: this.getWidth($sub) - (parseInt($sub.css('border-left-width')) || 0) - (parseInt($sub.css('border-right-width')) || 0), zIndex: this.get
13935StartZIndex() + this.zIndexInc })
13936							.eq(0).css('margin-top', vportY).end()
13937							.eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end()
13938							.eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show();
13939					}
13940				}
13941				if ( !$sub.closest('.menu-accordion').length ) {
13942					var rightPos = 'auto';
13943					if ( $sub.closest('.grid-filters').length ) {
13944						if ( $sub.closest('.text-right').length ) {
13945							leftPos = '0px';
13946							rightPos = 'auto';
13947						} else {
13948							leftPos = 'auto';
13949							rightPos = '0px';
13950						}
13951						x = 0;
13952					} else {
13953						if ( $sub.hasClass('mega-menu-inner') ) {
13954							$sub.css({ width: containerW});
13955							leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left));
13956							if ( ! $('body').hasClass('megamenu-side-to-side') ) {
13957								leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft'));
13958							}
13959							x = 0;
13960						} else {
13961							leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px';
13962							x = (level > 2 && x >= 0) ? x + 1 : x - 1;
13963						}
13964					}
13965				}
13966
13967				// $sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, right: rightPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-borders').length ? 1 : 0) });
13968				$sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, right: rightPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-borders').length && !$sub.closest('.menu-borders.needs-after').length ? 1 : 0) });
13969				// IE iframe shim
13970				this.menuIframeShim($sub);
13971				if ($sub.dataSM('ie-shim')) {
13972					$sub.dataSM('ie-shim').css({ zIndex: $sub.css('z-index'), width: subW, height: subH, marginLeft: x, marginTop: y - itemH + ($sub.closest('.menu-mini').length ? 0 : 1) });
13973				}
13974			},
13975			menuScroll: function($sub, up, wheel) {
13976				var y = parseFloat($sub.css('margin-top')),
13977					scroll = $sub.dataSM('scroll'),
13978					navH = $('.navbar-main').outerHeight(),
13979					end = scroll.vportY + (up ? navH + 54 : scroll.winH - scroll.subH),
13980					step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step);
13981				$sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end);
13982				y = parseFloat($sub.css('margin-top'));
13983				// show opposite arrow if appropriate
13984				if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) {
13985					$sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show();
13986				}
13987				// accelerate when not using mousewheel to scroll
13988				if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) {
13989					$sub.dataSM('scroll').step += 0.5;
13990				}
13991				// "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used
13992				if (Math.abs(y - end) < 1) {
13993					$sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide();
13994					$sub.dataSM('scroll').step = 1;
13995				} else if (!wheel) {
13996					var self = this;
13997					this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval);
13998				}
13999			},
14000			menuScrollMousewheel: function($sub, e) {
14001				var $closestSub = $(e.target).closest('ul');
14002				while ($closestSub.dataSM('in-mega')) {
14003					$closestSub = $closestSub.parent().closest('ul');
14004				}
14005				if ($closestSub[0] == $sub[0]) {
14006					var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0;
14007					if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) {
14008						this.menuScroll($sub, up, true);
14009					}
14010				}
14011				if ( ! $sub.hasClass('mega-menu-inner') ) {
14012					e.preventDefault();
14013				}
14014			},
14015			menuScrollOut: function($sub, e) {
14016				var reClass = /^scroll-(up|down)/,
14017					$closestSub = $(e.relatedTarget).closest('ul');
14018				while ($closestSub.dataSM('in-mega')) {
14019					$closestSub = $closestSub.parent().closest('ul');
14020				}
14021				if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) {
14022					$sub.dataSM('scroll-arrows').css('visibility', 'hidden');
14023				}
14024			},
14025			menuScrollOver: function($sub, e) {
14026				var reClass = /^scroll-(up|down)/,
14027					$closestSub = $(e.target).closest('ul');
14028				while ($closestSub.dataSM('in-mega')) {
14029					$closestSub = $closestSub.parent().closest('ul');
14030				}
14031				if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) {
14032					$sub.dataSM('scroll-arrows').css('visibility', 'visible');
14033				}
14034			},
14035			menuScrollStop: function($sub) {
14036				if (this.scrollTimeout) {
14037					clearTimeout(this.scrollTimeout);
14038					this.scrollTimeout = 0;
14039					$sub.dataSM('scroll').step = 1;
14040				}
14041			},
14042			menuShow: function($sub) {
14043				if (!$sub.dataSM('beforefirstshowfired')) {
14044					$sub.dataSM('beforefirstshowfired', true);
14045					if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) {
14046						return;
14047					}
14048				}
14049				if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) {
14050					return;
14051				}
14052				this.menuFixLayout($sub);
14053				$sub.stop(true, true);
14054				if (!$sub.is(':visible')) {
14055					$sub.css({
14056						'visibility': 'visible',
14057						'pointer-events': 'auto',
14058					});
14059					// set z-index - for IE < 9 set it to the parent LI
14060					var zIndex = this.getStartZIndex() + (++this.zIndexInc);
14061					if (IElt9) {
14062						$sub.parent().css('z-index', zIndex);
14063					} else {
14064						$sub.css('z-index', zIndex);
14065					}
14066					// highlight parent item
14067					if (this.opts.keepHighlighted || this.isCollapsible()) {
14068						if ($sub.dataSM('parent-a').attr('data-type') != 'title')
14069							$sub.dataSM('parent-a').addClass('highlighted');
14070					}
14071					// min/max-width fix - no way to rely purely on CSS as all UL's are nested
14072					if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) {
14073						if (!IElt8) {
14074							$sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
14075							if (this.opts.subMenusMinWidth) {
14076							 	$sub.css('min-width', this.opts.subMenusMinWidth);
14077							}
14078							if (this.opts.subMenusMaxWidth) {
14079							 	var noMaxWidth = this.getWidth($sub);
14080							 	if ( ! $sub.hasClass('mega-menu-inner') ) {
14081								 	$sub.css('max-width', this.opts.subMenusMaxWidth);
14082							 	}
14083								if (noMaxWidth > this.getWidth($sub)) {
14084									$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
14085								}
14086							}
14087						// IE6,7
14088 						} else {
14089							$sub.children().css('styleFloat', 'none');
14090							if (IE6) {
14091								$sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1)
14092									.children().children('a').css('white-space', 'nowrap');
14093							} else { // IE7
14094								$sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
14095								if (this.opts.subMenusMinWidth) {
14096									$sub.css('min-width', this.opts.subMenusMinWidth);
14097								}
14098							}
14099							if (this.opts.subMenusMaxWidth) {
14100								var noMaxWidth = $sub.width();
14101								if (IE6) {
14102							 		var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width();
14103									if (noMaxWidth > maxWidth) {
14104										$sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', '');
14105									} else {
14106										$sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' });
14107									}
14108								} else { // IE7
14109								 	if ( ! $sub.hasClass('mega-menu-inner') ) {
14110									 	$sub.css('max-width', this.opts.subMenusMaxWidth);
14111								 	}
14112									if (noMaxWidth > $sub.width()) {
14113										$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
14114									} else {
14115										$sub.width(noMaxWidth);
14116									}
14117								}
14118							} else {
14119							 	$sub.width($sub.width());
14120							}
14121							$sub.children().css('styleFloat', 'left');
14122						}
14123					}
14124					if ( $sub.hasClass('mega-menu-inner') && $('body').hasClass('scrollable-megamenu') && UNCODE.wwidth > UNCODE.mediaQuery ) {
14125						var $nav = $('.navbar-main'),
14126							navH = 0,
14127							navTop = 0,
14128							$vmenu = $('body.vmenu .vmenu-container, body.menu-overlay .vmenu-container, body.menu-offcanvas .vmenu-container');
14129						if ( $nav.length && typeof $nav[0] !== 'undefined' ) {
14130							var navRect = $nav[0].getBoundingClientRect();
14131							navH = navRect.height;
14132							navTop = navRect.top;
14133						}
14134						if ( ! $vmenu.length ) {
14135							$sub.css({ maxHeight: UNCODE.wheight - navH });
14136						}
14137					}
14138					this.menuPosition($sub);
14139					// insert IE iframe shim
14140					if ($sub.dataSM('ie-shim')) {
14141						$sub.dataSM('ie-shim').insertBefore($sub);
14142					}
14143					var complete = function() {
14144						// fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used
14145						$sub.css('overflow', '');
14146					};
14147					// if sub is collapsible (mobile view)
14148					if (this.isCollapsible()) {
14149						if (this.opts.collapsibleShowFunction) {
14150							this.opts.collapsibleShowFunction.call(this, $sub, complete);
14151						} else {
14152							$sub.show(this.opts.collapsibleShowDuration, complete);
14153						}
14154					} else {
14155						if (this.opts.showFunction) {
14156							this.opts.showFunction.call(this, $sub, complete);
14157						} else {
14158							$sub.show(this.opts.showDuration, complete);
14159						}
14160					}
14161					// save new sub menu for this level
14162					this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub;
14163					this.$root.triggerHandler('show.smapi', $sub[0]);
14164				}
14165			},
14166			popupHide: function(noHideTimeout) {
14167				if (this.hideTimeout) {
14168					clearTimeout(this.hideTimeout);
14169					this.hideTimeout = 0;
14170				}
14171				var self = this;
14172				this.hideTimeout = setTimeout(function() {
14173					self.menuHideAll();
14174				}, noHideTimeout ? 1 : this.opts.hideTimeout);
14175			},
14176			popupShow: function(left, top) {
14177				if (!this.opts.isPopup) {
14178					alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.');
14179					return;
14180				}
14181				if (this.hideTimeout) {
14182					clearTimeout(this.hideTimeout);
14183					this.hideTimeout = 0;
14184				}
14185				this.menuFixLayout(this.$root);
14186				this.$root.stop(true, true);
14187				if (!this.$root.is(':visible')) {
14188					this.$root.css({ left: left, top: top });
14189					// IE iframe shim
14190					this.menuIframeShim(this.$root);
14191					if (this.$root.dataSM('ie-shim')) {
14192						this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
14192: left, top: top }).insertBefore(this.$root);
14193					}
14194					// show menu
14195					if (this.opts.showFunction) {
14196						this.opts.showFunction.call(this, this.$root);
14197					} else {
14198						this.$root.show(this.opts.showDuration);
14199					}
14200					this.visibleSubMenus[0] = this.$root;
14201				}
14202			},
14203			refresh: function() {
14204				this.menuHideAll();
14205				this.$root.find('ul').each(function() {
14206						var $this = $(this);
14207						if ($this.dataSM('scroll-arrows')) {
14208							$this.dataSM('scroll-arrows').remove();
14209						}
14210					})
14211					.removeDataSM('in-mega')
14212					.removeDataSM('shown-before')
14213					.removeDataSM('ie-shim')
14214					.removeDataSM('scroll-arrows')
14215					.removeDataSM('parent-a')
14216					.removeDataSM('level')
14217					.removeDataSM('beforefirstshowfired');
14218				this.$root.find('a.has-submenu').removeClass('has-submenu')
14219					.parent().removeDataSM('sub');
14220				if (this.opts.subIndicators) {
14221					this.$root.find('span.sub-arrow').remove();
14222				}
14223				if (this.opts.markCurrentItem) {
14224					this.$root.find('a.current').removeClass('current');
14225				}
14226				this.subMenus = [];
14227				this.init(true);
14228			},
14229			rootOut: function(e) {
14230				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
14231					return;
14232				}
14233				if (this.hideTimeout) {
14234					clearTimeout(this.hideTimeout);
14235					this.hideTimeout = 0;
14236				}
14237				if (!this.opts.showOnClick || !this.opts.hideOnClick) {
14238					var self = this;
14239					this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout);
14240				}
14241			},
14242			rootOver: function(e) {
14243				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
14244					return;
14245				}
14246				if (this.hideTimeout) {
14247					clearTimeout(this.hideTimeout);
14248					this.hideTimeout = 0;
14249				}
14250			},
14251			winResize: function(e) {
14252				if (!this.handleEvents()) {
14253					// we still need to resize the disable overlay if it's visible
14254					if (this.$disableOverlay) {
14255						var pos = this.$root.offset();
14256	 					this.$disableOverlay.css({
14257							top: pos.top,
14258							left: pos.left,
14259							width: this.$root.outerWidth(),
14260							height: this.$root.outerHeight()
14261						});
14262					}
14263					return;
14264				}
14265				// hide sub menus on resize - on mobile do it only on orientation change
14266				if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) {
14267					if (this.activatedItems.length) {
14268						this.activatedItems[this.activatedItems.length - 1][0].blur();
14269					}
14270					this.menuHideAll();
14271				}
14272			}
14273		}
14274	});
14275
14276	$.fn.dataSM = function(key, val) {
14277		if (val) {
14278			return this.data(key + '_smartmenus', val);
14279		}
14280		return this.data(key + '_smartmenus');
14281	}
14282
14283	$.fn.removeDataSM = function(key) {
14284		return this.removeData(key + '_smartmenus');
14285	}
14286
14287	$.fn.smartmenus = function(options) {
14288		if (typeof options == 'string') {
14289			var args = arguments,
14290				method = options;
14291			Array.prototype.shift.call(args);
14292			return this.each(function() {
14293				var smartmenus = $(this).data('smartmenus');
14294				if (smartmenus && smartmenus[method]) {
14295					smartmenus[method].apply(smartmenus, args);
14296				}
14297			});
14298		}
14299		var opts = $.extend({}, $.fn.smartmenus.defaults, options);
14300		return this.each(function() {
14301			new $.SmartMenus(this, opts);
14302		});
14303	}
14304
14305	// default settings
14306	$.fn.smartmenus.defaults = {
14307		isPopup:		false,		// is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar
14308		mainMenuSubOffsetX:	0,		// pixels offset from default position
14309		mainMenuSubOffsetY:	0,		// pixels offset from default position
14310		subMenusSubOffsetX:	0,		// pixels offset from default position
14311		subMenusSubOffsetY:	0,		// pixels offset from default position
14312		subMenusMinWidth:	false, //'10em',		// min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
14313		subMenusMaxWidth:	false, //'20em',		// max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
14314		subIndicators: 		true,		// create sub menu indicators - creates a SPAN and inserts it in the A
14315		subIndicatorsPos: 	'prepend',	// position of the SPAN relative to the menu item content ('prepend', 'append')
14316		subIndicatorsText:	'+',		// [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too)
14317		scrollStep: 		30,		// pixels step when scrolling long sub menus that do not fit in the viewport height
14318		scrollInterval:		30,		// interval between each scrolling step
14319		scrollAccelerate:	true,		// accelerate scrolling or use a fixed step
14320		showTimeout:		250,		// timeout before showing the sub menus
14321		hideTimeout:		500,		// timeout before hiding the sub menus
14322		showDuration:		0,		// duration for show animation - set to 0 for no animation - matters only if showFunction:null
14323		showFunction:		null,		// custom function to use when showing a sub menu (the default is the jQuery 'show')
14324							// don't forget to call complete() at the end of whatever you do
14325							// e.g.: function($ul, complete) { $ul.fadeIn(250, complete); }
14326		hideDuration:		0,		// duration for hide animation - set to 0 for no animation - matters only if hideFunction:null
14327		hideFunction:		function($ul, complete) { $ul.fadeOut(200, complete); },	// custom function to use when hiding a sub menu (the default is the jQuery 'hide')
14328							// don't forget to call complete() at the end of whatever you do
14329							// e.g.: function($ul, complete) { $ul.fadeOut(250, complete); }
14330		collapsibleShowDuration:0,		// duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null
14331		collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); },	// custom function to use when showing a collapsible sub menu
14332							// (i.e. when mobile styles are used to make the sub menus collapsible)
14333		collapsibleHideDuration:0,		// duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null
14334		collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); },	// custom function to use when hiding a collapsible sub menu
14335							// (i.e. when mobile styles are used to make the sub menus collapsible)
14336		showOnClick:		false,		// show the first-level sub menus onclick instead of onmouseover (matters only for mouse input)
14337		hideOnClick:		true,		// hide the sub menus on click/tap anywhere on the page
14338		keepInViewport:		true,		// reposition the sub menus if needed to make sure they always appear inside the viewport
14339		keepHighlighted:	true,		// keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's)
14340		markCurrentItem:	false,		// automatically add the 'current' class to the A element of the item linking to the current URL
14341		markCurrentTree:	true,		// add the 'current' class also to the A elements of all ancestor items of the current item
14342		rightToLeftSubMenus:	false,		// right to left display of the sub menus (check the CSS for the sub indicators' position)
14343		bottomToTopSubMenus:	false,		// bottom to top display of the sub menus
14344		overlapControlsInIE:	true		// make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.)
14345	};
14346
14347})(jQuery);
14348/*
14349 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/
14350 * Open source under the BSD License.
14351 * Copyright © 2008 George McGinley Smith
14352 * All rights reserved.
14353 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE
14354*/
14355
14356/* globals jQuery, define, module, require */
14357(function (factory) {
14358	if (typeof define === "function" && define.amd) {
14359		define(['jquery'], function ($) {
14360			return factory($);
14361		});
14362	} else if (typeof module === "object" && typeof module.exports === "object") {
14363		module.exports = factory(require('jquery'));
14364	} else {
14365		factory(jQuery);
14366	}
14367})(function($){
14368
14369	// Preserve the original jQuery "swing" easing as "jswing"
14370	if (typeof $.easing !== 'undefined') {
14371		$.easing['jswing'] = $.easing['swing'];
14372	}
14373
14374	var pow = Math.pow,
14375		sqrt = Math.sqrt,
14376		sin = Math.sin,
14377		cos = Math.cos,
14378		PI = Math.PI,
14379		c1 = 1.70158,
14380		c2 = c1 * 1.525,
14381		c3 = c1 + 1,
14382		c4 = ( 2 * PI ) / 3,
14383		c5 = ( 2 * PI ) / 4.5;
14384
14385	// x is the fraction of animation progress, in the range 0..1
14386	function bounceOut(x) {
14387		var n1 = 7.5625,
14388			d1 = 2.75;
14389		if ( x < 1/d1 ) {
14390			return n1*x*x;
14391		} else if ( x < 2/d1 ) {
14392			return n1*(x-=(1.5/d1))*x + .75;
14393		} else if ( x < 2.5/d1 ) {
14394			return n1*(x-=(2.25/d1))*x + .9375;
14395		} else {
14396			return n1*(x-=(2.625/d1))*x + .984375;
14397		}
14398	}
14399
14400	$.extend( $.easing, {
14401		def: 'easeOutQuad',
14402		swing: function (x) {
14403			return $.easing[$.easing.def](x);
14404		},
14405		easeInQuad: function (x) {
14406			return x * x;
14407		},
14408		easeOutQuad: function (x) {
14409			return 1 - ( 1 - x ) * ( 1 - x );
14410		},
14411		easeInOutQuad: function (x) {
14412			return x < 0.5 ?
14413				2 * x * x :
14414				1 - pow( -2 * x + 2, 2 ) / 2;
14415		},
14416		easeInCubic: function (x) {
14417			return x * x * x;
14418		},
14419		easeOutCubic: function (x) {
14420			return 1 - pow( 1 - x, 3 );
14421		},
14422		easeInOutCubic: function (x) {
14423			return x < 0.5 ?
14424				4 * x * x * x :
14425				1 - pow( -2 * x + 2, 3 ) / 2;
14426		},
14427		easeInQuart: function (x) {
14428			return x * x * x * x;
14429		},
14430		easeOutQuart: function (x) {
14431			return 1 - pow( 1 - x, 4 );
14432		},
14433		easeInOutQuart: function (x) {
14434			return x < 0.5 ?
14435				8 * x * x * x * x :
14436				1 - pow( -2 * x + 2, 4 ) / 2;
14437		},
14438		easeInQuint: function (x) {
14439			return x * x * x * x * x;
14440		},
14441		easeOutQuint: function (x) {
14442			return 1 - pow( 1 - x, 5 );
14443		},
14444		easeInOutQuint: function (x) {
14445			return x < 0.5 ?
14446				16 * x * x * x * x * x :
14447				1 - pow( -2 * x + 2, 5 ) / 2;
14448		},
14449		easeInSine: function (x) {
14450			return 1 - cos( x * PI/2 );
14451		},
14452		easeOutSine: function (x) {
14453			return sin( x * PI/2 );
14454		},
14455		easeInOutSine: function (x) {
14456			return -( cos( PI * x ) - 1 ) / 2;
14457		},
14458		easeInExpo: function (x) {
14459			return x === 0 ? 0 : pow( 2, 10 * x - 10 );
14460		},
14461		easeOutExpo: function (x) {
14462			return x === 1 ? 1 : 1 - pow( 2, -10 * x );
14463		},
14464		easeInOutExpo: function (x) {
14465			return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ?
14466				pow( 2, 20 * x - 10 ) / 2 :
14467				( 2 - pow( 2, -20 * x + 10 ) ) / 2;
14468		},
14469		easeInCirc: function (x) {
14470			return 1 - sqrt( 1 - pow( x, 2 ) );
14471		},
14472		easeOutCirc: function (x) {
14473			return sqrt( 1 - pow( x - 1, 2 ) );
14474		},
14475		easeInOutCirc: function (x) {
14476			return x < 0.5 ?
14477				( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 :
14478				( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2;
14479		},
14480		easeInElastic: function (x) {
14481			return x === 0 ? 0 : x === 1 ? 1 :
14482				-pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 );
14483		},
14484		easeOutElastic: function (x) {
14485			return x === 0 ? 0 : x === 1 ? 1 :
14486				pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1;
14487		},
14488		easeInOutElastic: function (x) {
14489			return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ?
14490				-( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 :
14491				pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1;
14492		},
14493		easeInBack: function (x) {
14494			return c3 * x * x * x - c1 * x * x;
14495		},
14496		easeOutBack: function (x) {
14497			return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 );
14498		},
14499		easeInOutBack: function (x) {
14500			return x < 0.5 ?
14501				( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 :
14502				( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2;
14503		},
14504		easeInBounce: function (x) {
14505			return 1 - bounceOut( 1 - x );
14506		},
14507		easeOutBounce: bounceOut,
14508		easeInOutBounce: function (x) {
14509			return x < 0.5 ?
14510				( 1 - bounceOut( 1 - 2 * x ) ) / 2 :
14511				( 1 + bounceOut( 2 * x - 1 ) ) / 2;
14512		}
14513	});
14514	return $;
14515});
14516
14517/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
14518 * Licensed under the MIT License (LICENSE.txt).
14519 *
14520 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
14521 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
14522 * Thanks to: Seamus Leahy for adding deltaX and deltaY
14523 *
14524 * Version: 3.0.6
14525 *
14526 * Requires: 1.2.2+
14527 */
14528(function($) {
14529    var types = ['DOMMouseScroll', 'mousewheel'];
14530    if ($.event.fixHooks) {
14531        for (var i = types.length; i;) {
14532            $.event.fixHooks[types[--i]] = $.event.mouseHooks;
14533        }
14534    }
14535    $.event.special.mousewheel = {
14536        setup: function() {
14537            if (this.addEventListener) {
14538                for (var i = types.length; i;) {
14539                    this.addEventListener(types[--i], handler, false);
14540                }
14541            } else {
14542                this.onmousewheel = handler;
14543            }
14544        },
14545        teardown: function() {
14546            if (this.removeEventListener) {
14547                for (var i = types.length; i;) {
14548                    this.removeEventListener(types[--i], handler, false);
14549                }
14550            } else {
14551                this.onmousewheel = null;
14552            }
14553        }
14554    };
14555    $.fn.extend({
14556        mousewheel: function(fn) {
14557            return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
14558        },
14559        unmousewheel: function(fn) {
14560            return this.unbind("mousewheel", fn);
14561        }
14562    });
14563
14564    function handler(event) {
14565        var orgEvent = event || window.event,
14566            args = [].slice.call(arguments, 1),
14567            delta = 0,
14568            returnValue = true,
14569            deltaX = 0,
14570            deltaY = 0;
14571        event = $.event.fix(orgEvent);
14572        event.type = "mousewheel";
14573        // Old school scrollwheel delta
14574        if (orgEvent.wheelDelta) {
14575            delta = orgEvent.wheelDelta / 120;
14576        }
14577        if (orgEvent.detail) {
14578            delta = -orgEvent.detail / 3;
14579        }
14580        // New school multidimensional scroll (touchpads) deltas
14581        deltaY = delta;
14582        // Gecko
14583        if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) {
14584            deltaY = 0;
14585            deltaX = -1 * delta;
14586        }
14587        // Webkit
14588        if (orgEvent.wheelDeltaY !== undefined) {
14589            deltaY = orgEvent.wheelDeltaY / 120;
14590        }
14591        if (orgEvent.wheelDeltaX !== undefined) {
14592            deltaX = -1 * orgEvent.wheelDeltaX / 120;
14593        }
14594        // Add event and delta to the front of the arguments
14595        args.unshift(event, delta, deltaX, deltaY);
14596        return ($.event.dispatch || $.event.handle).apply(this, args);
14597    }
14598})(jQuery);
14599/**
14600 * jQuery iLightBox - Revolutionary Lightbox Plugin
14601 * http://www.ilightbox.net/
14602 *
14603 * @version: 2.2.4 - October 14, 2017
14604 *
14605 * @author: iProDev (Hemn Chawroka)
14606 *          http://www.iprodev.com/
14607 *
14608 */
14609(function($, window, undefined) {
14610
14611	var extensions = {
14612			flash: ['swf'],
14613			image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'],
14614			iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'],
14615			video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v']
14616		},
14617
14618		// Global DOM elements
14619		$win = $(window),
14620		$doc = $(document),
14621
14622		// Support indicators
14623		browser,
14624		transform,
14625		gpuAcceleration,
14626		fullScreenApi = '',
14627		userAgent = navigator.userAgent || navigator.vendor || window.opera,
14628        supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1),
14629        ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1,
14630        isMobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(userAgent.substr(0, 4)),
14631
14632		// Events
14633		clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox",
14634		touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox",
14635		touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox",
14636		touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox",
14637
14638		// Math shorthands
14639		abs = Math.abs,
14640		sqrt = Math.sqrt,
14641		round = Math.round,
14642		max = Math.max,
14643		min = Math.min,
14644		floor = Math.floor,
14645		random = Math.random,
14646
14647		pluginspages = {
14648			quicktime: 'http://www.apple.com/quicktime/download',
14649			flash: 'http://www.adobe.com/go/getflash'
14650		},
14651
14652		iLightBox = function(el, options, items, instant) {
14653			var iL = this;
14654
14655			iL.options = options,
14656				iL.selector = options.selector || el,
14657				iL.context = document,
14658				iL.instant = instant;
14659
14660			if (items.length < 1) iL.attachItems();
14661			else iL.items = items;
14662
14663			iL.vars = {
14664				total: iL.items.length,
14665				start: 0,
14666				current: null,
14667				next: null,
14668				prev: null,
14669				BODY: $('body'),
14670				loadRequests: 0,
14671				overlay: $('<div class="ilightbox-overlay"></div>'),
14672				loader: $('<div class="ilightbox-loader"><div></div></div>'),
14673				toolbar: $('<div class="ilightbox-toolbar"></div>'),
14674				innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'),
14675				title: $('<div class="ilightbox-title"></div>'),
14676				closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'),
14677				fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'),
14678				innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'),
14679				innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'),
14680				innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'),
14681				holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
14682				nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
14683				prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
14684				nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'),
14685				prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
14686				thumbnails: $('<div class="ilightbox-thumbnails" ondragstart="return false;"><div class="ilightbox-thumbnails-container"><a class="ilightbox-thumbnails-dragger"></a><div class="ilightbox-thumbnails-grid"></div></div></div>'),
14687				thumbs: false,
14688				nextLock: false,
14689				prevLock: false,
14690				hashLock: false,
14691				isMobile: false,
14692				mobileMaxWidth: 980,
14693				isInFullScreen: false,
14694				isSwipe: false,
14695				mouseID: 0,
14696				cycleID: 0,
14697				isPaused: 0,
14698				captionHeight: 39,
14699			};
14700
14701			// Hideable elements with mousemove event
14702			iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton);
14703
14704			iL.normalizeItems();
14705
14706			//Check necessary plugins
14707			iL.availPlugins();
14708
14709			//Set startFrom
14710			iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom;
14711
14712			//If randomStart
14713			iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom;
14714			iL.vars.start = iL.options.startFrom;
14715
14716			if (instant) iL.instantCall();
14717			else iL.patchItemsEvents();
14718
14719			if (iL.options.linkId) {
14720				iL.hashChangeHandler();
14721				$win.iLightBoxHashChange(function() {
14722					iL.hashChangeHandler();
14723				});
14724			}
14725
14726			if (supportTouch) {
14727				var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig,
14728					replace = "itap";
14729				iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace),
14730					iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace),
14731					iL.options.social.show = iL.options.social.show.replace(RegExp, replace),
14732					iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace);
14733			}
14734
14735			if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) {
14736				$.extend(iL.options.styles, {
14737					nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4,
14738					prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4,
14739					nextOpacity: 0,
14740					prevOpacity: 0
14741				});
14742			}
14743		};
14744
14745	//iLightBox helpers
14746	iLightBox.prototype = {
14747		showLoader: function() {
14748			var iL = this;
14749			iL.vars.loadRequests += 1;
14750			if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({
14751				//top: '-30px'
14752				opacity: '1'
14753			}, iL.options.show.speed, 'easeOutCirc');
14754			else iL.vars.loader.addClass('ilightbox-show').stop().animate({
14755				//left: '-30px'
14756				opacity: '1'
14757			}, iL.options.show.speed, 'easeOutCirc');
14758		},
14759
14760		hideLoader: function() {
14761			var iL = this;
14762			iL.vars.loadRequests -= 1;
14763			iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests;
14764			if (iL.options.path.toLowerCase() == "horizontal") {
14765				if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({
14766					//top: '-192px'
14767					opacity: '0'
14768				}, iL.options.show.speed, 'easeInCirc');
14769			} else {
14770				if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({
14771					//left: '-192px'
14772					opacity: '0'
14773				}, iL.options.show.speed, 'easeInCirc');
14774			}
14775		},
14776
14777		createUI: function() {
14778			var iL = this;
14779
14780			iL.ui = {
14781				currentElement: iL.vars.holder,
14782				nextElement: iL.vars.nextPhoto,
14783				prevElement: iL.vars.prevPhoto,
14784				currentItem: iL.vars.current,
14785				nextItem: iL.vars.next,
14786				prevItem: iL.vars.prev,
14787				hide: function() {
14788					iL.closeAction();
14789				},
14790				refresh: function() {
14791					(arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto();
14792				},
14793				fullscreen: function() {
14794					iL.fullScreenAction();
14795				}
14796			};
14797		},
14798
14799		attachItems: function() {
14800			var iL = this,
14801				itemsObject = new Array(),
14802				items = new Array();
14803
14804			$(iL.selector, iL.context).each(function() {
14805				var t = $(this),
14806					URL = t.attr(iL.options.attr) || null,
14807					options = t.data("options") && eval("({" + t.data("options") + "})") || {},
14808					caption = t.data('caption'),
14809					title = t.data('title'),
14810					type = t.data('type') || getTypeByExtension(URL),
14811					clone = t.data('lbox-clone') || false;
14812
14813				//Uncode addition ##START##
14814				if (type === false) {
14815					return;
14816				}
14817				//Uncode addition ##END##
14818
14819				if (t.data('lbox-clone') != undefined) return;
14820
14821				//Uncode addition ##START##
14822				if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) {
14823					var ALBUM_URLS = JSON.parse(t.attr('data-album')),
14824						URL_i,
14825						URLS_LENGHT = ALBUM_URLS.length;
14826
14827					for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) {
14828						if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) {
14829							var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\'';
14830							item_opts = item_opts && eval("({" + item_opts + "})") || {},
14831							items.push({
14832								URL: ALBUM_URLS[URL_i].url,
14833								caption: ALBUM_URLS[URL_i].caption,
14834								title: ALBUM_URLS[URL_i].title,
14835								type: getTypeByExtension(ALBUM_URLS[URL_i].url),
14836								options: item_opts,
14837								clone: clone
14838							});
14839							var newT = t;
14840							newT.attr('href',ALBUM_URLS[URL_i].url);
14841							if (!iL.instant) itemsObject.push(newT);
14842						}
14843					}
14844				} else {
14845				//Uncode addition ##END##
14846					items.push({
14847						URL: URL,
14848						caption: caption,
14849						title: title,
14850						type: type,
14851						options: options,
14852						clone: clone
14853					});
14854				}
14855
14856
14857				if (iL.vars != undefined) iL.vars.total = items.length;
14858
14859				if (!iL.instant) itemsObject.push(t);
14860			});
14861
14862			iL.items = items,
14863				iL.itemsObject = itemsObject;
14864
14865		},
14866
14867		normalizeItems: function() {
14868			var iL = this,
14869				newItems = new Array();
14870
14871			$.each(iL.items, function(key, val) {
14872
14873				if (typeof val == "string") val = {
14874					url: val
14875				};
14876
14877				var URL = val.url || val.URL || null,
14878					options = val.options || {},
14879					caption = val.caption || null,
14880					title = val.title || null,
14881					type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL),
14882					ext = (typeof URL != 'object') ? getExtension(URL) : '';
14883
14884				options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
14885				options.videoType = options.videoType || null,
14886				options.skin = options.skin || iL.options.skin,
14887				options.width = options.width || null,
14888				options.height = options.height || null,
14889				options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true,
14890				options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true,
14891				options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons);
14892
14893				if (type == "video") {
14894					options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {};
14895
14896					options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null;
14897					options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls";
14898					options.html5video.preload = options.html5video.preload || "metadata";
14899					options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false;
14900					//UNCODE addition
14901					options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false;
14902				}
14903
14904				if (!options.width || !options.height) {
14905					if (type == "video") options.width = 1280, options.height = 720;
14906					else if (type == "iframe") options.width = '100%', options.height = '90%';
14907					else if (type == "flash") options.width = 1280, options.height = 720;
14908				}
14909
14910				delete val.url;
14911				val.index = key;
14912				val.URL = URL;
14913				val.caption = caption;
14914				val.title = title;
14915				val.type = type;
14916				val.options = options;
14917				val.ext = ext;
14918
14919				newItems.push(val);
14920			});
14921
14922			iL.items = newItems;
14923		},
14924
14925		instantCall: function() {
14926			var iL = this,
14927				key = iL.vars.start;
14928
14929			iL.vars.current = key;
14930			iL.vars.next = (iL.items[key + 1]) ? key + 1 : null;
14931			iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null;
14932
14933			iL.addContents();
14934			iL.patchEvents();
14935		},
14936
14937		addContents: function() {
14938			var iL = this,
14939				vars = iL.vars,
14940				opts = iL.options,
14941				viewport = getViewport(),
14942				path = opts.path.toLowerCase(),
14943				recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) {
14944					return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition);
14945				}),
14946				needRecognition = recognizingItems.length > 0;
14947
14948			if (opts.mobileOptimizer && !opts.innerToolbar)
14949				vars.isMobile = viewport.width <= vars.mobileMaxWidth;
14950
14951			vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity);
14952
14953			if (opts.linkId)
14954				vars.overlay[0].setAttribute('linkid', opts.linkId);
14955
14956			//Add Toolbar Buttons
14957			if (opts.controls.toolbar) {
14958				vars.toolbar.addClass(opts.skin).append(vars.closeButton);
14959				if (opts.controls.fullscreen)
14960					vars.toolbar.append(vars.fullScreenButton);
14961				if (opts.controls.slideshow)
14962					vars.toolbar.append(vars.innerPlayButton);
14963				if (vars.total > 1)
14964					vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton);
14965			}
14966
14967			//Append elements to body
14968			vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto);
14969
14970			if (!opts.innerToolbar)
14971				vars.BODY.append(vars.toolbar);
14972			if (opts.controls.arrows)
14973				vars.BODY.append(vars.nextButton).append(vars.prevButton);
14974
14975			if (opts.controls.thumbnail && vars.total > 1) {
14976				vars.BODY.append(vars.thumbnails);
14977				vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path);
14978				$('div.ilightbox-thumbnails-grid', vars.thumbnails).empty();
14979				vars.thumbs = true;
14980			}
14981
14982			//Configure loader and arrows
14983			var loaderCss = (opts.path.toLowerCase() == "horizontal") ? {
14984				left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2))
14985			} : {
14986				top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2))
14987			};
14988			vars.loader.addClass(opts.skin).css(loaderCss);
14989			vars.nextButton.add(vars.prevButton).addClass(opts.skin);
14990			if (path == "horizontal")
14991				vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal');
14992
14993			// Configure arrow buttons
14994			vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile');
14995
14996			if (!opts.infinite) {
14997				vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
14998
14999				if (vars.current == 0)
15000					vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
15001				if (vars.current >= vars.total - 1)
15002					vars.nextButton.add(vars.innerNextButton).addClass('disabled');
15003			}
15004
15005			if (opts.show.effect) {
15006				vars.overlay.stop().fadeIn(opts.show.speed);
15007				vars.toolbar.stop().fadeIn(opts.show.speed);
15008			} else {
15009				vars.overlay.show();
15010				vars.toolbar.show();
15011			}
15012
15013			var length = recognizingItems.length;
15014			if (needRecognition) {
15015				iL.showLoader();
15016
15017				$.each(recognizingItems, function(key, val) {
15018					var resultFnc = function(result) {
15019							var key = -1,
15020								filter = iL.items.filter(function(e, i, arr) {
15021									if (e.URL == result.url)
15022										key = i;
15023
15024									return e.URL == result.url;
15025								}),
15026								self = iL.items[key];
15027
15028							if (result)
15029								$.extend(true, self, {
15030									URL: result.source,
15031									type: result.type,
15032									recognized: true,
15033									options: {
15034										html5video: result.html5video,
15035										width: (result.type == "image") ? 0 : (result.width || self.width),
15036										height: (result.type == "image") ? 0 : (result.height || self.height),
15037										thumbnail: self.options.thumbnail || result.thumbnail
15038									}
15039								});
15040
15041							length--;
15042
15043							if (length == 0) {
15044								iL.hideLoader();
15045
15046								vars.dontGenerateThumbs = false;
15047								iL.generateThumbnails();
15048
15049								if (opts.show.effect)
15050									setTimeout(function() {
15051										iL.generateBoxes();
15052									}, opts.show.speed);
15053								else
15054									iL.generateBoxes();
15055							}
15056						};
15057
15058					iL.ogpRecognition(this, resultFnc);
15059				});
15060			}
15061			else {
15062				if (opts.show.effect)
15063					setTimeout(function() {
15064						iL.generateBoxes();
15065					}, opts.show.speed);
15066				else
15067					iL.generateBoxes();
15068			}
15069
15070			iL.createUI();
15071
15072			window.iLightBox = {
15073				close: function() {
15074					iL.closeAction();
15075				},
15076				fullscreen: function() {
15077					iL.fullScreenAction();
15078				},
15079				moveNext: function() {
15080					iL.moveTo('next');
15081				},
15082				movePrev: function() {
15083					iL.moveTo('prev');
15084				},
15085				goTo: function(index) {
15086					iL.goTo(index);
15087				},
15088				refresh: function() {
15089					iL.refresh();
15090				},
15091				reposition: function() {
15092					(arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto();
15093				},
15094				setOption: function(options) {
15095					iL.setOption(options);
15096				},
15097				destroy: function() {
15098					iL.closeAction();
15099					iL.dispatchItemsEvents();
15100				}
15101			};
15102
15103			if (opts.linkId) {
15104				vars.hashLock = true;
15105				window.location.hash = opts.linkId + '/' + vars.current;
15106				setTimeout(function() {
15107					vars.hashLock = false;
15108				}, 55);
15109			}
15110
15111			if (!opts.slideshow.startPaused) {
15112				iL.resume();
15113				vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause');
15114			}
15115
15116			//Trigger the onOpen callback
15117			if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL);
15118		},
15119
15120		loadContent: function(obj, opt, speed) {
15121			var iL = this,
15122				holder, item;
15123
15124			iL.createUI();
15125
15126			obj.speed = speed || iL.options.effects.loadedFadeSpeed;
15127
15128			if (opt == 'current') {
15129				if (!obj.options.mousewheel) iL.vars.lockWheel = true;
15130				else iL.vars.lockWheel = false;
15131
15132				if (!obj.options.swipe) iL.vars.lockSwipe = true;
15133				else iL.vars.lockSwipe = false;
15134			}
15135
15136			switch (opt) {
15137				case 'current':
15138					holder = iL.vars.holder, item = iL.vars.current;
15139					break;
15140				case 'next':
15141					holder = iL.vars.nextPhoto, item = iL.vars.next;
15142					break;
15143				case 'prev':
15144					holder = iL.vars.prevPhoto, item = iL.vars.prev;
15145					break;
15146			}
15147
15148			holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin);
15149			$('div.ilightbox-inner-toolbar', holder).remove();
15150
15151			if (obj.title || iL.options.innerToolbar) {
15152				var innerToolbar = iL.vars.innerToolbar.clone();
15153				if (obj.title && iL.options.show.title) {
15154					var title = iL.vars.title.clone();
15155					title.empty().html(obj.title);
15156					innerToolbar.append(title);
15157				}
15158				if (iL.options.innerToolbar) {
15159					innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar);
15160				}
15161				holder.prepend(innerToolbar);
15162			}
15163
15164			//console.warn('loadContent', arguments);
15165
15166			iL.loadSwitcher(obj, holder, item, opt);
15167		},
15168
15169		loadSwitcher: function(obj, holder, item, opt) {
15170			var iL = this,
15171				opts = iL.options,
15172				api = {
15173					element: holder,
15174					position: item
15175				};
15176
15177			switch (obj.type) {
15178				case 'image':
15179					//Trigger the onBeforeLoad callback
15180					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15181					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15182
15183					iL.loadImage(obj.URL, function(img) {
15184						//Trigger the onAfterLoad callback
15185						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15186						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15187
15188						var width = (img) ? img.width : 400,
15189							height = (img) ? img.height : 200;
15190
15191						holder.data({
15192							naturalWidth: width,
15193							naturalHeight: height
15194						});
15195
15196						$('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>');
15197
15198						//Trigger the onRender callback
15199						if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15200						if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15201
15202						iL.configureHolder(obj, opt, holder);
15203					});
15204
15205					break;
15206
15207				case 'video':
15208					holder.data({
15209						naturalWidth: obj.options.width,
15210						naturalHeight: obj.options.height
15211					});
15212
15213					if (opt === 'current') {
15214						iL.addContent(holder, obj);
15215
15216						//Trigger the onRender callback
15217						if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15218						if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15219					} else {
15220						$('div.ilightbox-container', holder).empty();
15221					}
15222
15223					iL.configureHolder(obj, opt, holder);
15224
15225					break;
15226
15227				case 'iframe':
15228					//iL.showLoader();
15229					holder.data({
15230						naturalWidth: obj.options.width,
15231						naturalHeight: obj.options.height
15232					});
15233
15234					iL.configureHolder(obj, opt, holder);
15235
15236					if (opt === 'current') {
15237						var el = iL.addContent(holder, obj);
15238
15239						//Trigger the onRender callback
15240						if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15241						if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15242
15243						//Trigger the onBeforeLoad callback
15244						if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15245						if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15246
15247						el.bind('load', function() {
15248							//Trigger the onAfterLoad callback
15249							if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15250							if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15251
15252							//iL.hideLoader();
15253							el.unbind('load');
15254						});
15255					} else {
15256						$('div.ilightbox-container', holder).empty();
15257					}
15258
15259					break;
15260
15261				case 'inline':
15262					var el = $(obj.URL),
15263						content = iL.addContent(holder, obj),
15264						images = findImageInElement(holder);
15265
15266					holder.data({
15267						naturalWidth: (iL.items[item].options.width || el.outerWidth()),
15268						naturalHeight: (iL.items[item].options.height || el.outerHeight())
15269					});
15270					content.children().eq(0).show();
15271
15272					//Trigger the onRender callback
15273					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15274					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15275
15276					//Trigger the onBeforeLoad callback
15277					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15278					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15279
15280					iL.loadImage(images, function() {
15281						//Trigger the onAfterLoad callback
15282						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15283						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15284
15285						iL.configureHolder(obj, opt, holder);
15286					});
15287
15288					break;
15289
15290				case 'flash':
15291					var el = iL.addContent(holder, obj);
15292
15293					holder.data({
15294						naturalWidth: (iL.items[item].options.width || el.outerWidth()),
15295						naturalHeight: (iL.items[item].options.height || el.outerHeight())
15296					});
15297
15298					//Trigger the onRender callback
15299					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15300					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15301
15302					iL.configureHolder(obj, opt, holder);
15303
15304					break;
15305
15306				case 'ajax':
15307					var ajax = obj.options.ajax || {};
15308					//Trigger the onBeforeLoad callback
15309					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15310					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15311
15312					iL.showLoader();
15313					$.ajax({
15314						url: obj.URL || opts.ajaxSetup.url,
15315						data: ajax.data || null,
15316						dataType: ajax.dataType || "html",
15317						type: ajax.type || opts.ajaxSetup.type,
15318						cache: ajax.cache || opts.ajaxSetup.cache,
15319						crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain,
15320						global: ajax.global || opts.ajaxSetup.global,
15321						ifModified: ajax.ifModified || opts.ajaxSetup.ifModified,
15322						username: ajax.username || opts.ajaxSetup.username,
15323						password: ajax.password || opts.ajaxSetup.password,
15324						beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend,
15325						complete: ajax.complete || opts.ajaxSetup.complete,
15326						success: function(data, textStatus, jqXHR) {
15327							iL.hideLoader();
15328
15329							var el = $(data),
15330								container = $('div.ilightbox-container', holder),
15331								elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')),
15332								elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')),
15333								css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? {
15334									'overflow': 'hidden'
15335								} : {};
15336
15337							container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el));
15338							holder.show().data({
15339								naturalWidth: (elWidth || container.outerWidth()),
15340								naturalHeight: (elHeight || container.outerHeight())
15341							}).hide();
15342
15343							//Trigger the onRender callback
15344							if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15345							if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15346
15347							var images = findImageInElement(holder);
15348							iL.loadImage(images, function() {
15349								//Trigger the onAfterLoad callback
15350								if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15351								if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15352
15353								iL.configureHolder(obj, opt, holder);
15354							});
15355
15356							opts.ajaxSetup.success(data, textStatus, jqXHR);
15357							if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR);
15358						},
15359						error: function(jqXHR, textStatus, errorThrown) {
15360							//Trigger the onAfterLoad callback
15361							if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15362							if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15363
15364							iL.hideLoader();
15365							$('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>');
15366							iL.configureHolder(obj, opt, holder);
15367
15368							opts.ajaxSetup.error(jqXHR, textStatus, errorThrown);
15369							if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown);
15370						}
15371					});
15372
15373					break;
15374
15375				case 'html':
15376					var object = obj.URL,
15377						el
15378					container = $('div.ilightbox-container', holder);
15379
15380					if (object[0].nodeName) el = object.clone();
15381					else {
15382						var dom = $(object);
15383						if (dom.selector) el = $('<div>' + dom + '</div>');
15384						else el = dom;
15385					}
15386
15387					var elWidth = iL.items[item].options.width || parseInt(el.attr('width')),
15388						elHeight = iL.items[item].options.height || parseInt(el.attr('height'));
15389
15390					iL.addContent(holder, obj);
15391
15392					el.appendTo(document.documentElement).hide();
15393
15394					//Trigger the onRender callback
15395					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15396					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15397
15398					var images = findImageInElement(holder);
15399
15400					//Trigger the onBeforeLoad callback
15401					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15402					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15403
15404					iL.loadImage(images, function() {
15405						//Trigger the onAfterLoad callback
15406						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15407						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15408
15409						holder.show().data({
15410							naturalWidth: (elWidth || container.outerWidth()),
15411							naturalHeight: (elHeight || container.outerHeight())
15412						}).hide();
15413						el.remove();
15414
15415						iL.configureHolder(obj, opt, holder);
15416					});
15417
15418					break;
15419			}
15420		},
15421
15422		configureHolder: function(obj, opt, holder) {
15423			var iL = this,
15424				vars = iL.vars,
15425				opts = iL.options;
15426
15427			if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev');
15428
15429			if (opt == "current")
15430				var item = vars.current;
15431			else if (opt == "next")
15432				var opacity = opts.styles.nextOpacity,
15433					item = vars.next;
15434			else
15435				var opacity = opts.styles.prevOpacity,
15436					item = vars.prev;
15437
15438			var api = {
15439				element: holder,
15440				position: item
15441			};
15442
15443			iL.items[item].options.width = iL.items[item].options.width || 0,
15444			iL.items[item].options.height = iL.items[item].options.height || 0;
15445
15446			if (opt == "current") {
15447				if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() {
15448					holder.css(transform, '');
15449					if (obj.caption) {
15450						iL.setCaption(obj, holder);
15451						var caption = $('div.ilightbox-caption', holder),
15452							percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100);
15453						if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
15453Speed);
15454					}
15455
15456					var social = obj.options.social;
15457					if (social) {
15458						iL.setSocial(social, obj.URL, holder);
15459						if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed);
15460					}
15461
15462					//Generate thumbnails
15463					iL.generateThumbnails();
15464
15465					//Trigger the onShow callback
15466					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
15467					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
15468				});
15469				else {
15470					holder.show();
15471
15472					//Generate thumbnails
15473					iL.generateThumbnails();
15474
15475					//Trigger the onShow callback
15476					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
15477					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
15478				}
15479			} else {
15480				if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() {
15481					if (opt == "next") vars.nextLock = false;
15482					else vars.prevLock = false;
15483
15484					//Generate thumbnails
15485					iL.generateThumbnails();
15486
15487					//Trigger the onShow callback
15488					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
15489					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
15490				});
15491				else {
15492					holder.css({
15493						opacity: opacity
15494					}).show();
15495					if (opt == "next") vars.nextLock = false;
15496					else vars.prevLock = false;
15497
15498					//Generate thumbnails
15499					iL.generateThumbnails();
15500
15501					//Trigger the onShow callback
15502					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
15503					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
15504				}
15505			}
15506
15507			setTimeout(function() {
15508				iL.repositionPhoto();
15509			}, 0);
15510		},
15511
15512		generateBoxes: function() {
15513			var iL = this,
15514				vars = iL.vars,
15515				opts = iL.options;
15516
15517			if (opts.infinite && vars.total >= 3) {
15518				if (vars.current == vars.total - 1) vars.next = 0;
15519				if (vars.current == 0) vars.prev = vars.total - 1;
15520			} else opts.infinite = false;
15521
15522			//UNCODE addition
15523			if ( typeof iL.items[vars.current] == 'undefined' )
15524				vars.current = 0;
15525
15526			iL.loadContent(iL.items[vars.current], 'current', opts.show.speed);
15527
15528			if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed);
15529			if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed);
15530		},
15531
15532		generateThumbnails: function() {
15533			var iL = this,
15534				vars = iL.vars,
15535				opts = iL.options,
15536				timeOut = null;
15537
15538			if (vars.thumbs && !iL.vars.dontGenerateThumbs) {
15539				var thumbnails = vars.thumbnails,
15540					container = $('div.ilightbox-thumbnails-container', thumbnails),
15541					grid = $('div.ilightbox-thumbnails-grid', container),
15542					i = 0;
15543
15544				grid.removeAttr('style').empty();
15545
15546				$.each(iL.items, function(key, val) {
15547					var isActive = (vars.current == key) ? 'ilightbox-active' : '',
15548						opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity,
15549						thumb = val.options.thumbnail,
15550						thumbnail = $('<div class="ilightbox-thumbnail"></div>'),
15551						icon = $('<div class="ilightbox-thumbnail-icon"></div>');
15552
15553					thumbnail.css({
15554						opacity: 0
15555					}).addClass(isActive);
15556
15557					if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') {
15558						icon.addClass('ilightbox-thumbnail-video');
15559						thumbnail.append(icon);
15560					} else if (val.options.icon) {
15561						icon.addClass('ilightbox-thumbnail-' + val.options.icon);
15562						thumbnail.append(icon);
15563					}
15564
15565					if (thumb) iL.loadImage(thumb, function(img) {
15566						i++;
15567						if (img) thumbnail.data({
15568							naturalWidth: img.width,
15569							naturalHeight: img.height
15570						}).append('<img src="' + thumb + '" border="0" />');
15571						else thumbnail.data({
15572							naturalWidth: opts.thumbnails.maxWidth,
15573							naturalHeight: opts.thumbnails.maxHeight
15574						});
15575
15576						clearTimeout(timeOut);
15577						timeOut = setTimeout(function() {
15578							iL.positionThumbnails(thumbnails, container, grid);
15579						}, 20);
15580						setTimeout(function() {
15581							thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity);
15582						}, i * 20);
15583					});
15584
15585					grid.append(thumbnail);
15586				});
15587				iL.vars.dontGenerateThumbs = true;
15588			}
15589		},
15590
15591		positionThumbnails: function(thumbnails, container, grid) {
15592			var iL = this,
15593				vars = iL.vars,
15594				opts = iL.options,
15595				viewport = getViewport(),
15596				path = opts.path.toLowerCase();
15597
15598			if (!thumbnails) thumbnails = vars.thumbnails;
15599			if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails);
15600			if (!grid) grid = $('div.ilightbox-thumbnails-grid', container);
15601
15602			var thumbs = $('.ilightbox-thumbnail', grid),
15603				widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX,
15604				heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY,
15605				gridWidth = (path == 'horizontal') ? 0 : widthAvail,
15606				gridHeight = (path == 'horizontal') ? heightAvail : 0,
15607				active = $('.ilightbox-active', grid),
15608				gridCss = {},
15609				css = {};
15610
15611			if (arguments.length < 3) {
15612				thumbs.css({
15613					opacity: opts.thumbnails.normalOpacity
15614				});
15615				active.css({
15616					opacity: opts.thumbnails.activeOpacity
15617				});
15618			}
15619
15620			thumbs.each(function(i) {
15621				var t = $(this),
15622					data = t.data(),
15623					width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth;
15624				height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0;
15625				dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true);
15626
15627				t.css({
15628					width: dims.width,
15629					height: dims.height
15630				});
15631				if (path == 'horizontal') t.css({
15632					'float': 'left'
15633				});
15634
15635				(path == 'horizontal') ? (
15636					gridWidth += t.outerWidth()
15637				) : (
15638					gridHeight += t.outerHeight()
15639				);
15640			});
15641
15642			gridCss = {
15643				width: gridWidth,
15644				height: gridHeight
15645			};
15646
15647			grid.css(gridCss);
15648
15649			gridCss = {};
15650
15651			var gridOffset = grid.offset(),
15652				activeOffset = (active.length) ? active.offset() : {
15653					top: parseInt(heightAvail / 2),
15654					left: parseInt(widthAvail / 2)
15655				};
15656
15657			gridOffset.top = (gridOffset.top - $doc.scrollTop()),
15658				gridOffset.left = (gridOffset.left - $doc.scrollLeft()),
15659				activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()),
15660				activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft());
15661
15662			(path == 'horizontal') ? (
15663				gridCss.top = 0,
15664				gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2))
15665			) : (
15666				gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))),
15667				gridCss.left = 0
15668			);
15669
15670			if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc');
15671			else grid.css(gridCss);
15672		},
15673
15674		loadImage: function(image, callback) {
15675			if (!$.isArray(image)) image = [image];
15676
15677			var iL = this,
15678				length = image.length;
15679
15680			if (length > 0) {
15681				iL.showLoader();
15682				$.each(image, function(index, value) {
15683					var img = new Image();
15684					img.onload = function() {
15685						length -= 1;
15686						if (length == 0) {
15687							iL.hideLoader();
15688							callback(img);
15689						}
15690					};
15691					img.onerror = img.onabort = function() {
15692						length -= 1;
15693						if (length == 0) {
15694							iL.hideLoader();
15695							callback(false);
15696						}
15697					};
15698					img.src = image[index];
15699				});
15700			} else callback(false);
15701		},
15702
15703		patchItemsEvents: function() {
15704			var iL = this,
15705				vars = iL.vars,
15706				clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL",
15707				vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL";
15708
15709			if (iL.context && iL.selector) {
15710				var $items = $(iL.selector, iL.context);
15711
15712				$(iL.context).on(clickEvent, iL.selector, function() {
15713					var $this = $(this),
15714						//UNCODE addition
15715						key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this);
15716					if (UNCODE.isMobile) {
15717						var isCarousel = $this.closest('.owl-carousel');
15718						if (isCarousel.length) {
15719							if (isCarousel.hasClass('owl-translating')) return false;
15720						}
15721					}
15722
15723					vars.current = key;
15724					vars.next = iL.items[key + 1] ? key + 1 : null;
15725					vars.prev = iL.items[key - 1] ? key - 1 : null;
15726
15727					//UNCODE addition
15728					if ( vars.BODY.hasClass('fp-slide-scrolling') )
15729						return false;
15730
15731					iL.addContents();
15732					iL.patchEvents();
15733
15734					return false;
15735				}).on(vEvent, iL.selector, function() {
15736					return false;
15737				});
15738			} else
15739				$.each(iL.itemsObject, function(key, val) {
15740					val.on(clickEvent, function() {
15741						vars.current = key;
15742						vars.next = iL.items[key + 1] ? key + 1 : null;
15743						vars.prev = iL.items[key - 1] ? key - 1 : null;
15744
15745						iL.addContents();
15746						iL.patchEvents();
15747
15748						return false;
15749					}).on(vEvent, function() {
15750						return false;
15751					});
15752				});
15753		},
15754
15755		dispatchItemsEvents: function() {
15756			var iL = this,
15757				vars = iL.vars,
15758				opts = iL.options;
15759
15760			if (iL.context && iL.selector)
15761				$(iL.context).off('.iL', iL.selector);
15762			else
15763				$.each(iL.itemsObject, function(key, val) {
15764					val.off('.iL');
15765				});
15766		},
15767
15768		refresh: function() {
15769			var iL = this;
15770
15771			iL.dispatchItemsEvents();
15772			iL.attachItems();
15773			iL.normalizeItems();
15774			iL.patchItemsEvents();
15775		},
15776
15777		patchEvents: function() {
15778			var iL = this,
15779				vars = iL.vars,
15780				opts = iL.options,
15781				path = opts.path.toLowerCase(),
15782				holders = $('.ilightbox-holder'),
15783				fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox',
15784				durationThreshold = 1000,
15785				horizontalDistanceThreshold =
15786				verticalDistanceThreshold = 100,
15787				buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild];
15788
15789			$win.bind('resize.iLightBox', function() {
15790				var viewport = getViewport();
15791
15792				if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth;
15793				vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile');
15794
15795				iL.repositionPhoto(null);
15796				if (supportTouch) {
15797					clearTimeout(vars.setTime);
15798					vars.setTime = setTimeout(function() {
15799						var scrollTop = getScrollXY().y;
15800						window.scrollTo(0, scrollTop - 30);
15801						window.scrollTo(0, scrollTop + 30);
15802						window.scrollTo(0, scrollTop);
15803					}, 2000);
15804				}
15805				if (vars.thumbs) iL.positionThumbnails();
15806			}).bind('keydown.iLightBox', function(event) {
15807				if (opts.controls.keyboard) {
15808					switch (event.keyCode) {
15809						case 13:
15810							if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction();
15811							break;
15812						case 27:
15813							if (opts.keyboard.esc) iL.closeAction();
15814							break;
15815						case 37:
15816							if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev');
15817							break;
15818						case 38:
15819							if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev');
15820							break;
15821						case 39:
15822							if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next');
15823							break;
15824						case 40:
15825							if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next');
15826							break;
15827					}
15828				}
15829			});
15830
15831			if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() {
15832				iL.doFullscreen();
15833			});
15834
15835			var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) {
15836					return arr.lastIndexOf(e) === i;
15837				}),
15838				holderEvents = "";
15839
15840			$.each(holderEventsArr, function(key, val) {
15841				if (key != 0) holderEvents += ' ';
15842				holderEvents += val;
15843			});
15844
15845			$doc.on(clickEvent, '.ilightbox-overlay', function() {
15846				if (opts.overlay.blur) iL.closeAction();
15847			}).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() {
15848				iL.moveTo('next');
15849			}).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() {
15850				iL.moveTo('prev');
15851			}).on(clickEvent, '.ilightbox-thumbnail', function() {
15852				var t = $(this),
15853					thumbs = $('.ilightbox-thumbnail', vars.thumbnails),
15854					index = thumbs.index(t);
15855
15856				if (index != vars.current) iL.goTo(index);
15857			}).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) {
15858				var caption = $('div.ilightbox-caption', vars.holder),
15859					social = $('div.ilightbox-social', vars.holder),
15860					fadeSpeed = opts.effects.fadeSpeed;
15861
15862				if (vars.nextLock || vars.prevLock) {
15863					if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed);
15864					else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed);
15865
15866					if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed);
15867					else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed);
15868				} else {
15869					if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed);
15870					else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed);
15871
15872					if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed);
15873					else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed);
15874				}
15875			}).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) {
15876				if (e.type == 'mouseenter') vars.lockWheel = true;
15877				else vars.lockWheel = false;
15878			}).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() {
15879				var t = $(this);
15880
15881				if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction();
15882				else if (t.hasClass('ilightbox-play')) {
15883					iL.resume();
15884					t.addClass('ilightbox-pause').removeClass('ilightbox-play');
15885				} else if (t.hasClass('ilightbox-pause')) {
15886					iL.pause();
15887					t.addClass('ilightbox-play').removeClass('ilightbox-pause');
15888				} else iL.closeAction();
15889			}).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) {
15890				// prevent scrolling
15891				e.preventDefault();
15892			});
15893
15894			function mouseMoveHandler(e) {
15895				if (!vars.isMobile) {
15896					if (!vars.mouseID) {
15897						vars.hideableElements.show();
15898					}
15899
15900					vars.mouseID = clearTimeout(vars.mouseID);
15901
15902					if (buttonsArray.indexOf(e.target) === -1)
15903						vars.mouseID = setTimeout(function() {
15904							vars.hideableElements.hide();
15905							vars.mouseID = clearTimeout(vars.mouseID);
15906						}, 3000);
15907				}
15908			}
15909
15910			if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler);
15911
15912			if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) {
15913				if (e.type == 'mouseenter' && vars.cycleID) iL.pause();
15914				else if (e.type == 'mouseleave' && vars.isPaused) iL.resume();
15915			});
15916
15917			var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'),
15918				delay = false;
15919
15920			if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) {
15921				event.preventDefault();
15922				if (delay) return;
15923				delay = true;
15924				if (!vars.lockWheel) {
15925					event.preventDefault();
15926					if (delta < 0) {
15927						iL.moveTo('next');
15928					} else if (delta > 0) {
15929						iL.moveTo('prev');
15930					}
15931				}
15932				setTimeout(function(){
15933					delay = false;
15934				}, 2000);
15935			});
15936
15937			if (opts.controls.swipe) holders.on(touchStartEvent, function(event) {
15938				if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return;
15939
15940				vars.BODY.addClass('ilightbox-closedhand');
15941
15942				var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event,
15943					scrollTop = $doc.scrollTop(),
15944					scrollLeft = $doc.scrollLeft(),
15945					offsets = [
15946						holders.eq(0).offset(),
15947						holders.eq(1).offset(),
15948						holders.eq(2).offset()
15949					],
15950					offSet = [{
15951						top: offsets[0].top - scrollTop,
15952						left: offsets[0].left - scrollLeft
15953					}, {
15954						top: offsets[1].top - scrollTop,
15955						left: offsets[1].left - scrollLeft
15956					}, {
15957						top: offsets[2].top - scrollTop,
15958						left: offsets[2].left - scrollLeft
15959					}],
15960					start = {
15961						time: (new Date()).getTime(),
15962						coords: [data.pageX - scrollLeft, data.pageY - scrollTop]
15963					},
15964					stop;
15965
15966				function moveEachHandler(i) {
15967					var t = $(this),
15968						offset = offSet[i],
15969						scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])];
15970
15971					t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px';
15972				}
15973
15974				function moveHandler(event) {
15975
15976					if (!start) return;
15977
15978					var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event;
15979
15980					stop = {
15981						time: (new Date()).getTime(),
15982						coords: [data.pageX - scrollLeft, data.pageY - scrollTop]
15983					};
15984
15985					holders.each(moveEachHandler);
15986
15987					// prevent scrolling
15988					event.preventDefault();
15989				}
15990
15991				function repositionHolders() {
15992					holders.each(function() {
15993						var t = $(this),
15994							offset = t.data('offset') || {
15995								top: t.offset().top - scrollTop,
15996								left: t.offset().left - scrollLeft
15997							},
15998							top = offset.top,
15999							left = offset.left;
16000
16001						t.css(transform, gpuAcceleration).stop().animate({
16002							top: top,
16003							left: left
16004						}, 500, 'easeOutCirc', function() {
16005							t.css(transform, '');
16006						});
16007					});
16008				}
16009
16010				holders.bind(touchMoveEvent, moveHandler);
16011				$doc.one(touchStopEvent, function(event) {
16012					holders.unbind(touchMoveEvent, moveHandler);
16013
16014					vars.BODY.removeClass('ilightbox-closedhand');
16015
16016					if (start && stop) {
16017						if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) {
16018							if (start.coords[0] > stop.coords[0]) {
16019								if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders();
16020								else {
16021									vars.isSwipe = true;
16022									iL.moveTo('next');
16023								}
16024							} else {
16025								if (vars.current == 0 && !opts.infinite) repositionHolders();
16026								else {
16027									vars.isSwipe = true;
16028									iL.moveTo('prev');
16029								}
16030							}
16031						} else if (path == "vertical" && stop.time - start.time < durationThreshold && abs(start.coords[1] - stop.coords[1]) > horizontalDistanceThreshold && abs(start.coords[0] - stop.coords[0]) < verticalDistanceThreshold) {
16032							if (start.coords[1] > stop.coords[1]) {
16033								if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders();
16034								else {
16035									vars.isSwipe = true;
16036									iL.moveTo('next');
16037								}
16038							} else {
16039								if (vars.current == 0 && !opts.infinite) repositionHolders();
16040								else {
16041									vars.isSwipe = true;
16042									iL.moveTo('prev');
16043								}
16044							}
16045						} else repositionHolders();
16046					}
16047					start = stop = undefined;
16048				});
16049			});
16050
16051		},
16052
16053		goTo: function(index) {
16054			var iL = this,
16055				vars = iL.vars,
16056				opts = iL.options,
16057				diff = (index - vars.current);
16058
16059			if (opts.infinite) {
16060				if (index == vars.total - 1 && vars.current == 0) diff = -1;
16061				if (vars.current == vars.total - 1 && index == 0) diff = 1;
16062			}
16063
16064			if (diff == 1) iL.moveTo('next');
16065			else if (diff == -1) iL.moveTo('prev');
16066			else {
16067
16068				if (vars.nextLock || vars.prevLock) return false;
16069
16070				//Trigger the onBeforeChange callback
16071				if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui);
16072
16073				if (opts.linkId) {
16074					vars.hashLock = true;
16075					window.location.hash = opts.linkId + '/' + index;
16076				}
16077
16078				if (iL.items[index]) {
16079					if (!iL.items[index].options.mousewheel) vars.lockWheel = true;
16080					else iL.vars.lockWheel = false;
16081
16082					if (!iL.items[index].options.swipe) vars.lockSwipe = true;
16083					else vars.lockSwipe = false;
16084				}
16085
16086				$.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) {
16087					val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed);
16088				});
16089
16090				vars.current = index;
16091				vars.next = index + 1;
16092				vars.prev = index - 1;
16093
16094				iL.createUI();
16095
16096				setTimeout(function() {
16097					iL.generateBoxes();
16098				}, opts.effects.loadedFadeSpeed + 50);
16099
16100				$('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active');
16101				iL.positionThumbnails();
16102
16103				if (opts.linkId) setTimeout(function() {
16104					vars.hashLock = false;
16105				}, 55);
16106
16107				// Configure arrow buttons
16108				if (!opts.infinite) {
16109					vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
16110
16111					if (vars.current == 0) {
16112						vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
16113					}
16114					if (vars.current >= vars.total - 1) {
16115						vars.nextButton.add(vars.innerNextButton).addClass('disabled');
16116					}
16117				}
16118
16119				// Reset next cycle timeout
16120				iL.resetCycle();
16121
16122				//Trigger the onAfterChange callback
16123				if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui);
16124			}
16125		},
16126
16127		moveTo: function(side) {
16128			var iL = this,
16129				vars = iL.vars,
16130				opts = iL.options,
16131				path = opts.path.toLowerCase(),
16132				viewport = getViewport(),
16133				switchSpeed = opts.effects.switchSpeed;
16134
16135			if (vars.nextLock || vars.prevLock) return false;
16136			else {
16137
16138				var item = (side == "next") ? vars.next : vars.prev;
16139
16140				if (opts.linkId) {
16141					vars.hashLock = true;
16142					window.location.hash = opts.linkId + '/' + item;
16143				}
16144
16145				if (side == "next") {
16146					if (!iL.items[item]) return false;
16147					var firstHolder = vars.nextPhoto,
16148						secondHolder = vars.holder,
16149						lastHolder = vars.prevPhoto,
16150						firstClass = 'ilightbox-prev',
16151						secondClass = 'ilightbox-next';
16152				} else if (side == "prev") {
16153					if (!iL.items[item]) return false;
16154					var firstHolder = vars.prevPhoto,
16155						secondHolder = vars.holder,
16156						lastHolder = vars.nextPhoto,
16157						firstClass = 'ilightbox-next',
16158						secondClass = 'ilightbox-prev';
16159				}
16160
16161				//Trigger the onBeforeChange callback
16162				if (typeof opts.callback.onBeforeChange == 'function')
16163					opts.callback.onBeforeChange.call(iL, iL.ui);
16164
16165				(side == "next") ? vars.nextLock = true: vars.prevLock = true;
16166
16167				var captionFirst = $('div.ilightbox-caption', secondHolder),
16168					socialFirst = $('div.ilightbox-social', secondHolder);
16169
16170				if (captionFirst.length)
16171					captionFirst.stop().fadeOut(switchSpeed, function() {
16172						$(this).remove();
16173					});
16174				if (socialFirst.length)
16175					socialFirst.stop().fadeOut(switchSpeed, function() {
16176						$(this).remove();
16177					});
16178
16179				if (iL.items[item].caption) {
16180					iL.setCaption(iL.items[item], firstHolder);
16181					var caption = $('div.ilightbox-caption', firstHolder),
16182						percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100);
16183					if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed);
16184				}
16185
16186				var social = iL.items[item].options.social;
16187				if (social) {
16188					iL.setSocial(social, iL.items[item].URL, firstHolder);
16189					if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed);
16190				}
16191
16192				$.each([firstHolder, secondHolder, lastHolder], function(key, val) {
16193					val.removeClass('ilightbox-next ilightbox-prev');
16194				});
16195
16196				var firstOffset = firstHolder.data('offset'),
16197					winW = (viewport.width - (opts.styles.pageOffsetX)),
16198					winH = (viewport.height - (opts.styles.pageOffsetY)),
16199					width = firstOffset.newDims.width,
16200					height = firstOffset.newDims.height,
16201					thumbsOffset = firstOffset.thumbsOffset,
16202					diff = firstOffset.diff,
16203					top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)),
16204					left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2));
16205
16206				var secondOffset = secondHolder.data('offset'),
16207					object = secondOffset.object;
16208
16209				/*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) {
16210					var objRatio = width / height;
16211					height = height - vars.captionHeight;
16212					width = height * objRatio;
16213					top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top,
16214					left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2));
16215				}*/
16216
16217				firstHolder.show().css(transform, gpuAcceleration).animate({
16218					top: top,
16219					left: left,
16220					opacity: 1
16221				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
16222					firstHolder.css(transform, '');
16223				});
16224
16225				$('div.ilightbox-container', firstHolder).animate({
16226					width: width,
16227					height: height
16228				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc');
16229
16230				diff = secondOffset.diff;
16231
16232				width = secondOffset.newDims.width,
16233					height = secondOffset.newDims.height;
16234
16235				width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']),
16236					height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']),
16237					top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2));
16238
16239				if (side == 'prev')
16240					left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2));
16241				else {
16242					top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)),
16243					left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2));
16244				}
16245
16246				/*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) {
16247					var objRatio = width / height;
16248					height = height - vars.captionHeight;
16249					width = height * objRatio;
16250					top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top;
16251				}*/
16252
16253				$('div.ilightbox-container', secondHolder).animate({
16254					width: width,
16255					height: height
16256				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc');
16257
16258				secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({
16259					top: top,
16260					left: left,
16261					opacity: opts.styles.prevOpacity,
16262				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
16263					secondHolder.css(transform, '');
16264
16265					$('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active');
16266					iL.positionThumbnails();
16267
16268					if (iL.items[item]) {
16269						if (!iL.items[item].options.mousewheel) vars.lockWheel = true;
16270						else vars.lockWheel = false;
16271
16272						if (!iL.items[item].options.swipe) vars.lockSwipe = true;
16273						else vars.lockSwipe = false;
16274					}
16275
16276					vars.isSwipe = false;
16277
16278					// Remove iframe & video from previous slide
16279					if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) {
16280						$('div.ilightbox-container', secondHolder).empty();
16281					}
16282
16283					if (side == "next") {
16284						vars.nextPhoto = lastHolder,
16285							vars.prevPhoto = secondHolder,
16286							vars.holder = firstHolder;
16287
16288						vars.nextPhoto.hide();
16289
16290						vars.next = vars.next + 1,
16291							vars.prev = vars.current,
16292							vars.current = vars.current + 1;
16293
16294						if (opts.infinite) {
16295							if (vars.current > vars.total - 1) vars.current = 0;
16296							if (vars.current == vars.total - 1) vars.next = 0;
16297							if (vars.current == 0) vars.prev = vars.total - 1;
16298						}
16299
16300						iL.createUI();
16301
16302						if (!iL.items[vars.next])
16303							vars.nextLock = false;
16304						else
16305							iL.loadContent(iL.items[vars.next], 'next');
16306					} else {
16307						vars.prevPhoto = lastHolder;
16308						vars.nextPhoto = secondHolder;
16309						vars.holder = firstHolder;
16310
16311						vars.prevPhoto.hide();
16312
16313						vars.next = vars.current;
16314						vars.current = vars.prev;
16315						vars.prev = vars.current - 1;
16316
16317						if (opts.infinite) {
16318							if (vars.current == vars.total - 1) vars.next = 0;
16319							if (vars.current == 0) vars.prev = vars.total - 1;
16320						}
16321
16322						iL.createUI();
16323
16324						if (!iL.items[vars.prev])
16325							vars.prevLock = false;
16326						else
16327							iL.loadContent(iL.items[vars.prev], 'prev');
16328					}
16329
16330					// Add iframe & video content for current slide
16331					if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) {
16332						iL.loadContent(iL.items[vars.current], 'current');
16333					}
16334
16335					if (opts.linkId) setTimeout(function() {
16336						vars.hashLock = false;
16337					}, 55);
16338
16339					// Configure arrow buttons
16340					if (!opts.infinite) {
16341						vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
16342
16343						if (vars.current == 0)
16344							vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
16345						if (vars.current >= vars.total - 1)
16346							vars.nextButton.add(vars.innerNextButton).addClass('disabled');
16347					}
16348
16349					iL.repositionPhoto();
16350
16351					// Reset next cycle timeout
16352					iL.resetCycle();
16353
16354					//Trigger the onAfterChange callback
16355					if (typeof opts.callback.onAfterChange == 'function')
16356						opts.callback.onAfterChange.call(iL, iL.ui);
16357				});
16358
16359				top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)),
16360					left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left');
16361
16362				lastHolder.css(transform, gpuAcceleration).animate({
16363					top: top,
16364					left: left,
16365					opacity: opts.styles.nextOpacity
16366				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
16367					lastHolder.css(transform, '');
16368				}).addClass(secondClass);
16369			}
16370		},
16371
16372		setCaption: function(obj, target) {
16373			var iL = this,
16374				caption = $('<div class="ilightbox-caption"></div>');
16375
16376			if (obj.caption) {
16377				caption.html(obj.caption);
16378				$('div.ilightbox-container', target).append(caption);
16379			}
16380		},
16381
16382		normalizeSocial: function(obj, url) {
16383			var iL = this,
16384				vars = iL.vars,
16385				opts = iL.options,
16386				baseURL = window.location.href;
16387
16388			$.each(obj, function(key, value) {
16389				if (!value)
16390					return true;
16391
16392				var item = key.toLowerCase(),
16393					source, text;
16394
16395				switch (item) {
16396					case 'facebook':
16397						source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}",
16398							text = "Share on Facebook";
16399						break;
16400					case 'twitter':
16401						source = "http://twitter.com/home?status={URL}",
16402							text = "Share on Twitter";
16403						break;
16404					case 'digg':
16405						source = "http://digg.com/submit?phase=2&url={URL}",
16406							text = "Share on Digg";
16407						break;
16408					case 'reddit':
16409						source = "http://reddit.com/submit?url={URL}",
16410							text = "Share on reddit";
16411						break;
16412				}
16413
16414				obj[key] = {
16415					URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL,
16416					source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url),
16417					text: value.text || text || "Share on " + key,
16418					width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640,
16419					height: value.height || 360
16420				};
16421
16422			});
16423
16424			return obj;
16425		},
16426
16427		setSocial: function(obj, url, target) {
16428			var iL = this,
16429				socialBar = $('<div class="ilightbox-social"></div>'),
16430				buttons = '<ul>';
16431
16432			obj = iL.normalizeSocial(obj, url);
16433
16434			$.each(obj, function(key, value) {
16435				var item = key.toLowerCase(),
16436					source = value.source.replace(/\{URL\}/g, encodeURIComponent(value.URL).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'));
16437				buttons += '<li class="' + key + '"><a href="' + source + '" onclick="javascript:window.open(this.href' + ((value.width <= 0 || value.height <= 0) ? '' : ', \'\', \'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=' + value.height + ',width=' + value.width + ',left=40,top=40\'') + ');return false;" title="' + value.text + '" target="_blank"></a></li>';
16438			});
16439
16440			buttons += '</ul>';
16441
16442			socialBar.html(buttons);
16443			$('div.ilightbox-container', target).append(socialBar);
16444		},
16445
16446		fullScreenAction: function() {
16447			var iL = this,
16448				vars = iL.vars;
16449
16450			if (fullScreenApi.supportsFullScreen) {
16451				if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement);
16452				else fullScreenApi.requestFullScreen(document.documentElement);
16453			} else {
16454				iL.doFullscreen();
16455			}
16456		},
16457
16458		doFullscreen: function() {
16459			var iL = this,
16460				vars = iL.vars,
16461				viewport = getViewport(),
16462				opts = iL.options;
16463
16464			if (opts.fullAlone) {
16465				var currentHolder = vars.holder,
16466					current = iL.items[vars.current],
16467					windowWidth = viewport.width,
16468					windowHeight = viewport.height,
16469					elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader],
16470					hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails];
16471
16472				if (!vars.isInFullScreen) {
16473					vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true;
16474					vars.overlay.css({
16475						opacity: 1
16476					});
16477
16478					$.each(hideElements, function(i, element) {
16479						element.hide();
16480					});
16481
16482					vars.fullScreenButton.attr('title', opts.text.exitFullscreen);
16483
16484					if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
16485						naturalWidthOld: currentHolder.data('naturalWidth'),
16486						naturalHeightOld: currentHolder.data('naturalHeight'),
16487						naturalWidth: windowWidth,
16488						naturalHeight: windowHeight
16489					});
16490					else {
16491						var viewport = current.options.fullViewPort || opts.fullViewPort || '',
16492							newWidth = windowWidth,
16493							newHeight = windowHeight,
16494							width = currentHolder.data('naturalWidth'),
16495							height = currentHolder.data('naturalHeight');
16496
16497						if (viewport.toLowerCase() == 'fill') {
16498							newHeight = (newWidth / width) * height;
16499
16500							if (newHeight < windowHeight) {
16501								newWidth = (windowHeight / height) * width,
16502									newHeight = windowHeight;
16503							}
16504						} else if (viewport.toLowerCase() == 'fit') {
16505							var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true);
16506
16507							newWidth = dims.width,
16508								newHeight = dims.height;
16509						} else if (viewport.toLowerCase() == 'stretch') {
16510							newWidth = newWidth,
16511								newHeight = newHeight;
16512						} else {
16513							var scale = (width > newWidth || height > newHeight) ? true : false,
16514								dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale);
16515							newWidth = dims.width,
16516								newHeight = dims.height;
16517						}
16518
16519						currentHolder.data({
16520							naturalWidthOld: currentHolder.data('naturalWidth'),
16521							naturalHeightOld: currentHolder.data('naturalHeight'),
16522							naturalWidth: newWidth,
16523							naturalHeight: newHeight
16524						});
16525					}
16526
16527					$.each(elements, function(key, val) {
16528						val.addClass('ilightbox-fullscreen');
16529					});
16530
16531					//Trigger the onEnterFullScreen callback
16532					if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui);
16533				} else {
16534					vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false;
16535					vars.overlay.css({
16536						opacity: iL.options.overlay.opacity
16537					});
16538
16539					$.each(hideElements, function(i, element) {
16540						element.show();
16541					});
16542
16543					vars.fullScreenButton.attr('title', opts.text.enterFullscreen);
16544
16545					currentHolder.data({
16546						naturalWidth: currentHolder.data('naturalWidthOld'),
16547						naturalHeight: currentHolder.data('naturalHeightOld'),
16548						naturalWidthOld: null,
16549						naturalHeightOld: null
16550					});
16551
16552					$.each(elements, function(key, val) {
16553						val.removeClass('ilightbox-fullscreen');
16554					});
16555
16556					//Trigger the onExitFullScreen callback
16557					if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui);
16558				}
16559			} else {
16560				if (!vars.isInFullScreen) vars.isInFullScreen = true;
16561				else vars.isInFullScreen = false;
16562			}
16563			iL.repositionPhoto(true);
16564		},
16565
16566		closeAction: function() {
16567			var iL = this,
16568				vars = iL.vars,
16569				opts = iL.options;
16570
16571			$win.unbind('.iLightBox');
16572			$doc.off('.iLightBox');
16573
16574			if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement);
16575
16576			$('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox');
16577
16578			if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() {
16579				vars.overlay.remove();
16580				vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox');
16581			});
16582			else {
16583				vars.overlay.remove();
16584				vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox');
16585			}
16586
16587			var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails];
16588
16589			$.each(fadeOuts, function(i, element) {
16590				element.removeAttr('style').remove();
16591			});
16592
16593			vars.dontGenerateThumbs = vars.isInFullScreen = false;
16594
16595			window.iLightBox = null;
16596
16597			if (opts.linkId) {
16598				vars.hashLock = true;
16599				removeHash();
16600				setTimeout(function() {
16601					vars.hashLock = false;
16602				}, 55);
16603			}
16604
16605			vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
16606
16607			//Trigger the onHide callback
16608			if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui);
16609		},
16610
16611		repositionPhoto: function() {
16612			var iL = this,
16613				vars = iL.vars,
16614				opts = iL.options,
16615				path = opts.path.toLowerCase(),
16616				viewport = getViewport(),
16617				winWidth = viewport.width,
16618				winHeight = viewport.height;
16619
16620			if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0;
16621
16622			var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()),
16623				thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)),
16624				width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)),
16625				height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)),
16626				offsetW = (path == 'horizontal') ? parseInt((iL.items[vars.next] || iL.items[vars.prev]) ? ((opts.styles.nextOffsetX + opts.styles.prevOffsetX)) * 2 : (((width / 10) <= 30) ? 30 : (width / 10))) : parseInt(((width / 10) <= 30) ? 30 : (width / 10)) + thumbsOffsetW,
16627				offsetH = (path == 'horizontal') ? parseInt(((height / 10) <= 30) ? 30 : (height / 10)) + thumbsOffsetH : parseInt((iL.items[vars.next] || iL.items[vars.prev]) ? ((opts.styles.nextOffsetX + opts.styles.prevOffsetX)) * 2 : (((height / 10) <= 30) ? 30 : (height / 10)));
16628
16629			var elObject = {
16630				type: 'current',
16631				width: width,
16632				height: height,
16633				item: iL.items[vars.current],
16634				offsetW: offsetW,
16635				offsetH: offsetH,
16636				thumbsOffsetW: thumbsOffsetW,
16637				thumbsOffsetH: thumbsOffsetH,
16638				animate: arguments.length,
16639				holder: vars.holder
16640			};
16641
16642			iL.repositionEl(elObject);
16643
16644			if (iL.items[vars.next]) {
16645				elObject = $.extend(elObject, {
16646					type: 'next',
16647					item: iL.items[vars.next],
16648					offsetX: opts.styles.nextOffsetX,
16649					offsetY: opts.styles.nextOffsetY,
16650					holder: vars.nextPhoto
16651				});
16652
16653				iL.repositionEl(elObject);
16654			}
16655
16656			if (iL.items[vars.prev]) {
16657				elObject = $.extend(elObject, {
16658					type: 'prev',
16659					item: iL.items[vars.prev],
16660					offsetX: opts.styles.nextOffsetX,
16661					offsetY: opts.styles.prevOffsetY,
16662					holder: vars.prevPhoto
16663				});
16664
16665				iL.repositionEl(elObject);
16666			}
16667
16668			var loaderCss = (path == "horizontal") ? {
16669				left: parseInt((width / 2) - (vars.loader.outerWidth() / 2))
16670			} : {
16671				top: parseInt((height / 2) - (vars.loader.outerHeight() / 2))
16672			};
16673			vars.loader.css(loaderCss);
16674		},
16675
16676		repositionEl: function(obj) {
16677			var iL = this,
16678				vars = iL.vars,
16679				opts = iL.options,
16680				path = opts.path.toLowerCase(),
16681				widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW),
16682				heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH),
16683				itemParent = obj.item,
16684				item = obj.item.options,
16685				holder = obj.holder,
16686				offsetX = obj.offsetX || 0,
16687				offsetY = obj.offsetY || 0,
16688				//Uncode change ##START##
16689				toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0,
16690				//Uncode change ##END##
16691				thumbsOffsetW = obj.thumbsOffsetW,
16692				thumbsOffsetH = obj.thumbsOffsetH;
16693
16694			if (obj.type == 'current') {
16695				if (typeof item.width == 'number' && item.width) widthAvail = ((vars.isInFullScreen && opts.fullAlone) && (opts.fullStretchTypes.indexOf(itemParent.type) != -1 || item.fullViewPort || opts.fullViewPort)) ? widthAvail : ((item.width > widthAvail) ? widthAvail : item.width);
16696				if (typeof item.height == 'number' && item.height) heightAvail = ((vars.isInFullScreen && opts.fullAlone) && (opts.fullStretchTypes.indexOf(itemParent.type) != -1 || item.fullViewPort || opts.fullViewPort)) ? heightAvail : ((item.height > heightAvail) ? heightAvail : item.height);
16697			} else {
16698				if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width;
16699				if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height;
16700			}
16701
16702
16703			//Uncode change ##START##
16704			heightAvail = parseInt(heightAvail - toolbarHeight);
16705			// heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight());
16706			//Uncode change ##END##
16707
16708			var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'),
16709				height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight');
16710
16711			var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? {
16712					width: width,
16713					height: height
16714				} : iL.getNewDimenstions(widthAvail, heightAvail, width, height)),
16715				newDims = $.extend({}, dims, {});
16716
16717			if (obj.type == 'prev' || obj.type == 'next')
16718				width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)),
16719				height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale));
16720			else
16721				width = dims.width,
16722				height = dims.height;
16723
16724			var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2),
16725				heightDiff = parseInt((getPixel(holder, 'padding-top') + getPixel(holder, 'padding-bottom') + getPixel(holder, 'border-top-width') + getPixel(holder, 'border-bottom-width') + ($('.ilightbox-inner-toolbar', holder).outerHeight() || 0)) / 2);
16726
16727			switch (obj.type) {
16728				case 'current':
16729					var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)),
16730						left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2));
16731					break;
16732
16733				case 'next':
16734					var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)),
16735						left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2));
16736					break;
16737
16738				case 'prev':
16739					var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)),
16740						left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2));
16741					break;
16742			}
16743
16744			holder.data('offset', {
16745				top: top,
16746				left: left,
16747				newDims: newDims,
16748				diff: {
16749					W: widthDiff,
16750					H: heightDiff
16751				},
16752				thumbsOffset: {
16753					W: thumbsOffsetW,
16754					H: thumbsOffsetH
16755				},
16756				object: obj
16757			});
16758
16759			var opacityMobile;
16760			if ( isMobile ) {
16761				opacityMobile = {
16762					opacity: 1,
16763					top: top,
16764					left: left
16765				};
16766			} else {
16767				opacityMobile = {
16768					top: top,
16769					left: left
16770				};
16771			}
16772
16773			if (obj.animate > 0 && opts.effects.reposition) {
16774				holder.css(transform, gpuAcceleration).stop().animate(
16775					opacityMobile,
16776					opts.effects.repositionSpeed, 'easeOutCirc', function() {
16777					holder.css(transform, '');
16778				});
16779				$('div.ilightbox-container', holder).stop().animate({
16780					width: width,
16781					height: height
16782				}, opts.effects.repositionSpeed, 'easeOutCirc');
16783				$('div.ilightbox-inner-toolbar', holder).stop().animate({
16784					width: width
16785				}, opts.effects.repositionSpeed, 'easeOutCirc', function() {
16786					$(this).css('overflow', 'visible');
16787				});
16788			} else {
16789				holder.css(opacityMobile);
16790				$('div.ilightbox-container', holder).css({
16791					width: width,
16792					height: height
16793				});
16794				$('div.ilightbox-inner-toolbar', holder).css({
16795					width: width
16796				});
16797			}
16798		},
16799
16800
16801		resume: function(priority) {
16802			var iL = this,
16803				vars = iL.vars,
16804				opts = iL.options;
16805
16806			if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) {
16807				return;
16808			}
16809
16810			vars.isPaused = 0;
16811
16812			if (vars.cycleID) {
16813				vars.cycleID = clearTimeout(vars.cycleID);
16814			}
16815
16816			vars.cycleID = setTimeout(function() {
16817				if (vars.current == vars.total - 1) iL.goTo(0);
16818				else iL.moveTo('next');
16819			}, opts.slideshow.pauseTime);
16820		},
16821
16822		pause: function(priority) {
16823			var iL = this,
16824				vars = iL.vars,
16825				opts = iL.options;
16826
16827			if (priority < vars.isPaused) {
16828				return;
16829			}
16830
16831			vars.isPaused = priority || 100;
16832
16833			if (vars.cycleID) {
16834				vars.cycleID = clearTimeout(vars.cycleID);
16835			}
16836		},
16837
16838		resetCycle: function() {
16839			var iL = this,
16840				vars = iL.vars,
16841				opts = iL.options;
16842
16843			if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) {
16844				iL.resume();
16845			}
16846		},
16847
16848		getNewDimenstions: function(width, height, width_old, height_old, thumb) {
16849			var iL = this;
16850
16851			if (!width) factor = height / height_old;
16852			else if (!height) factor = width / width_old;
16853			else factor = min(width / width_old, height / height_old);
16854
16855			if (!thumb) {
16856				if (factor > iL.options.maxScale) factor = iL.options.maxScale;
16857				else if (factor < iL.options.minScale) factor = iL.options.minScale;
16858			}
16859
16860			var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width,
16861				final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height;
16862
16863			return {
16864				width: final_width,
16865				height: final_height,
16866				ratio: factor
16867			};
16868		},
16869
16870		setOption: function(options) {
16871			var iL = this;
16872
16873			iL.options = $.extend(true, iL.options, options || {});
16874			iL.refresh();
16875		},
16876
16877		availPlugins: function() {
16878			var iL = this,
16879				testEl = document.createElement("video");
16880
16881			iL.plugins = {
16882				flash: !isMobile,
16883				quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false,
16884				html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')),
16885				html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')),
16886				html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')),
16887				html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, ''))
16888			};
16889		},
16890
16891		addContent: function(element, obj) {
16892			var iL = this,
16893				el;
16894
16895			switch (obj.type) {
16896				case 'video':
16897					var HTML5 = false,
16898						videoType = obj.videoType,
16899						html5video = obj.options.html5video;
16900
16901					if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264)
16902						obj.ext = 'mp4',
16903						obj.URL = html5video.h264 || obj.URL;
16904					else if (html5video.webm && iL.plugins.html5WebM)
16905						obj.ext = 'webm',
16906						obj.URL = html5video.webm || obj.URL;
16907					else if (html5video.ogg && iL.plugins.html5Vorbis)
16908						obj.ext = 'ogv',
16909						obj.URL = html5video.ogg || obj.URL;
16910
16911					if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4";
16912					else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm";
16913					else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg";
16914					else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime";
16915
16916					if (HTML5) {
16917						el = $('<video />
16917', {
16918							"width": "100%",
16919							"height": "100%",
16920							"preload": html5video.preload,
16921							"autoplay": html5video.autoplay,
16922							"loop": html5video.loop,
16923							"poster": html5video.poster,
16924							"controls": html5video.controls,
16925							"controlslist": "nodownload"
16926						}).append($('<source />', {
16927							"src": obj.URL,
16928							"type": videoType
16929						}));
16930					} else {
16931						if (!iL.plugins.quicktime) el = $('<span />', {
16932							"class": "ilightbox-alert",
16933							html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime')
16934						});
16935						else {
16936
16937							el = $('<object />', {
16938								"type": "video/quicktime",
16939								"pluginspage": pluginspages.quicktime
16940							}).attr({
16941								"data": obj.URL,
16942								"width": "100%",
16943								"height": "100%"
16944							}).append($('<param />', {
16945								"name": "src",
16946								"value": obj.URL
16947							})).append($('<param />', {
16948								"name": "autoplay",
16949								"value": "false"
16950							})).append($('<param />', {
16951								"name": "loop",
16952								"value": "false"
16953							})).append($('<param />', {
16954								"name": "scale",
16955								"value": "tofit"
16956							}));
16957
16958							if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false');
16959						}
16960					}
16961
16962					break;
16963
16964				case 'flash':
16965					if (!iL.plugins.flash) el = $('<span />', {
16966						"class": "ilightbox-alert",
16967						html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player')
16968					});
16969					else {
16970						var flashvars = "",
16971							i = 0;
16972
16973						if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) {
16974							if (i != 0) flashvars += "&";
16975							flashvars += k + "=" + encodeURIComponent(v);
16976							i++;
16977						});
16978						else flashvars = null;
16979
16980						el = $('<embed />').attr({
16981							"type": "application/x-shockwave-flash",
16982							"src": obj.URL,
16983							"width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%",
16984							"height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%",
16985							"quality": "high",
16986							"bgcolor": "#000000",
16987							"play": "true",
16988							"loop": "true",
16989							"menu": "true",
16990							"wmode": "transparent",
16991							"scale": "showall",
16992							"allowScriptAccess": "always",
16993							"allowFullScreen": "true",
16994							"flashvars": flashvars,
16995							"fullscreen": "yes"
16996						});
16997					}
16998
16999					break;
17000
17001				case 'iframe':
17002					el = $('<iframe />').attr({
17003						"width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%",
17004						"height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%",
17005						src: obj.URL,
17006						frameborder: 0,
17007						'hspace': 0,
17008						'vspace': 0,
17009						'scrolling': supportTouch ? 'auto' : 'scroll',
17010						'webkitAllowFullScreen': '',
17011						'mozallowfullscreen': '',
17012						'allowFullScreen': ''
17013					});
17014
17015					break;
17016
17017				case 'inline':
17018					el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true));
17019
17020					break;
17021
17022				case 'html':
17023					var object = obj.URL,
17024						el;
17025
17026					if (object[0].nodeName) {
17027						el = $('<div class="ilightbox-wrapper"></div>').html(object);
17028					} else {
17029						var dom = $(obj.URL),
17030							html = (dom.selector) ? $('<div>' + dom + '</div>') : dom;
17031						el = $('<div class="ilightbox-wrapper"></div>').html(html);
17032					}
17033
17034					break;
17035			}
17036
17037			$('div.ilightbox-container', element).empty().html(el);
17038
17039			// For fixing Chrome about just playing the video for first time
17040			if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() {
17041				var src = el[0].currentSrc + '?' + floor(random() * 30000);
17042				el[0].currentSrc = src;
17043				el[0].src = src;
17044			});
17045
17046			return el;
17047		},
17048
17049		ogpRecognition: function(obj, callback) {
17050			var iL = this,
17051				url = obj.URL;
17052
17053			iL.showLoader();
17054			doAjax(url, function(data) {
17055				iL.hideLoader();
17056				if (data) {
17057					var object = new Object();
17058
17059					object.length = false,
17060					object.url = data.url;
17061
17062					if (data.status == 200) {
17063						var result = data.results,
17064							type = result.type,
17065							source = result.source;
17066
17067						object.source = source.src,
17068						object.width = source.width && parseInt(source.width) || 0,
17069						object.height = source.height && parseInt(source.height) || 0,
17070						object.type = type,
17071						object.thumbnail = source.thumbnail || result.images && result.images[0],
17072						object.html5video = result.html5video || {},
17073						object.length = true;
17074
17075						if (source.type == 'application/x-shockwave-flash') object.type = "flash";
17076						else if (source.type.indexOf("video/") != -1) object.type = "video";
17077						else if (source.type.indexOf("/html") != -1) object.type = "iframe";
17078						else if (source.type.indexOf("image/") != -1) object.type = "image";
17079
17080					} else if (typeof data.response != 'undefined')
17081						throw data.response;
17082
17083					callback.call(this, object.length ? object : false);
17084				}
17085			});
17086		},
17087
17088		hashChangeHandler: function(url) {
17089			var iL = this,
17090				vars = iL.vars,
17091				opts = iL.options,
17092				URL = url || window.location.href,
17093				hash = parseURI(URL).hash,
17094				split = hash.split('/'),
17095				index = split[1];
17096
17097			if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return;
17098
17099			if (index) {
17100				var target = split[1] || 0;
17101				if (iL.items[target]) {
17102					var overlay = $('.ilightbox-overlay');
17103					if (overlay.length && overlay.attr('linkid') == opts.linkId) {
17104						iL.goTo(target);
17105					} else {
17106						iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click');
17107						//iL.goTo(target);
17108					}
17109				} else {
17110					var overlay = $('.ilightbox-overlay');
17111					if (overlay.length) iL.closeAction();
17112				}
17113			} else {
17114				var overlay = $('.ilightbox-overlay');
17115				if (overlay.length) iL.closeAction();
17116			}
17117		}
17118	};
17119
17120	/**
17121	 * Parse style to pixels.
17122	 *
17123	 * @param {Object}   $element   jQuery object with element.
17124	 * @param {Property} property   CSS property to get the pixels from.
17125	 *
17126	 * @return {Int}
17127	 */
17128	function getPixel($element, property) {
17129		return parseInt($element.css(property), 10) || 0;
17130	}
17131
17132	/**
17133	 * Make sure that number is within the limits.
17134	 *
17135	 * @param {Number} number
17136	 * @param {Number} min
17137	 * @param {Number} max
17138	 *
17139	 * @return {Number}
17140	 */
17141	function within(number, min, max) {
17142		return number < min ? min : number > max ? max : number;
17143	}
17144
17145	/**
17146	 * Get viewport/window size (width and height).
17147	 *
17148	 * @return {Object}
17149	 */
17150	function getViewport() {
17151		var e = window,
17152			a = 'inner';
17153		if (!('innerWidth' in window)) {
17154			a = 'client';
17155			e = document.documentElement || document.body;
17156		}
17157		return {
17158			width: e[a + 'Width'],
17159			height: e[a + 'Height']
17160		}
17161	}
17162
17163	/**
17164	 * Remove hash tag from the URL
17165	 *
17166	 * @return {Void}
17167	 */
17168	function removeHash() {
17169		var scroll = getScrollXY();
17170
17171		//UNCODE change
17172		// window.location.hash = "";
17173		// history.pushState("", document.title, window.location.pathname + window.location.search);
17174		history.replaceState({}, document.title, window.location.pathname + window.location.search);
17175
17176		// Restore the scroll offset, should be flicker free
17177		window.scrollTo(scroll.x, scroll.y);
17178	}
17179
17180	/**
17181	 * Do the ajax requests with callback.
17182	 *
17183	 * @param {String}   url
17184	 * @param {Function} callback
17185	 *
17186	 * @return {Void}
17187	 */
17188	function doAjax(url, callback) {
17189		var url = "//ilightbox.net/getSource/jsonp.php?url=" + encodeURIComponent(url).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A');
17190		$.ajax({
17191			url: url,
17192			dataType: 'jsonp'
17193		});
17194
17195		iLCallback = function(data) {
17196			callback.call(this, data);
17197		};
17198	}
17199
17200	/**
17201	 * Find image from DOM elements
17202	 *
17203	 * @param {Element} element
17204	 *
17205	 * @return {Void}
17206	 */
17207	function findImageInElement(element) {
17208		var elements = $('*', element),
17209			imagesArr = new Array();
17210
17211		elements.each(function() {
17212			var url = "",
17213				element = this;
17214
17215			if ($(element).css("background-image") != "none") {
17216				url = $(element).css("background-image");
17217			} else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") {
17218				url = $(element).attr("src");
17219			}
17220
17221			if (url.indexOf("gradient") == -1) {
17222				url = url.replace(/url\(\"/g, "");
17223				url = url.replace(/url\(/g, "");
17224				url = url.replace(/\"\)/g, "");
17225				url = url.replace(/\)/g, "");
17226
17227				var urls = url.split(",");
17228
17229				for (var i = 0; i < urls.length; i++) {
17230					if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) {
17231						var extra = "";
17232						if (browser.msie && browser.version < 9) {
17233							extra = "?" + floor(random() * 3000);
17234						}
17235						imagesArr.push(urls[i] + extra);
17236					}
17237				}
17238			}
17239		});
17240
17241		return imagesArr;
17242	}
17243
17244	/**
17245	 * Get file extension.
17246	 *
17247	 * @param {String} URL
17248	 *
17249	 * @return {String}
17250	 */
17251	function getExtension(URL) {
17252		if (URL !== null) {
17253			//UNCODE: fix issue to detect media type with query strings
17254			var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL;
17255			ext = ext.split('.').pop().toLowerCase();
17256
17257			return ext;
17258		}
17259	}
17260
17261	/**
17262	 * Get type via extension.
17263	 *
17264	 * @param {String} URL
17265	 *
17266	 * @return {String}
17267	 */
17268	function getTypeByExtension(URL) {
17269		var type,
17270			ext = getExtension(URL);
17271
17272		//Uncode addition ##START##
17273		if (URL == undefined) {
17274			return false;
17275		}
17276		//Uncode addition ##END##
17277
17278		if (extensions.image.indexOf(ext) !== -1) type = 'image';
17279		else if (extensions.flash.indexOf(ext) !== -1) type = 'flash';
17280		else if (extensions.video.indexOf(ext) !== -1) type = 'video';
17281		else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition
17282		else type = 'iframe';
17283
17284		return type;
17285	}
17286
17287	/**
17288	 * Return value from percent of a number.
17289	 *
17290	 * @param {Number} percent
17291	 * @param {Number} total
17292	 *
17293	 * @return {Number}
17294	 */
17295	function percentToValue(percent, total) {
17296		return parseInt((total / 100) * percent);
17297	}
17298
17299	/**
17300	 * A JavaScript equivalent of PHP’s parse_url.
17301	 *
17302	 * @param {String} url           The URL to parse.
17303	 *
17304	 * @return {Mixed}
17305	 */
17306	function parseURI(url) {
17307		var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
17308		// authority = '//' + user + ':' + pass '@' + hostname + ':' port
17309		return (m ? {
17310			href: m[0] || '',
17311			protocol: m[1] || '',
17312			authority: m[2] || '',
17313			host: m[3] || '',
17314			hostname: m[4] || '',
17315			port: m[5] || '',
17316			pathname: m[6] || '',
17317			search: m[7] || '',
17318			hash: m[8] || ''
17319		} : null);
17320	}
17321
17322	/**
17323	 * Gets the absolute URI.
17324	 *
17325	 * @param {String} href     The relative URL.
17326	 * @param {String} base     The base URL.
17327	 *
17328	 * @return {String}         The absolute URL.
17329	 */
17330	function absolutizeURI(base, href) { // RFC 3986
17331		var iL = this;
17332
17333		function removeDotSegments(input) {
17334			var output = [];
17335			input.replace(/^(\.\.?(\/|$))+/, '')
17336				.replace(/\/(\.(\/|$))+/g, '/')
17337				.replace(/\/\.\.$/, '/../')
17338				.replace(/\/?[^\/]*/g, function(p) {
17339					if (p === '/..') {
17340						output.pop();
17341					} else {
17342						output.push(p);
17343					}
17344				});
17345			return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
17346		}
17347
17348		href = parseURI(href || '');
17349		base = parseURI(base || '');
17350
17351		return !href || !base ? null : (href.protocol || base.protocol) +
17352			(href.protocol || href.authority ? href.authority : base.authority) +
17353			removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
17354			(href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
17355			href.hash;
17356	}
17357
17358	/**
17359	 * A JavaScript equivalent of PHP’s version_compare.
17360	 *
17361	 * @param {String} v1
17362	 * @param {String} v2
17363	 * @param {String} operator
17364	 *
17365	 * @return {Boolean}
17366	 */
17367	function version_compare(v1, v2, operator) {
17368		this.php_js = this.php_js || {};
17369		this.php_js.ENV = this.php_js.ENV || {};
17370		var i = 0,
17371			x = 0,
17372			compare = 0,
17373			vm = {
17374				'dev': -6,
17375				'alpha': -5,
17376				'a': -5,
17377				'beta': -4,
17378				'b': -4,
17379				'RC': -3,
17380				'rc': -3,
17381				'#': -2,
17382				'p': 1,
17383				'pl': 1
17384			},
17385			prepVersion = function(v) {
17386				v = ('' + v).replace(/[_\-+]/g, '.');
17387				v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.');
17388				return (!v.length ? [-8] : v.split('.'));
17389			},
17390			numVersion = function(v) {
17391				return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
17392			};
17393		v1 = prepVersion(v1);
17394		v2 = prepVersion(v2);
17395		x = max(v1.length, v2.length);
17396		for (i = 0; i < x; i++) {
17397			if (v1[i] == v2[i]) {
17398				continue;
17399			}
17400			v1[i] = numVersion(v1[i]);
17401			v2[i] = numVersion(v2[i]);
17402			if (v1[i] < v2[i]) {
17403				compare = -1;
17404				break;
17405			} else if (v1[i] > v2[i]) {
17406				compare = 1;
17407				break;
17408			}
17409		}
17410		if (!operator) {
17411			return compare;
17412		}
17413
17414		switch (operator) {
17415			case '>':
17416			case 'gt':
17417				return (compare > 0);
17418			case '>=':
17419			case 'ge':
17420				return (compare >= 0);
17421			case '<=':
17422			case 'le':
17423				return (compare <= 0);
17424			case '==':
17425			case '=':
17426			case 'eq':
17427				return (compare === 0);
17428			case '<>':
17429			case '!=':
17430			case 'ne':
17431				return (compare !== 0);
17432			case '':
17433			case '<':
17434			case 'lt':
17435				return (compare < 0);
17436			default:
17437				return null;
17438		}
17439	}
17440
17441
17442	// Begin the iLightBox plugin
17443	$.fn.iLightBox = function() {
17444
17445		var args = arguments,
17446			opt = ($.isPlainObject(args[0])) ? args[0] : args[1],
17447			items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1];
17448
17449		if (!opt) opt = {};
17450
17451		// Default options. Play carefully.
17452		var options = $.extend(true, {
17453			attr: 'href',
17454			path: 'vertical',
17455			skin: 'dark',
17456			linkId: false,
17457			infinite: false,
17458			startFrom: 0,
17459			randomStart: false,
17460			keepAspectRatio: true,
17461			maxScale: 1,
17462			minScale: .2,
17463			innerToolbar: false,
17464			smartRecognition: false,
17465			mobileOptimizer: true,
17466			fullAlone: true,
17467			fullViewPort: null,
17468			fullStretchTypes: 'flash, video',
17469			overlay: {
17470				blur: true,
17471				opacity: .85
17472			},
17473			controls: {
17474				arrows: false,
17475				slideshow: false,
17476				toolbar: true,
17477				fullscreen: true,
17478				thumbnail: true,
17479				keyboard: true,
17480				mousewheel: true,
17481				swipe: true
17482			},
17483			keyboard: {
17484				left: true, // previous
17485				right: true, // next
17486				up: true, // previous
17487				down: true, // next
17488				esc: true, // close
17489				shift_enter: true // fullscreen
17490			},
17491			show: {
17492				effect: true,
17493				speed: 300,
17494				title: true
17495			},
17496			hide: {
17497				effect: true,
17498				speed: 300
17499			},
17500			caption: {
17501				start: true,
17502				show: 'mouseenter',
17503				hide: 'mouseleave'
17504			},
17505			social: {
17506				start: true,
17507				show: 'mouseenter',
17508				hide: 'mouseleave',
17509				buttons: false
17510			},
17511			styles: {
17512				pageOffsetX: 0,
17513				pageOffsetY: 0,
17514				nextOffsetX: 45,
17515				nextOffsetY: 0,
17516				nextOpacity: 1,
17517				nextScale: 1,
17518				prevOffsetX: 45,
17519				prevOffsetY: 0,
17520				prevOpacity: 1,
17521				prevScale: 1
17522			},
17523			thumbnails: {
17524				maxWidth: 120,
17525				maxHeight: 80,
17526				normalOpacity: 1,
17527				activeOpacity: .6
17528			},
17529			effects: {
17530				reposition: true,
17531				repositionSpeed: 200,
17532				switchSpeed: 500,
17533				loadedFadeSpeed: 180,
17534				fadeSpeed: 200
17535			},
17536			slideshow: {
17537				pauseTime: 5000,
17538				pauseOnHover: false,
17539				startPaused: true
17540			},
17541			text: {
17542				close: "Press Esc to close",
17543				enterFullscreen: "Enter Fullscreen (Shift+Enter)",
17544				exitFullscreen: "Exit Fullscreen (Shift+Enter)",
17545				slideShow: "Slideshow",
17546				next: "Next",
17547				previous: "Previous"
17548			},
17549			errors: {
17550				loadImage: "An error occurred when trying to load photo.",
17551				loadContents: "An error occurred when trying to load contents.",
17552				missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>."
17553			},
17554			ajaxSetup: {
17555				url: '',
17556				beforeSend: function(jqXHR, settings) {},
17557				cache: false,
17558				complete: function(jqXHR, textStatus) {},
17559				crossDomain: false,
17560				error: function(jqXHR, textStatus, errorThrown) {},
17561				success: function(data, textStatus, jqXHR) {},
17562				global: true,
17563				ifModified: false,
17564				username: null,
17565				password: null,
17566				type: 'GET'
17567			},
17568			callback: {}
17569		}, opt);
17570
17571		var instant = ($.isArray(items) || typeof items == 'string') ? true : false;
17572
17573		items = $.isArray(items) ? items : new Array();
17574
17575		if (typeof args[0] == 'string') items[0] = args[0];
17576
17577		if (version_compare($.fn.jquery, '1.8', '>=')) {
17578			var iLB = new iLightBox($(this), options, items, instant);
17579			return {
17580				close: function() {
17581					iLB.closeAction();
17582				},
17583				fullscreen: function() {
17584					iLB.fullScreenAction();
17585				},
17586				moveNext: function() {
17587					iLB.moveTo('next');
17588				},
17589				movePrev: function() {
17590					iLB.moveTo('prev');
17591				},
17592				goTo: function(index) {
17593					iLB.goTo(index);
17594				},
17595				refresh: function() {
17596					iLB.refresh();
17597				},
17598				reposition: function() {
17599					(arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto();
17600				},
17601				setOption: function(options) {
17602					iLB.setOption(options);
17603				},
17604				destroy: function() {
17605					iLB.closeAction();
17606					iLB.dispatchItemsEvents();
17607				}
17608			};
17609		} else {
17610			throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+";
17611		}
17612
17613	};
17614
17615
17616	$.iLightBox = function() {
17617		return $.fn.iLightBox(arguments[0], arguments[1]);
17618	};
17619
17620	function getScrollXY() {
17621		var scrOfX = 0,
17622			scrOfY = 0;
17623		if (typeof(window.pageYOffset) == 'number') {
17624			//Netscape compliant
17625			scrOfY = window.pageYOffset;
17626			scrOfX = window.pageXOffset;
17627		} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
17628			//DOM compliant
17629			scrOfY = document.body.scrollTop;
17630			scrOfX = document.body.scrollLeft;
17631		} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
17632			//IE6 standards compliant mode
17633			scrOfY = document.documentElement.scrollTop;
17634			scrOfX = document.documentElement.scrollLeft;
17635		}
17636		return {
17637			x: scrOfX,
17638			y: scrOfY
17639		};
17640	}
17641
17642	(function() {
17643		// add new event shortcuts
17644		$.each(("touchstart touchmove touchend " +
17645			"tap taphold " +
17646			"swipe swipeleft swiperight " +
17647			"scrollstart scrollstop").split(" "), function(i, name) {
17648
17649			$.fn[name] = function(fn) {
17650				return fn ? this.bind(name, fn) : this.trigger(name);
17651			};
17652
17653			// jQuery < 1.8
17654			// if ($.attrFn) {
17655			// 	$.attrFn[name] = true;
17656			// }
17657		});
17658
17659		var tapSettings = {
17660			startEvent: 'touchstart.iTap',
17661			endEvent: 'touchend.iTap'
17662		};
17663
17664		// tap Event:
17665		$.event.special.itap = {
17666			setup: function() {
17667
17668				var self = this,
17669					$self = $(this),
17670					start, stop;
17671
17672				$self.bind(tapSettings.startEvent, function(event) {
17673					start = getScrollXY();
17674
17675					$self.one(tapSettings.endEvent, function(event) {
17676						stop = getScrollXY();
17677
17678						var orgEvent = event || window.event;
17679						event = $.event.fix(orgEvent);
17680						event.type = "itap";
17681
17682						if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event);
17683
17684						start = stop = undefined;
17685					});
17686				});
17687			},
17688
17689			teardown: function() {
17690				$(this).unbind(tapSettings.startEvent);
17691			}
17692		};
17693	}());
17694
17695
17696	//Fullscreen API
17697	(function() {
17698		fullScreenApi = {
17699				supportsFullScreen: false,
17700				isFullScreen: function() {
17701					return false;
17702				},
17703				requestFullScreen: function() {},
17704				cancelFullScreen: function() {},
17705				fullScreenEventName: '',
17706				prefix: ''
17707			},
17708			browserPrefixes = 'webkit moz o ms khtml'.split(' ');
17709
17710		// check for native support
17711		if (typeof document.cancelFullScreen != 'undefined') {
17712			fullScreenApi.supportsFullScreen = true;
17713		} else {
17714			// check for fullscreen support by vendor prefix
17715			for (var i = 0, il = browserPrefixes.length; i < il; i++) {
17716				fullScreenApi.prefix = browserPrefixes[i];
17717
17718				if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') {
17719					fullScreenApi.supportsFullScreen = true;
17720
17721					break;
17722				}
17723			}
17724		}
17725
17726		// update methods to do something useful
17727		if (fullScreenApi.supportsFullScreen) {
17728			fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
17729
17730			fullScreenApi.isFullScreen = function() {
17731				switch (this.prefix) {
17732					case '':
17733						return document.fullScreen;
17734					case 'webkit':
17735						return document.webkitIsFullScreen;
17736					default:
17737						return document[this.prefix + 'FullScreen'];
17738				}
17739			}
17740			fullScreenApi.requestFullScreen = function(el) {
17741				return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
17742			}
17743			fullScreenApi.cancelFullScreen = function(el) {
17744				return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
17745			}
17746		}
17747	}());
17748
17749	// Browser detect
17750	(function() {
17751		function uaMatch(ua) {
17752			ua = ua.toLowerCase();
17753
17754			var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
17755				/(webkit)[ \/]([\w.]+)/.exec(ua) ||
17756				/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
17757				/(msie) ([\w.]+)/.exec(ua) ||
17758				ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
17759
17760			return {
17761				browser: match[1] || "",
17762				version: match[2] || "0"
17763			};
17764		}
17765
17766		var matched = uaMatch(navigator.userAgent);
17767		browser = {};
17768
17769		if (matched.browser) {
17770			browser[matched.browser] = true;
17771			browser.version = matched.version;
17772		}
17773
17774		// Chrome is Webkit, but Webkit is also Safari.
17775		if (browser.chrome) {
17776			browser.webkit = true;
17777		} else if (browser.webkit) {
17778			browser.safari = true;
17779		}
17780	}());
17781
17782	// Feature detects
17783	(function() {
17784		var prefixes = ['', 'webkit', 'moz', 'ms', 'o'];
17785		var el = document.createElement('div');
17786
17787		function testProp(prop) {
17788			for (var p = 0, pl = prefixes.length; p < pl; p++) {
17789				var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop;
17790				if (el.style[prefixedProp] !== undefined) {
17791					return prefixedProp;
17792				}
17793			}
17794		}
17795
17796		// Global support indicators
17797		transform = testProp('transform') || '';
17798		gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : '';
17799	}());
17800
17801
17802	/*
17803		PluginDetect v0.7.9
17804		www.pinlady.net/PluginDetect/license/
17805		[ getVersion onWindowLoaded BetterIE ]
17806		[ Flash QuickTime Shockwave ]
17807	*/
17808	var PluginDetect={version:"0.7.9",name:"PluginDetect",handler:function(c,b,a){return function(){c(b,a)}},openTag:"<",isDefined:function(b){return typeof b!="undefined"},isArray:function(b){return(/array/i).test(Object.prototype.toString.call(b))},isFunc:function(b){return typeof b=="function"},isString:function(b){return typeof b=="string"},isNum:function(b){return typeof b=="number"},isStrNum:function(b){return(typeof b=="string"&&(/\d/).test(b))},getNumRegx:/[\d][\d\.\_,-]*/,splitNumRegx:/[\.\_,-]/g,getNum:function(b,c){var d=this,a=d.isStrNum(b)?(d.isDefined(c)?new RegExp(c):d.getNumRegx).exec(b):null;return a?a[0]:null},compareNums:function(h,f,d){var e=this,c,b,a,g=parseInt;if(e.isStrNum(h)&&e.isStrNum(f)){if(e.isDefined(d)&&d.compareNums){return d.compareNums(h,f)}c=h.split(e.splitNumRegx);b=f.split(e.splitNumRegx);for(a=0;a<min(c.length,b.length);a++){if(g(c[a],10)>g(b[a],10)){return 1}if(g(c[a],10)<g(b[a],10)){return -1}}}return 0},formatNum:function(b,c){var d=this,a,e;if(!d.isStrNum(b)){return null}if(!d.isNum(c)){c=4}c--;e=b.replace(/\s/g,"").split(d.splitNumRegx).concat(["0","0","0","0"]);for(a=0;a<4;a++){if(/^(0+)(.+)$/.test(e[a])){e[a]=RegExp.$2}if(a>c||!(/\d/).test(e[a])){e[a]="0"}}return e.slice(0,4).join(",")},$$hasMimeType:function(a){return function(c){if(!a.isIE&&c){var f,e,b,d=a.isArray(c)?c:(a.isString(c)?[c]:[]);for(b=0;b<d.length;b++){if(a.isString(d[b])&&/[^\s]/.test(d[b])){f=navigator.mimeTypes[d[b]];e=f?f.enabledPlugin:0;if(e&&(e.name||e.description)){return f}}}}return null}},findNavPlugin:function(l,e,c){var j=this,h=new RegExp(l,"i"),d=(!j.isDefined(e)||e)?/\d/:0,k=c?new RegExp(c,"i"):0,a=navigator.plugins,g="",f,b,m;for(f=0;f<a.length;f++){m=a[f].description||g;b=a[f].name||g;if((h.test(m)&&(!d||d.test(RegExp.leftContext+RegExp.rightContext)))||(h.test(b)&&(!d||d.test(RegExp.leftContext+RegExp.rightContext)))){if(!k||!(k.test(m)||k.test(b))){return a[f]}}}return null},getMimeEnabledPlugin:function(k,m,c){var e=this,f,b=new RegExp(m,"i"),h="",g=c?new RegExp(c,"i"):0,a,l,d,j=e.isString(k)?[k]:k;for(d=0;d<j.length;
17808d++){if((f=e.hasMimeType(j[d]))&&(f=f.enabledPlugin)){l=f.description||h;a=f.name||h;if(b.test(l)||b.test(a)){if(!g||!(g.test(l)||g.test(a))){return f}}}}return 0},getPluginFileVersion:function(f,b){var h=this,e,d,g,a,c=-1;if(h.OS>2||!f||!f.version||!(e=h.getNum(f.version))){return b}if(!b){return e}e=h.formatNum(e);b=h.formatNum(b);d=b.split(h.splitNumRegx);g=e.split(h.splitNumRegx);for(a=0;a<d.length;a++){if(c>-1&&a>c&&d[a]!="0"){return b}if(g[a]!=d[a]){if(c==-1){c=a}if(d[a]!="0"){return b}}}return e},AXO:window.ActiveXObject,getAXO:function(a){var f=null,d,b=this,c={};try{f=new b.AXO(a)}catch(d){}return f},convertFuncs:function(f){var a,g,d,b=/^[\$][\$]/,c=this;for(a in f){if(b.test(a)){try{g=a.slice(2);if(g.length>0&&!f[g]){f[g]=f[a](f);delete f[a]}}catch(d){}}}},initObj:function(e,b,d){var a,c;if(e){if(e[b[0]]==1||d){for(a=0;a<b.length;a=a+2){e[b[a]]=b[a+1]}}for(a in e){c=e[a];if(c&&c[b[0]]==1){this.initObj(c,b)}}}},initScript:function(){var d=this,a=navigator,h,i=document,l=a.userAgent||"",j=a.vendor||"",b=a.platform||"",k=a.product||"";d.initObj(d,["$",d]);for(h in d.Plugins){if(d.Plugins[h]){d.initObj(d.Plugins[h],["$",d,"$$",d.Plugins[h]],1)}}d.convertFuncs(d);d.OS=100;if(b){var g=["Win",1,"Mac",2,"Linux",3,"FreeBSD",4,"iPhone",21.1,"iPod",21.2,"iPad",21.3,"Win.*CE",22.1,"Win.*Mobile",22.2,"Pocket\\s*PC",22.3,"",100];for(h=g.length-2;h>=0;h=h-2){if(g[h]&&new RegExp(g[h],"i").test(b)){d.OS=g[h+1];break}}};d.head=i.getElementsByTagName("head")[0]||i.getElementsByTagName("body")[0]||i.body||null;d.isIE=new Function("return/*@cc_on!@*/!1")();d.verIE=d.isIE&&(/MSIE\s*(\d+\.?\d*)/i).test(l)?parseFloat(RegExp.$1,10):null;d.verIEfull=null;d.docModeIE=null;if(d.isIE){var f,n,c=document.createElement("div");try{c.style.behavior="url(#default#clientcaps)";d.verIEfull=(c.getComponentVersion("{89820200-ECBD-11CF-8B85-00AA005B4383}","componentid")).replace(/,/g,".")}catch(f){}n=parseFloat(d.verIEfull||"0",10);d.docModeIE=i.documentMode||((/back/i).test(i.compatMode||"")?5:n)||d.verIE;d.verIE=n||d.docModeIE};d.ActiveXEnabled=false;if(d.isIE){var h,m=["Msxml2.XMLHTTP","Msxml2.DOMDocument","Microsoft.XMLDOM","ShockwaveFlash.ShockwaveFlash","TDCCtl.TDCCtl","Shell.UIHelper","Scripting.Dictionary","wmplayer.ocx"];for(h=0;h<m.length;h++){if(d.getAXO(m[h])){d.ActiveXEnabled=true;break}}};d.isGecko=(/Gecko/i).test(k)&&(/Gecko\s*\/\s*\d/i).test(l);
17808d.verGecko=d.isGecko?d.formatNum((/rv\s*\:\s*([\.\,\d]+)/i).test(l)?RegExp.$1:"0.9"):null;d.isChrome=(/Chrome\s*\/\s*(\d[\d\.]*)/i).test(l);d.verChrome=d.isChrome?d.formatNum(RegExp.$1):null;d.isSafari=((/Apple/i).test(j)||(!j&&!d.isChrome))&&(/Safari\s*\/\s*(\d[\d\.]*)/i).test(l);d.verSafari=d.isSafari&&(/Version\s*\/\s*(\d[\d\.]*)/i).test(l)?d.formatNum(RegExp.$1):null;d.isOpera=(/Opera\s*[\/]?\s*(\d+\.?\d*)/i).test(l);d.verOpera=d.isOpera&&((/Version\s*\/\s*(\d+\.?\d*)/i).test(l)||1)?parseFloat(RegExp.$1,10):null;d.addWinEvent("load",d.handler(d.runWLfuncs,d))},init:function(d){var c=this,b,d,a={status:-3,plugin:0};if(!c.isString(d)){return a}if(d.length==1){c.getVersionDelimiter=d;return a}d=d.toLowerCase().replace(/\s/g,"");b=c.Plugins[d];if(!b||!b.getVersion){return a}a.plugin=b;if(!c.isDefined(b.installed)){b.installed=null;b.version=null;b.version0=null;b.getVersionDone=null;b.pluginName=d}c.garbage=false;if(c.isIE&&!c.ActiveXEnabled&&d!=="java"){a.status=-2;return a}a.status=1;return a},fPush:function(b,a){var c=this;if(c.isArray(a)&&(c.isFunc(b)||(c.isArray(b)&&b.length>0&&c.isFunc(b[0])))){a.push(b)}},callArray:function(b){var c=this,a;if(c.isArray(b)){for(a=0;a<b.length;a++){if(b[a]===null){return}c.call(b[a]);b[a]=null}}},call:function(c){var b=this,a=b.isArray(c)?c.length:-1;if(a>0&&b.isFunc(c[0])){c[0](b,a>1?c[1]:0,a>2?c[2]:0,a>3?c[3]:0)}else{if(b.isFunc(c)){c(b)}}},getVersionDelimiter:",",$$getVersion:function(a){return function(g,d,c){var e=a.init(g),f,b,h={};if(e.status<0){return null};f=e.plugin;if(f.getVersionDone!=1){f.getVersion(null,d,c);if(f.getVersionDone===null){f.getVersionDone=1}}a.cleanup();b=(f.version||f.version0);b=b?b.replace(a.splitNumRegx,a.getVersionDelimiter):b;return b}},cleanup:function(){var a=this;if(a.garbage&&a.isDefined(window.CollectGarbage)){window.CollectGarbage()}},isActiveXObject:function(d,b){var f=this,a=false,g,c='<object width="1" height="1" style="display:none" '+d.getCodeBaseVersion(b)+">"+d.HTML+f.openTag+"/object>";if(!f.head){return a}f.head.insertBefore(document.createElement("object"),f.head.firstChild);f.head.firstChild.outerHTML=c;try{f.head.firstChild.classid=d.classID}catch(g){}try{if(f.head.firstChild.object){a=true}}catch(g){}try{if(a&&f.head.firstChild.readyState<4){f.garbage=true}}catch(g){}f.head.removeChild(f.head.firstChild);return a},codebaseSearch:function(f,b){var c=this;if(!c.ActiveXEnabled||!f){return null}if(f.BIfuncs&&f.BIfuncs.length&&f.BIfuncs[f.BIfuncs.length-1]!==null){c.callArray(f.BIfuncs)}var d,o=f.SEARCH,k={};if(c.isStrNum(b)){if(o.match&&o.min&&c.compareNums(b,o.min)<=0){return true}if(o.match&&o.max&&c.compareNums(b,o.max)>=0){return false}d=c.isActiveXObject(f,b);if(d&&(!o.min||c.compareNums(b,o.min)>0)){o.min=b}if(!d&&(!o.max||c.compareNums(b,o.max)<0)){o.max=b}return d};var e=[0,0,0,0],l=[].concat(o.digits),a=o.min?1:0,j,i,h,g,m,n=function(p,r){var q=[].concat(e);q[p]=r;return c.isActiveXObject(f,q.join(","))};if(o.max){g=o.max.split(c.splitNumRegx);for(j=0;j<g.length;j++){g[j]=parseInt(g[j],10)}if(g[0]<l[0]){l[0]=g[0]}}if(o.min){m=o.min.split(c.splitNumRegx);for(j=0;j<m.length;j++){m[j]=parseInt(m[j],10)}if(m[0]>e[0]){e[0]=m[0]}}if(m&&g){for(j=1;j<m.length;j++){if(m[j-1]!=g[j-1]){break}if(g[j]<l[j]){l[j]=g[j]}if(m[j]>e[j]){e[j]=m[j]}}}if(o.max){for(j=1;j<l.length;j++){if(g[j]>0&&l[j]==0&&l[j-1]<o.digits[j-1]){l[j-1]+=1;break}}};for(j=0;j<l.length;j++){h={};for(i=0;i<20;i++){if(l[j]-e[j]<1){break}d=round((l[j]+e[j])/2);if(h["a"+d]){break}h["a"+d]=1;if(n(j,d)){e[j]=d;a=1}else{l[j]=d}}l[j]=e[j];if(!a&&n(j,e[j])){a=1};if(!a){break}};return a?e.join(","):null},addWinEvent:function(d,c){var e=this,a=window,b;if(e.isFunc(c)){if(a.addEventListener){a.addEventListener(d,c,false)}else{if(a.attachEvent){a.attachEvent("on"+d,c)}else{b=a["on"+d];a["on"+d]=e.winHandler(c,b)}}}},winHandler:function(d,c){return function(){d();if(typeof c=="function"){c()}}},WLfuncs0:[],WLfuncs:[],runWLfuncs:function(a){var b={};a.winLoaded=true;a.callArray(a.WLfuncs0);a.callArray(a.WLfuncs);if(a.onDoneEmptyDiv){a.onDoneEmptyDiv()}},winLoaded:false,$$onWindowLoaded:function(a){return function(b){if(a.winLoaded){a.call(b)}else{a.fPush(b,a.WLfuncs)}}},div:null,divID:"plugindetect",divWidth:50,pluginSize:1,emptyDiv:function(){var d=this,b,h,c,a,f,g;if(d.div&&d.div.childNodes){for(b=d.div.childNodes.length-1;b>=0;b--){c=d.div.childNodes[b];if(c&&c.childNodes){for(h=c.childNodes.length-1;h>=0;h--){g=c.childNodes[h];try{c.removeChild(g)}catch(f){}}}if(c){try{d.div.removeChild(c)}catch(f){}}}}if(!d.div){a=document.getElementById(d.divID);if(a){d.div=a}}if(d.div&&d.div.parentNode){try{d.div.parentNode.removeChild(d.div)}catch(f){}d.div=null}},DONEfuncs:[],onDoneEmptyDiv:function(){var c=this,a,b;if(!c.winLoaded){return}if(c.WLfuncs&&c.WLfuncs.length&&c.WLfuncs[c.WLfuncs.length-1]!==null){return}for(a in c){b=c[a];if(b&&b.funcs){if(b.OTF==3){return}if(b.funcs.length&&b.funcs[b.funcs.length-1]!==null){return}}}for(a=0;a<c.DONEfuncs.length;a++){c.callArray(c.DONEfuncs)}
17808c.emptyDiv()},getWidth:function(c){if(c){var a=c.scrollWidth||c.offsetWidth,b=this;if(b.isNum(a)){return a}}return -1},getTagStatus:function(m,g,a,b){var c=this,f,k=m.span,l=c.getWidth(k),h=a.span,j=c.getWidth(h),d=g.span,i=c.getWidth(d);if(!k||!h||!d||!c.getDOMobj(m)){return -2}if(j<i||l<0||j<0||i<0||i<=c.pluginSize||c.pluginSize<1){return 0}if(l>=i){return -1}try{if(l==c.pluginSize&&(!c.isIE||c.getDOMobj(m).readyState==4)){if(!m.winLoaded&&c.winLoaded){return 1}if(m.winLoaded&&c.isNum(b)){if(!c.isNum(m.count)){m.count=b}if(b-m.count>=10){return 1}}}}catch(f){}return 0},getDOMobj:function(g,a){var f,d=this,c=g?g.span:0,b=c&&c.firstChild?1:0;try{if(b&&a){d.div.focus()}}catch(f){}return b?c.firstChild:null},setStyle:function(b,g){var f=b.style,a,d,c=this;if(f&&g){for(a=0;a<g.length;a=a+2){try{f[g[a]]=g[a+1]}catch(d){}}}},insertDivInBody:function(i,g){var f,c=this,h="pd33993399",b=null,d=g?window.top.document:window.document,a=d.getElementsByTagName("body")[0]||d.body;if(!a){try{d.write('<div id="'+h+'">.'+c.openTag+"/div>");b=d.getElementById(h)}catch(f){}}a=d.getElementsByTagName("body")[0]||d.body;if(a){a.insertBefore(i,a.firstChild);if(b){a.removeChild(b)}}},insertHTML:function(f,b,g,a,k){var l,m=document,j=this,p,o=m.createElement("span"),n,i;var c=["outlineStyle","none","borderStyle","none","padding","0px","margin","0px","visibility","visible"];var h="outline-style:none;border-style:none;padding:0px;margin:0px;visibility:visible;";if(!j.isDefined(a)){a=""}if(j.isString(f)&&(/[^\s]/).test(f)){f=f.toLowerCase().replace(/\s/g,"");p=j.openTag+f+' width="'+j.pluginSize+'" height="'+j.pluginSize+'" ';p+='style="'+h+'display:inline;" ';for(n=0;n<b.length;n=n+2){if(/[^\s]/.test(b[n+1])){p+=b[n]+'="'+b[n+1]+'" '}}p+=">";for(n=0;n<g.length;n=n+2){if(/[^\s]/.test(g[n+1])){p+=j.openTag+'param name="'+g[n]+'" value="'+g[n+1]+'" />'}}p+=a+j.openTag+"/"+f+">"}else{p=a}if(!j.div){i=m.getElementById(j.divID);if(i){j.div=i}else{j.div=m.createElement("div");j.div.id=j.divID}j.setStyle(j.div,c.concat(["width",j.divWidth+"px","height",(j.pluginSize+3)+"px","fontSize",(j.pluginSize+3)+"px","lineHeight",(j.pluginSize+3)+"px","verticalAlign","baseline","display","block"]));if(!i){j.setStyle(j.div,["position","absolute","right","0px","top","0px"]);j.insertDivInBody(j.div)}}if(j.div&&j.div.parentNode){j.setStyle(o,c.concat(["fontSize",(j.pluginSize+3)+"px","lineHeight",(j.pluginSize+3)+"px","verticalAlign","baseline","display","inline"]));try{o.innerHTML=p}catch(l){};try{j.div.appendChild(o)}catch(l){};return{span:o,winLoaded:j.winLoaded,tagName:f,outerHTML:p}}return{span:null,winLoaded:j.winLoaded,tagName:"",outerHTML:p}},Plugins:{quicktime:{mimeType:["video/quicktime","application/x-quicktimeplayer","image/x-macpaint","image/x-quicktime"],progID:"QuickTimeCheckObject.QuickTimeCheck.1",progID0:"QuickTime.QuickTime",classID:"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B",minIEver:7,HTML:'<param name="src" value="" /><param name="controller" value="false" />',getCodeBaseVersion:function(a){return'codebase="#version='+a+'"'},SEARCH:{min:0,max:0,match:0,digits:[16,128,128,0]},getVersion:function(c){var f=this,d=f.$,a=null,e=null,b;if(!d.isIE){if(d.hasMimeType(f.mimeType)){e=d.OS!=3?d.findNavPlugin("QuickTime.*Plug-?in",0):null;if(e&&e.name){a=d.getNum(e.name)}}}else{if(d.isStrNum(c)){b=c.split(d.splitNumRegx);if(b.length>3&&parseInt(b[3],10)>0){b[3]="9999"}c=b.join(",")}if(d.isStrNum(c)&&d.verIE>=f.minIEver&&f.canUseIsMin()>0){f.installed=f.isMin(c);f.getVersionDone=0;return}f.getVersionDone=1;if(!a&&d.verIE>=f.minIEver){a=f.CDBASE2VER(d.codebaseSearch(f))}if(!a){e=d.getAXO(f.progID);if(e&&e.QuickTimeVersion){a=e.QuickTimeVersion.toString(16);a=parseInt(a.charAt(0),16)+"."+parseInt(a.charAt(1),16)+"."+parseInt(a.charAt(2),16)}}}f.installed=a?1:(e?0:-1);f.version=d.formatNum(a,3)},cdbaseUpper:["7,60,0,0","0,0,0,0"],cdbaseLower:["7,50,0,0",null],cdbase2ver:[function(c,b){var a=b.split(c.$.splitNumRegx);return[a[0],a[1].charAt(0),a[1].charAt(1),a[2]].join(",")},null],CDBASE2VER:function(f){var e=this,c=e.$,b,a=e.cdbaseUpper,d=e.cdbaseLower;
17808if(f){f=c.formatNum(f);for(b=0;b<a.length;b++){if(a[b]&&c.compareNums(f,a[b])<0&&d[b]&&c.compareNums(f,d[b])>=0&&e.cdbase2ver[b]){return e.cdbase2ver[b](e,f)}}}return f},canUseIsMin:function(){var f=this,d=f.$,b,c=f.canUseIsMin,a=f.cdbaseUpper,e=f.cdbaseLower;if(!c.value){c.value=-1;for(b=0;b<a.length;b++){if(a[b]&&d.codebaseSearch(f,a[b])){c.value=1;break}if(e[b]&&d.codebaseSearch(f,e[b])){c.value=-1;break}}}f.SEARCH.match=c.value==1?1:0;return c.value},isMin:function(c){var b=this,a=b.$;return a.codebaseSearch(b,c)?0.7:-1}},flash:{mimeType:"application/x-shockwave-flash",progID:"ShockwaveFlash.ShockwaveFlash",classID:"clsid:D27CDB6E-AE6D-11CF-96B8-444553540000",getVersion:function(){var b=function(i){if(!i){return null}var e=/[\d][\d\,\.\s]*[rRdD]{0,1}[\d\,]*/.exec(i);return e?e[0].replace(/[rRdD\.]/g,",").replace(/\s/g,""):null};var j=this,g=j.$,k,h,l=null,c=null,a=null,f,m,d;if(!g.isIE){m=g.hasMimeType(j.mimeType);if(m){f=g.getDOMobj(g.insertHTML("object",["type",j.mimeType],[],"",j));try{l=g.getNum(f.GetVariable("$version"))}catch(k){}}if(!l){d=m?m.enabledPlugin:null;if(d&&d.description){l=b(d.description)}if(l){l=g.getPluginFileVersion(d,l)}}}else{for(h=15;h>2;h--){c=g.getAXO(j.progID+"."+h);if(c){a=h.toString();break}}if(!c){c=g.getAXO(j.progID)}if(a=="6"){try{c.AllowScriptAccess="always"}catch(k){return"6,0,21,0"}}try{l=b(c.GetVariable("$version"))}catch(k){}if(!l&&a){l=a}}j.installed=l?1:-1;j.version=g.formatNum(l);return true}},shockwave:{mimeType:"application/x-director",progID:"SWCtl.SWCtl",classID:"clsid:166B1BCA-3F9C-11CF-8075-444553540000",getVersion:function(){var a=null,b=null,g,f,d=this,c=d.$;if(!c.isIE){f=c.findNavPlugin("Shockwave\\s*for\\s*Director");if(f&&f.description&&c.hasMimeType(d.mimeType)){a=c.getNum(f.description)}if(a){a=c.getPluginFileVersion(f,a)}}else{try{b=c.getAXO(d.progID).ShockwaveVersion("")}catch(g){}if(c.isString(b)&&b.length>0){a=c.getNum(b)}else{if(c.getAXO(d.progID+".8")){a="8"}else{if(c.getAXO(d.progID+".7")){a="7"}else{if(c.getAXO(d.progID+".1")){a="6"}}}}}d.installed=a?1:-1;d.version=c.formatNum(a)}},zz:0}};PluginDetect.initScript();
17809
17810	var gArgCountErr='The "%%" function requires an even number of arguments.\nArguments should be in the form "atttributeName", "attributeValue", ...',gTagAttrs=null,gQTGeneratorVersion=1;function AC_QuickTimeVersion(){return gQTGeneratorVersion}function _QTComplain(a,b){b=b.replace("%%",a);alert(b)}function _QTAddAttribute(a,b,c){var d;d=gTagAttrs[a+b];null==d&&(d=gTagAttrs[b]);return null!=d?(0==b.indexOf(a)&&null==c&&(c=b.substring(a.length)),null==c&&(c=b),c+'="'+d+'" '):""}function _QTAddObjectAttr(a,b){if(0==a.indexOf("emb#"))return"";0==a.indexOf("obj#")&&null==b&&(b=a.substring(4));return _QTAddAttribute("obj#",a,b)}function _QTAddEmbedAttr(a,b){if(0==a.indexOf("obj#"))return"";0==a.indexOf("emb#")&&null==b&&(b=a.substring(4));return _QTAddAttribute("emb#",a,b)}function _QTAddObjectParam(a,b){var c,d="",e=b?" />":">";-1==a.indexOf("emb#")&&(c=gTagAttrs["obj#"+a],null==c&&(c=gTagAttrs[a]),0==a.indexOf("obj#")&&(a=a.substring(4)),null!=c&&(d='  <param name="'+a+'" value="'+c+'"'+e+"\n"));return d}function _QTDeleteTagAttrs(){for(var a=0;a<arguments.length;a++){var b=arguments[a];delete gTagAttrs[b];delete gTagAttrs["emb#"+b];delete gTagAttrs["obj#"+b]}}function _QTGenerate(a,b,c){if(4>c.length||0!=c.length%2)return _QTComplain(a,gArgCountErr),"";gTagAttrs=[];gTagAttrs.src=c[0];gTagAttrs.width=c[1];gTagAttrs.height=c[2];gTagAttrs.classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B";gTagAttrs.pluginspage="http://www.apple.com/quicktime/download/";a=c[3];if(null==a||""==a)a="6,0,2,0";gTagAttrs.codebase="http://www.apple.com/qtactivex/qtplugin.cab#version="+a;for(var d,e=4;e<c.length;e+=2)d=c[e].toLowerCase(),a=c[e+1],"name"==d||"id"==d?gTagAttrs.name=a:gTagAttrs[d]=a;c="<object "+_QTAddObjectAttr("classid")+_QTAddObjectAttr("width")+_QTAddObjectAttr("height")+_QTAddObjectAttr("codebase")+_QTAddObjectAttr("name","id")+_QTAddObjectAttr("tabindex")+_QTAddObjectAttr("hspace")+_QTAddObjectAttr("vspace")+_QTAddObjectAttr("border")+_QTAddObjectAttr("align")+_QTAddObjectAttr("class")+_QTAddObjectAttr("title")+_QTAddObjectAttr("accesskey")+_QTAddObjectAttr("noexternaldata")+">\n"+_QTAddObjectParam("src",b);e="  <embed "+_QTAddEmbedAttr("src")+_QTAddEmbedAttr("width")+_QTAddEmbedAttr("height")+_QTAddEmbedAttr("pluginspage")+_QTAddEmbedAttr("name")+_QTAddEmbedAttr("align")+_QTAddEmbedAttr("tabindex");_QTDeleteTagAttrs("src","width","height","pluginspage","classid","codebase","name","tabindex","hspace","vspace","border","align","noexternaldata","class","title","accesskey");for(d in gTagAttrs)a=gTagAttrs[d],null!=a&&(e+=_QTAddEmbedAttr(d),c+=_QTAddObjectParam(d,b));return c+e+"> </embed>\n</object>"}function QT_GenerateOBJECTText(){return _QTGenerate("QT_GenerateOBJECTText",!1,arguments)};
17811
17812
17813	/*
17814		jQuery hashchange event v1.3
17815		https://github.com/cowboy/jquery-hashchange
17816		Copyright (c) 2010 "Cowboy" Ben Alman
17817		Dual licensed under the MIT and GPL licenses.
17818	*/
17819	(function(){function e(a){a=a||location.href;return"#"+a.replace(/^[^#]*#?(.*)$/,"$1")}var k=document,b,f=$.event.special,p=k.documentMode,m="oniLightBoxHashChange"in window&&(void 0===p||7<p);$.fn.iLightBoxHashChange=function(a){return a?this.bind("iLightBoxHashChange",a):this.trigger("iLightBoxHashChange")};$.fn.iLightBoxHashChange.delay=50;f.iLightBoxHashChange=$.extend(f.iLightBoxHashChange,{setup:function(){if(m)return!1;$(b.start)},teardown:function(){if(m)return!1;$(b.stop)}});b=function(){function a(){var c=
17820	e(),d=f(l);c!==l?(n(l=c,d),$(window).trigger("iLightBoxHashChange")):d!==l&&(location.href=location.href.replace(/#.*/,"")+d);g=setTimeout(a,$.fn.iLightBoxHashChange.delay)}var h={},g,l=e(),b=function(c){return c},n=b,f=b;h.start=function(){g||a()};h.stop=function(){g&&clearTimeout(g);g=void 0};browser.msie&&!m&&function(){var c,d;h.start=function(){c||(d=(d=$.fn.iLightBoxHashChange.src)&&d+e(),c=$('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){d||n(e());a()}).attr("src",d||
17821	"javascript:0").insertAfter("body")[0].contentWindow,k.onpropertychange=function(){try{"title"===event.propertyName&&(c.document.title=k.title)}catch(a){}})};h.stop=b;f=function(){return e(c.location.href)};n=function(a,d){var b=c.document,e=$.fn.iLightBoxHashChange.domain;
17821a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})();
17822
17823	if (!Array.prototype.filter) {
17824		Array.prototype.filter = function(fun /*, thisp */ ) {
17825			"use strict";
17826
17827			if (this == null)
17828				throw new TypeError();
17829
17830			var t = Object(this);
17831			var len = t.length >>> 0;
17832			if (typeof fun != "function")
17833				throw new TypeError();
17834
17835			var res = [];
17836			var thisp = arguments[1];
17837			for (var i = 0; i < len; i++) {
17838				if (i in t) {
17839					var val = t[i]; // in case fun mutates this
17840					if (fun.call(thisp, val, i, t))
17841						res.push(val);
17842				}
17843			}
17844
17845			return res;
17846		};
17847	}
17848
17849	if (!Array.prototype.indexOf) {
17850		Array.prototype.indexOf = function(searchElement, fromIndex) {
17851			var k;
17852
17853			if (this == null) {
17854				throw new TypeError('"this" is null or not defined');
17855			}
17856
17857			var O = Object(this);
17858
17859			var len = O.length >>> 0;
17860
17861			if (len === 0) {
17862				return -1;
17863			}
17864
17865			var n = +fromIndex || 0;
17866
17867			if (abs(n) === Infinity) {
17868				n = 0;
17869			}
17870
17871			if (n >= len) {
17872				return -1;
17873			}
17874
17875			k = max(n >= 0 ? n : len - abs(n), 0);
17876
17877			while (k < len) {
17878				var kValue;
17879				if (k in O && O[k] === searchElement) {
17880					return k;
17881				}
17882				k++;
17883			}
17884			return -1;
17885		};
17886	}
17887
17888	if (!Array.prototype.lastIndexOf) {
17889		Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) {
17890			"use strict";
17891
17892			if (this == null)
17893				throw new TypeError();
17894
17895			var t = Object(this);
17896			var len = t.length >>> 0;
17897			if (len === 0)
17898				return -1;
17899
17900			var n = len;
17901			if (arguments.length > 1) {
17902				n = Number(arguments[1]);
17903				if (n != n)
17904					n = 0;
17905				else if (n != 0 && n != (1 / 0) && n != -(1 / 0))
17906					n = (n > 0 || -1) * floor(abs(n));
17907			}
17908
17909			var k = n >= 0 ? min(n, len - 1) : len - abs(n);
17910
17911			for (; k >= 0; k--) {
17912				if (k in t && t[k] === searchElement)
17913					return k;
17914			}
17915			return -1;
17916		};
17917	}
17918})(jQuery, this);
17919
17920/*!
17921 * lightgallery | 2.5.0 | June 13th 2022
17922 * http://www.lightgalleryjs.com/
17923 * Copyright (c) 2020 Sachin Neravath;
17924 * @license GPLv3
17925 */
17926
17927(function (global, factory) {
17928	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
17929	typeof define === 'function' && define.amd ? define(factory) :
17930	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory());
17931}(this, (function () { 'use strict';
17932
17933	/*! *****************************************************************************
17934	Copyright (c) Microsoft Corporation.
17935
17936	Permission to use, copy, modify, and/or distribute this software for any
17937	purpose with or without fee is hereby granted.
17938
17939	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
17940	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17941	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
17942	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17943	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17944	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17945	PERFORMANCE OF THIS SOFTWARE.
17946	***************************************************************************** */
17947
17948	var __assign = function() {
17949		__assign = Object.assign || function __assign(t) {
17950			for (var s, i = 1, n = arguments.length; i < n; i++) {
17951				s = arguments[i];
17952				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
17953			}
17954			return t;
17955		};
17956		return __assign.apply(this, arguments);
17957	};
17958
17959	function __spreadArrays() {
17960		for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
17961		for (var r = Array(s), k = 0, i = 0; i < il; i++)
17962			for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
17963				r[k] = a[j];
17964		return r;
17965	}
17966
17967	/**
17968	 * List of lightGallery events
17969	 * All events should be documented here
17970	 * Below interfaces are used to build the website documentations
17971	 * */
17972	var lGEvents = {
17973		afterAppendSlide: 'lgAfterAppendSlide',
17974		init: 'lgInit',
17975		hasVideo: 'lgHasVideo',
17976		containerResize: 'lgContainerResize',
17977		updateSlides: 'lgUpdateSlides',
17978		afterAppendSubHtml: 'lgAfterAppendSubHtml',
17979		beforeOpen: 'lgBeforeOpen',
17980		afterOpen: 'lgAfterOpen',
17981		slideItemLoad: 'lgSlideItemLoad',
17982		beforeSlide: 'lgBeforeSlide',
17983		afterSlide: 'lgAfterSlide',
17984		posterClick: 'lgPosterClick',
17985		dragStart: 'lgDragStart',
17986		dragMove: 'lgDragMove',
17987		dragEnd: 'lgDragEnd',
17988		beforeNextSlide: 'lgBeforeNextSlide',
17989		beforePrevSlide: 'lgBeforePrevSlide',
17990		beforeClose: 'lgBeforeClose',
17991		afterClose: 'lgAfterClose',
17992		rotateLeft: 'lgRotateLeft',
17993		rotateRight: 'lgRotateRight',
17994		flipHorizontal: 'lgFlipHorizontal',
17995		flipVertical: 'lgFlipVertical',
17996		autoplay: 'lgAutoplay',
17997		autoplayStart: 'lgAutoplayStart',
17998		autoplayStop: 'lgAutoplayStop',
17999	};
18000
18001	var lightGalleryCoreSettings = {
18002		mode: 'lg-slide',
18003		easing: 'ease',
18004		speed: 400,
18005		licenseKey: '0000-0000-000-0000',
18006		height: '100%',
18007		width: '100%',
18008		addClass: '',
18009		startClass: 'lg-start-zoom',
18010		backdropDuration: 300,
18011		container: '',
18012		startAnimationDuration: 400,
18013		zoomFromOrigin: true,
18014		hideBarsDelay: 0,
18015		showBarsAfter: 10000,
18016		slideDelay: 0,
18017		supportLegacyBrowser: true,
18018		allowMediaOverlap: false,
18019		videoMaxSize: '1280-720',
18020		loadYouTubePoster: true,
18021		defaultCaptionHeight: 0,
18022		ariaLabelledby: '',
18023		ariaDescribedby: '',
18024		resetScrollPosition: true,
18025		hideScrollbar: false,
18026		closable: true,
18027		swipeToClose: true,
18028		closeOnTap: true,
18029		showCloseIcon: true,
18030		showMaximizeIcon: false,
18031		loop: true,
18032		escKey: true,
18033		keyPress: true,
18034		trapFocus: true,
18035		controls: true,
18036		slideEndAnimation: true,
18037		hideControlOnEnd: false,
vendor: 17,869 bytes, lines 18038-18657
18038		mousewheel: false,
18039		getCaptionFromTitleOrAlt: true,
18040		appendSubHtmlTo: '.lg-sub-html',
18041		subHtmlSelectorRelative: false,
18042		preload: 2,
18043		numberOfSlideItemsInDom: 10,
18044		selector: '',
18045		selectWithin: '',
18046		nextHtml: '',
18047		prevHtml: '',
18048		index: 0,
18049		iframeWidth: '100%',
18050		iframeHeight: '100%',
18051		iframeMaxWidth: '100%',
18052		iframeMaxHeight: '100%',
18053		download: true,
18054		counter: true,
18055		appendCounterTo: '.lg-toolbar',
18056		swipeThreshold: 50,
18057		enableSwipe: true,
18058		enableDrag: true,
18059		dynamic: false,
18060		dynamicEl: [],
18061		extraProps: [],
18062		exThumbImage: '',
18063		isMobile: undefined,
18064		mobileSettings: {
18065			controls: false,
18066			showCloseIcon: false,
18067			download: false,
18068		},
18069		plugins: [],
18070		strings: {
18071			closeGallery: 'Close gallery',
18072			toggleMaximize: 'Toggle maximize',
18073			previousSlide: 'Previous slide',
18074			nextSlide: 'Next slide',
18075			download: 'Download',
18076			playVideo: 'Play video',
18077		},
18078	};
18079
18080	function initLgPolyfills() {
18081		(function () {
18082			if (typeof window.CustomEvent === 'function')
18083				return false;
18084			function CustomEvent(event, params) {
18085				params = params || {
18086					bubbles: false,
18087					cancelable: false,
18088					detail: null,
18089				};
18090				var evt = document.createEvent('CustomEvent');
18091				evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
18092				return evt;
18093			}
18094			window.CustomEvent = CustomEvent;
18095		})();
18096		(function () {
18097			if (!Element.prototype.matches) {
18098				Element.prototype.matches =
18099					Element.prototype.msMatchesSelector ||
18100						Element.prototype.webkitMatchesSelector;
18101			}
18102		})();
18103	}
18104	var lgQuery = /** @class */ (function () {
18105		function lgQuery(selector) {
18106			this.cssVenderPrefixes = [
18107				'TransitionDuration',
18108				'TransitionTimingFunction',
18109				'Transform',
18110				'Transition',
18111			];
18112			this.selector = this._getSelector(selector);
18113			this.firstElement = this._getFirstEl();
18114			return this;
18115		}
18116		lgQuery.generateUUID = function () {
18117			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
18118				var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
18119				return v.toString(16);
18120			});
18121		};
18122		lgQuery.prototype._getSelector = function (selector, context) {
18123			if (context === void 0) { context = document; }
18124			if (typeof selector !== 'string') {
18125				return selector;
18126			}
18127			context = context || document;
18128			var fl = selector.substring(0, 1);
18129			if (fl === '#') {
18130				return context.querySelector(selector);
18131			}
18132			else {
18133				return context.querySelectorAll(selector);
18134			}
18135		};
18136		lgQuery.prototype._each = function (func) {
18137			if (!this.selector) {
18138				return this;
18139			}
18140			if (this.selector.length !== undefined) {
18141				[].forEach.call(this.selector, func);
18142			}
18143			else {
18144				func(this.selector, 0);
18145			}
18146			return this;
18147		};
18148		lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) {
18149			// prettier-ignore
18150			var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) {
18151				return group1.toUpperCase();
18152			});
18153			if (this.cssVenderPrefixes.indexOf(property) !== -1) {
18154				el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value;
18155				el.style['webkit' + property] = value;
18156				el.style['moz' + property] = value;
18157				el.style['ms' + property] = value;
18158				el.style['o' + property] = value;
18159			}
18160			else {
18161				el.style[property] = value;
18162			}
18163		};
18164		lgQuery.prototype._getFirstEl = function () {
18165			if (this.selector && this.selector.length !== undefined) {
18166				return this.selector[0];
18167			}
18168			else {
18169				return this.selector;
18170			}
18171		};
18172		lgQuery.prototype.isEventMatched = function (event, eventName) {
18173			var eventNamespace = eventName.split('.');
18174			return event
18175				.split('.')
18176				.filter(function (e) { return e; })
18177				.every(function (e) {
18178				return eventNamespace.indexOf(e) !== -1;
18179			});
18180		};
18181		lgQuery.prototype.attr = function (attr, value) {
18182			if (value === undefined) {
18183				if (!this.firstElement) {
18184					return '';
18185				}
18186				return this.firstElement.getAttribute(attr);
18187			}
18188			this._each(function (el) {
18189				el.setAttribute(attr, value);
18190			});
18191			return this;
18192		};
18193		lgQuery.prototype.find = function (selector) {
18194			return $LG(this._getSelector(selector, this.selector));
18195		};
18196		lgQuery.prototype.first = function () {
18197			if (this.selector && this.selector.length !== undefined) {
18198				return $LG(this.selector[0]);
18199			}
18200			else {
18201				return $LG(this.selector);
18202			}
18203		};
18204		lgQuery.prototype.eq = function (index) {
18205			return $LG(this.selector[index]);
18206		};
18207		lgQuery.prototype.parent = function () {
18208			return $LG(this.selector.parentElement);
18209		};
18210		lgQuery.prototype.get = function () {
18211			return this._getFirstEl();
18212		};
18213		lgQuery.prototype.removeAttr = function (attributes) {
18214			var attrs = attributes.split(' ');
18215			this._each(function (el) {
18216				attrs.forEach(function (attr) { return el.removeAttribute(attr); });
18217			});
18218			return this;
18219		};
18220		lgQuery.prototype.wrap = function (className) {
18221			if (!this.firstElement) {
18222				return this;
18223			}
18224			var wrapper = document.createElement('div');
18225			wrapper.className = className;
18226			this.firstElement.parentNode.insertBefore(wrapper, this.firstElement);
18227			this.firstElement.parentNode.removeChild(this.firstElement);
18228			wrapper.appendChild(this.firstElement);
18229			return this;
18230		};
18231		lgQuery.prototype.addClass = function (classNames) {
18232			if (classNames === void 0) { classNames = ''; }
18233			this._each(function (el) {
18234				// IE doesn't support multiple arguments
18235				classNames.split(' ').forEach(function (className) {
18236					if (className) {
18237						el.classList.add(className);
18238					}
18239				});
18240			});
18241			return this;
18242		};
18243		lgQuery.prototype.removeClass = function (classNames) {
18244			this._each(function (el) {
18245				// IE doesn't support multiple arguments
18246				classNames.split(' ').forEach(function (className) {
18247					if (className) {
18248						el.classList.remove(className);
18249					}
18250				});
18251			});
18252			return this;
18253		};
18254		lgQuery.prototype.hasClass = function (className) {
18255			if (!this.firstElement) {
18256				return false;
18257			}
18258			return this.firstElement.classList.contains(className);
18259		};
18260		lgQuery.prototype.hasAttribute = function (attribute) {
18261			if (!this.firstElement) {
18262				return false;
18263			}
18264			return this.firstElement.hasAttribute(attribute);
18265		};
18266		lgQuery.prototype.toggleClass = function (className) {
18267			if (!this.firstElement) {
18268				return this;
18269			}
18270			if (this.hasClass(className)) {
18271				this.removeClass(className);
18272			}
18273			else {
18274				this.addClass(className);
18275			}
18276			return this;
18277		};
18278		lgQuery.prototype.css = function (property, value) {
18279			var _this = this;
18280			this._each(function (el) {
18281				_this._setCssVendorPrefix(el, property, value);
18282			});
18283			return this;
18284		};
18285		// Need to pass separate namespaces for separate elements
18286		lgQuery.prototype.on = function (events, listener) {
18287			var _this = this;
18288			if (!this.selector) {
18289				return this;
18290			}
18291			events.split(' ').forEach(function (event) {
18292				if (!Array.isArray(lgQuery.eventListeners[event])) {
18293					lgQuery.eventListeners[event] = [];
18294				}
18295				lgQuery.eventListeners[event].push(listener);
18296				_this.selector.addEventListener(event.split('.')[0], listener);
18297			});
18298			return this;
18299		};
18300		// @todo - test this
18301		lgQuery.prototype.once = function (event, listener) {
18302			var _this = this;
18303			this.on(event, function () {
18304				_this.off(event);
18305				listener(event);
18306			});
18307			return this;
18308		};
18309		lgQuery.prototype.off = function (event) {
18310			var _this = this;
18311			if (!this.selector) {
18312				return this;
18313			}
18314			Object.keys(lgQuery.eventListeners).forEach(function (eventName) {
18315				if (_this.isEventMatched(event, eventName)) {
18316					lgQuery.eventListeners[eventName].forEach(function (listener) {
18317						_this.selector.removeEventListener(eventName.split('.')[0], listener);
18318					});
18319					lgQuery.eventListeners[eventName] = [];
18320				}
18321			});
18322			return this;
18323		};
18324		lgQuery.prototype.trigger = function (event, detail) {
18325			if (!this.firstElement) {
18326				return this;
18327			}
18328			var customEvent = new CustomEvent(event.split('.')[0], {
18329				detail: detail || null,
18330			});
18331			this.firstElement.dispatchEvent(customEvent);
18332			return this;
18333		};
18334		// Does not support IE
18335		lgQuery.prototype.load = function (url) {
18336			var _this = this;
18337			fetch(url)
18338				.then(function (res) { return res.text(); })
18339				.then(function (html) {
18340				_this.selector.innerHTML = html;
18341			});
18342			return this;
18343		};
18344		lgQuery.prototype.html = function (html) {
18345			if (html === undefined) {
18346				if (!this.firstElement) {
18347					return '';
18348				}
18349				return this.firstElement.innerHTML;
18350			}
18351			this._each(function (el) {
18352				el.innerHTML = html;
18353			});
18354			return this;
18355		};
18356		lgQuery.prototype.append = function (html) {
18357			this._each(function (el) {
18358				if (typeof html === 'string') {
18359					el.insertAdjacentHTML('beforeend', html);
18360				}
18361				else {
18362					el.appendChild(html);
18363				}
18364			});
18365			return this;
18366		};
18367		lgQuery.prototype.prepend = function (html) {
18368			this._each(function (el) {
18369				el.insertAdjacentHTML('afterbegin', html);
18370			});
18371			return this;
18372		};
18373		lgQuery.prototype.remove = function () {
18374			this._each(function (el) {
18375				el.parentNode.removeChild(el);
18376			});
18377			return this;
18378		};
18379		lgQuery.prototype.empty = function () {
18380			this._each(function (el) {
18381				el.innerHTML = '';
18382			});
18383			return this;
18384		};
18385		lgQuery.prototype.scrollTop = function (scrollTop) {
18386			if (scrollTop !== undefined) {
18387				document.body.scrollTop = scrollTop;
18388				document.documentElement.scrollTop = scrollTop;
18389				return this;
18390			}
18391			else {
18392				return (window.pageYOffset ||
18393					document.documentElement.scrollTop ||
18394					document.body.scrollTop ||
18395					0);
18396			}
18397		};
18398		lgQuery.prototype.scrollLeft = function (scrollLeft) {
18399			if (scrollLeft !== undefined) {
18400				document.body.scrollLeft = scrollLeft;
18401				document.documentElement.scrollLeft = scrollLeft;
18402				return this;
18403			}
18404			else {
18405				return (window.pageXOffset ||
18406					document.documentElement.scrollLeft ||
18407					document.body.scrollLeft ||
18408					0);
18409			}
18410		};
18411		lgQuery.prototype.offset = function () {
18412			if (!this.firstElement) {
18413				return {
18414					left: 0,
18415					top: 0,
18416				};
18417			}
18418			var rect = this.firstElement.getBoundingClientRect();
18419			var bodyMarginLeft = $LG('body').style().marginLeft;
18420			// Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value
18421			return {
18422				left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(),
18423				top: rect.top + this.scrollTop(),
18424			};
18425		};
18426		lgQuery.prototype.style = function () {
18427			if (!this.firstElement) {
18428				return {};
18429			}
18430			return (this.firstElement.currentStyle ||
18431				window.getComputedStyle(this.firstElement));
18432		};
18433		// Width without padding and border even if box-sizing is used.
18434		lgQuery.prototype.width = function () {
18435			var style = this.style();
18436			return (this.firstElement.clientWidth -
18437				parseFloat(style.paddingLeft) -
18438				parseFloat(style.paddingRight));
18439		};
18440		// Height without padding and border even if box-sizing is used.
18441		lgQuery.prototype.height = function () {
18442			var style = this.style();
18443			return (this.firstElement.clientHeight -
18444				parseFloat(style.paddingTop) -
18445				parseFloat(style.paddingBottom));
18446		};
18447		lgQuery.eventListeners = {};
18448		return lgQuery;
18449	}());
18450	function $LG(selector) {
18451		initLgPolyfills();
18452		return new lgQuery(selector);
18453	}
18454
18455	var defaultDynamicOptions = [
18456		'src',
18457		'sources',
18458		'subHtml',
18459		'subHtmlUrl',
18460		'html',
18461		'video',
18462		'poster',
18463		'slideName',
18464		'responsive',
18465		'srcset',
18466		'sizes',
18467		'iframe',
18468		'downloadUrl',
18469		'download',
18470		'width',
18471		'facebookShareUrl',
18472		'tweetText',
18473		'iframeTitle',
18474		'twitterShareUrl',
18475		'pinterestShareUrl',
18476		'pinterestText',
18477		'fbHtml',
18478		'disqusIdentifier',
18479		'disqusUrl',
18480	];
18481	// Convert html data-attribute to camalcase
18482	function convertToData(attr) {
18483		// FInd a way for lgsize
18484		if (attr === 'href') {
18485			return 'src';
18486		}
18487		attr = attr.replace('data-', '');
18488		attr = attr.charAt(0).toLowerCase() + attr.slice(1);
18489		attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
18490		return attr;
18491	}
18492	var utils = {
18493		/**
18494		 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option
18495		 */
18496		//Uncode edit ##START##
18497		getSize: function (el, container, spacing, defaultLgSize, galleryItem) {
18498		// getSize: function (el, container, spacing, defaultLgSize) {
18499		//Uncode edit ##END##
18500			if (spacing === void 0) { spacing = 0; }
18501			var LGel = $LG(el);
18502			var lgSize = LGel.attr('data-lg-size') || defaultLgSize;
18503			//Uncode edit ##START##
18504			if ( typeof galleryItem.size && galleryItem.size != null ) {
18505				lgSize = galleryItem.size;
18506			}
18507			//Uncode edit ##END##
18508			if (!lgSize) {
18509				return;
18510			}
18511			var isResponsiveSizes = lgSize.split(',');
18512			// if at-least two viewport sizes are available
18513			if (isResponsiveSizes[1]) {
18514				var wWidth = window.innerWidth;
18515				for (var i = 0; i < isResponsiveSizes.length; i++) {
18516					var size_1 = isResponsiveSizes[i];
18517					var responsiveWidth = parseInt(size_1.split('-')[2], 10);
18518					if (responsiveWidth > wWidth) {
18519						lgSize = size_1;
18520						break;
18521					}
18522					// take last item as last option
18523					if (i === isResponsiveSizes.length - 1) {
18524						lgSize = size_1;
18525					}
18526				}
18527			}
18528			var size = lgSize.split('-');
18529			var width = parseInt(size[0], 10);
18530			var height = parseInt(size[1], 10);
18531			var cWidth = container.width();
18532			var cHeight = container.height() - spacing;
18533			var maxWidth = Math.min(cWidth, width);
18534			var maxHeight = Math.min(cHeight, height);
18535			var ratio = Math.min(maxWidth / width, maxHeight / height);
18536			return { width: width * ratio, height: height * ratio };
18537		},
18538		/**
18539		 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option
18540		 * @param {jQuery Element}
18541		 * @returns {String} Transform CSS string
18542		 */
18543		getTransform: function (el, container, top, bottom, imageSize) {
18544			if (!imageSize) {
18545				return;
18546			}
18547			var LGel = $LG(el).find('img').first();
18548			if (!LGel.get()) {
18549				return;
18550			}
18551			var containerRect = container.get().getBoundingClientRect();
18552			var wWidth = containerRect.width;
18553			// using innerWidth to include mobile safari bottom bar
18554			var wHeight = container.height() - (top + bottom);
18555			var elWidth = LGel.width();
18556			var elHeight = LGel.height();
18557			var elStyle = LGel.style();
18558			var x = (wWidth - elWidth) / 2 -
18559				LGel.offset().left +
18560				(parseFloat(elStyle.paddingLeft) || 0) +
18561				(parseFloat(elStyle.borderLeft) || 0) +
18562				$LG(window).scrollLeft() +
18563				containerRect.left;
18564			var y = (wHeight - elHeight) / 2 -
18565				LGel.offset().top +
18566				(parseFloat(elStyle.paddingTop) || 0) +
18567				(parseFloat(elStyle.borderTop) || 0) +
18568				$LG(window).scrollTop() +
18569				top;
18570			var scX = elWidth / imageSize.width;
18571			var scY = elHeight / imageSize.height;
18572			var transform = 'translate3d(' +
18573				(x *= -1) +
18574				'px, ' +
18575				(y *= -1) +
18576				'px, 0) scale3d(' +
18577				scX +
18578				', ' +
18579				scY +
18580				', 1)';
18581			return transform;
18582		},
18583		getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) {
18584			var title = iframeTitle ? 'title="' + iframeTitle + '"' : '';
18585			return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:" + iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n                    <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\"  allowfullscreen=\"true\"></iframe>\n                </div>";
18586		},
18587		getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) {
18588			var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : '';
18589			var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : '';
18590			var imgMarkup = "<img " + altAttr + " " + srcsetAttr + "  " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />";
18591			var sourceTag = '';
18592			if (sources) {
18593				var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources;
18594				sourceTag = sourceObj.map(function (source) {
18595					var attrs = '';
18596					Object.keys(source).forEach(function (key) {
18597						// Do not remove the first space as it is required to separate the attributes
18598						attrs += " " + key + "=\"" + source[key] + "\"";
18599					});
18600					return "<source " + attrs + "></source>";
18601				});
18602			}
18603			return "" + sourceTag + imgMarkup;
18604		},
18605		// Get src from responsive src
18606		getResponsiveSrc: function (srcItms) {
18607			var rsWidth = [];
18608			var rsSrc = [];
18609			var src = '';
18610			for (var i = 0; i < srcItms.length; i++) {
18611				var _src = srcItms[i].split(' ');
18612				// Manage empty space
18613				if (_src[0] === '') {
18614					_src.splice(0, 1);
18615				}
18616				rsSrc.push(_src[0]);
18617				rsWidth.push(_src[1]);
18618			}
18619			var wWidth = window.innerWidth;
18620			for (var j = 0; j < rsWidth.length; j++) {
18621				if (parseInt(rsWidth[j], 10) > wWidth) {
18622					src = rsSrc[j];
18623					break;
18624				}
18625			}
18626			return src;
18627		},
18628		isImageLoaded: function (img) {
18629			if (!img)
18630				return false;
18631			// During the onload event, IE correctly identifies any images that
18632			// weren’t downloaded as not complete. Others should too. Gecko-based
18633			// browsers act like NS4 in that they report this incorrectly.
18634			if (!img.complete) {
18635				return false;
18636			}
18637			// However, they do have two very useful properties: naturalWidth and
18638			// naturalHeight. These give the true size of the image. If it failed
18639			// to load, either of these should be zero.
18640			if (img.naturalWidth === 0) {
18641				return false;
18642			}
18643			// No other way of checking: assume it’s ok.
18644			return true;
18645		},
18646		getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) {
18647			var videoClass = '';
18648			if (_isVideo && _isVideo.youtube) {
18649				videoClass = 'lg-has-youtube';
18650			}
18651			else if (_isVideo && _isVideo.vimeo) {
18652				videoClass = 'lg-has-vimeo';
18653			}
18654			else {
18655				videoClass = 'lg-has-html5';
18656			}
18657			return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n                <div class=\"lg-video-play-button\">
18657\n                <svg\n                    viewBox=\"0 0 20 20\"\n                    preserveAspectRatio=\"xMidYMid\"\n                    focusable=\"false\"\n                    aria-labelledby=\"" + playVideoString + "\"\n                    role=\"img\"\n                    class=\"lg-video-play-icon\"\n                >\n                    <title>" + playVideoString + "</title>\n                    <polygon class=\"lg-video-play-icon-inner\" points=\"1,0 20,10 1,20\"></polygon>\n                </svg>\n                <svg class=\"lg-video-play-icon-bg\" viewBox=\"0 0 50 50\" focusable=\"false\">\n                    <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle></svg>\n                <svg class=\"lg-video-play-icon-circle\" viewBox=\"0 0 50 50\" focusable=\"false\">\n                    <circle cx=\"50%\" cy=\"50%\" r=\"20\"></circle>\n                </svg>\n            </div>\n            " + (dummyImg || '') + "\n            <img class=\"lg-object lg-video-poster\" src=\"" + _poster + "\" />\n        </div>";
18658		},
18659		getFocusableElements: function (container) {
18660			var elements = container.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])');
18661			var visibleElements = [].filter.call(elements, function (element) {
18662				var style = window.getComputedStyle(element);
18663				return style.display !== 'none' && style.visibility !== 'hidden';
18664			});
18665			return visibleElements;
18666		},
18667		/**
18668		 * @desc Create dynamic elements array from gallery items when dynamic option is false
18669		 * It helps to avoid frequent DOM interaction
18670		 * and avoid multiple checks for dynamic elments
18671		 *
18672		 * @returns {Array} dynamicEl
18673		 */
18674		getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) {
18675			var dynamicElements = [];
18676			var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps);
18677			[].forEach.call(items, function (item) {
18678				var dynamicEl = {};
18679				for (var i = 0; i < item.attributes.length; i++) {
18680					var attr = item.attributes[i];
18681					if (attr.specified) {
18682						var dynamicAttr = convertToData(attr.name);
18683						var label = '';
18684						if (availableDynamicOptions.indexOf(dynamicAttr) > -1) {
18685							label = dynamicAttr;
18686						}
18687						if (label) {
18688							dynamicEl[label] = attr.value;
18689						}
18690					}
18691				}
18692				var currentItem = $LG(item);
18693				var alt = currentItem.find('img').first().attr('alt') || currentItem.attr('data-alt');
18694				var title = currentItem.attr('title');
18695				//Uncode edit ##START##
18696				// var thumb = exThumbImage
18697				var thumb = exThumbImage && currentItem.attr(exThumbImage)
18698				//Uncode edit ##END##
18699					? currentItem.attr(exThumbImage)
18700					: currentItem.find('img').first().attr('src');
18701				dynamicEl.thumb = thumb;
18702				//Uncode edit ##START##
18703				if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) {
18704					// dynamicEl.subHtml = title || alt || '';
18705					dynamicEl.subHtml = title || '';
18706				}
18707				// dynamicEl.alt = alt || title || '';
18708				dynamicEl.alt = alt || title;
18709				var inlineType = currentItem.attr('data-type');
18710				dynamicEl.type = inlineType;
18711				//Uncode edit ##END##
18712				dynamicElements.push(dynamicEl);
18713			});
18714			return dynamicElements;
18715		},
18716		isMobile: function () {
18717			return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
18718		},
18719		/**
18720		 * @desc Check the given src is video
18721		 * @param {String} src
18722		 * @return {Object} video type
18723		 * Ex:{ youtube  :  ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] }
18724		 *
18725		 * @todo - this information can be moved to dynamicEl to avoid frequent calls
18726		 */
18727		isVideo: function (src, isHTML5VIdeo, index) {
18728			if (!src || src.match(/\.(mp4|m4v|ogg|webm)$/) ) {
18729				if (isHTML5VIdeo) {
18730					return {
18731						html5: true,
18732					};
18733				}
18734				else {
18735					console.warn('lightGallery :- data-src is not provided on slide item ' +
18736						(index + 1) +
18737						'. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/');
18738					return;
18739				}
18740			}
18741			var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i);
18742			var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i);
18743			var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/);
18744			if (youtube) {
18745				return {
18746					youtube: youtube,
18747				};
18748			}
18749			else if (vimeo) {
18750				return {
18751					vimeo: vimeo,
18752				};
18753			}
18754			else if (wistia) {
18755				return {
18756					wistia: wistia,
18757				};
18758			}
18759		},
18760	};
18761
18762	// @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio
18763	// @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html
18764	// Unique id for each gallery
18765	var lgId = 0;
18766	var LightGallery = /** @class */ (function () {
18767		function LightGallery(element, options) {
18768			this.lgOpened = false;
vendor: 26,259 bytes, lines 18769-19448
18769			this.index = 0;
18770			// lightGallery modules
18771			this.plugins = [];
18772			// false when lightGallery load first slide content;
18773			this.lGalleryOn = false;
18774			// True when a slide animation is in progress
18775			this.lgBusy = false;
18776			this.currentItemsInDom = [];
18777			// Scroll top value before lightGallery is opened
18778			this.prevScrollTop = 0;
18779			this.bodyPaddingRight = 0;
18780			this.isDummyImageRemoved = false;
18781			this.dragOrSwipeEnabled = false;
18782			this.mediaContainerPosition = {
18783				top: 0,
18784				bottom: 0,
18785			};
18786			if (!element) {
18787				return this;
18788			}
18789			lgId++;
18790			this.lgId = lgId;
18791			this.el = element;
18792			this.LGel = $LG(element);
18793			this.generateSettings(options);
18794			this.buildModules();
18795			// When using dynamic mode, ensure dynamicEl is an array
18796			if (this.settings.dynamic &&
18797				this.settings.dynamicEl !== undefined &&
18798				!Array.isArray(this.settings.dynamicEl)) {
18799				throw 'When using dynamic mode, you must also define dynamicEl as an Array.';
18800			}
18801			this.galleryItems = this.getItems();
18802			this.normalizeSettings();
18803			// Gallery items
18804			this.init();
18805			//Uncode edit ##START##
18806			// this.validateLicense();
18807			//Uncode edit ##END##
18808			return this;
18809		}
18810		LightGallery.prototype.generateSettings = function (options) {
18811			// lightGallery settings
18812			this.settings = __assign(__assign({}, lightGalleryCoreSettings), options);
18813			if (this.settings.isMobile &&
18814				typeof this.settings.isMobile === 'function'
18815				? this.settings.isMobile()
18816				: utils.isMobile()) {
18817				var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings);
18818				this.settings = __assign(__assign({}, this.settings), mobileSettings);
18819			}
18820		};
18821		LightGallery.prototype.normalizeSettings = function () {
18822			if (this.settings.slideEndAnimation) {
18823				this.settings.hideControlOnEnd = false;
18824			}
18825			if (!this.settings.closable) {
18826				this.settings.swipeToClose = false;
18827			}
18828			// And reset it on close to get the correct value next time
18829			this.zoomFromOrigin = this.settings.zoomFromOrigin;
18830			// At the moment, Zoom from image doesn't support dynamic options
18831			// @todo add zoomFromOrigin support for dynamic images
18832			if (this.settings.dynamic) {
18833				this.zoomFromOrigin = false;
18834			}
18835			if (!this.settings.container) {
18836				this.settings.container = document.body;
18837			}
18838			// settings.preload should not be grater than $item.length
18839			this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length);
18840		};
18841		LightGallery.prototype.init = function () {
18842			var _this = this;
18843			this.addSlideVideoInfo(this.galleryItems);
18844			this.buildStructure();
18845			this.LGel.trigger(lGEvents.init, {
18846				instance: this,
18847			});
18848			if (this.settings.keyPress) {
18849				this.keyPress();
18850			}
18851			setTimeout(function () {
18852				_this.enableDrag();
18853				_this.enableSwipe();
18854				_this.triggerPosterClick();
18855			}, 50);
18856			this.arrow();
18857			if (this.settings.mousewheel) {
18858				this.mousewheel();
18859			}
18860			if (!this.settings.dynamic) {
18861				this.openGalleryOnItemClick();
18862			}
18863		};
18864		LightGallery.prototype.openGalleryOnItemClick = function () {
18865			var _this = this;
18866			var _loop_1 = function (index) {
18867				var element = this_1.items[index];
18868				var $element = $LG(element);
18869				// Using different namespace for click because click event should not unbind if selector is same object('this')
18870				// @todo manage all event listners - should have namespace that represent element
18871				var uuid = lgQuery.generateUUID();
18872				$element
18873					.attr('data-lg-id', uuid)
18874					.on("click.lgcustom-item-" + uuid, function (e) {
18875					e.preventDefault();
18876					var currentItemIndex = _this.settings.index || index;
18877					_this.openGallery(currentItemIndex, element);
18878				});
18879			};
18880			var this_1 = this;
18881			// Using for loop instead of using bubbling as the items can be any html element.
18882			for (var index = 0; index < this.items.length; index++) {
18883				_loop_1(index);
18884			}
18885		};
18886		/**
18887		 * Module constructor
18888		 * Modules are build incrementally.
18889		 * Gallery should be opened only once all the modules are initialized.
18890		 * use moduleBuildTimeout to make sure this
18891		 */
18892		LightGallery.prototype.buildModules = function () {
18893			var _this = this;
18894			this.settings.plugins.forEach(function (plugin) {
18895				_this.plugins.push(new plugin(_this, $LG));
18896			});
18897		};
18898		LightGallery.prototype.validateLicense = function () {
18899			if (!this.settings.licenseKey) {
18900				console.warn('Please provide a valid license key');
18901			}
18902			else if (this.settings.licenseKey === '0000-0000-000-0000') {
18903				console.warn("lightGallery: " + this.settings.licenseKey + " license key is not valid for production use");
18904			}
18905		};
18906		LightGallery.prototype.getSlideItem = function (index) {
18907			return $LG(this.getSlideItemId(index));
18908		};
18909		LightGallery.prototype.getSlideItemId = function (index) {
18910			return "#lg-item-" + this.lgId + "-" + index;
18911		};
18912		LightGallery.prototype.getIdName = function (id) {
18913			return id + "-" + this.lgId;
18914		};
18915		LightGallery.prototype.getElementById = function (id) {
18916			return $LG("#" + this.getIdName(id));
18917		};
18918		LightGallery.prototype.manageSingleSlideClassName = function () {
18919			if (this.galleryItems.length < 2) {
18920				this.outer.addClass('lg-single-item');
18921			}
18922			else {
18923				this.outer.removeClass('lg-single-item');
18924			}
18925		};
18926		LightGallery.prototype.buildStructure = function () {
18927			var _this = this;
18928			var container = this.$container && this.$container.get();
18929			if (container) {
18930				return;
18931			}
18932			var controls = '';
18933			var subHtmlCont = '';
18934			// Create controls
18935			if (this.settings.controls) {
18936				controls = "<button type=\"button\" id=\"" + this.getIdName('lg-prev') + "\" aria-label=\"" + this.settings.strings['previousSlide'] + "\" class=\"lg-prev lg-icon\"> " + this.settings.prevHtml + " </button>\n                <button type=\"button\" id=\"" + this.getIdName('lg-next') + "\" aria-label=\"" + this.settings.strings['nextSlide'] + "\" class=\"lg-next lg-icon\"> " + this.settings.nextHtml + " </button>";
18937			}
18938			if (this.settings.appendSubHtmlTo !== '.lg-item') {
18939				subHtmlCont =
18940					'<div class="lg-sub-html" role="status" aria-live="polite"></div>';
18941			}
18942			var addClasses = '';
18943			if (this.settings.allowMediaOverlap) {
18944				// Do not remove space before last single quote
18945				addClasses += 'lg-media-overlap ';
18946			}
18947			var ariaLabelledby = this.settings.ariaLabelledby
18948				? 'aria-labelledby="' + this.settings.ariaLabelledby + '"'
18949				: '';
18950			var ariaDescribedby = this.settings.ariaDescribedby
18951				? 'aria-describedby="' + this.settings.ariaDescribedby + '"'
18952				: '';
18953			var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : '');
18954			var closeIcon = this.settings.closable && this.settings.showCloseIcon
18955				? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>"
18956				: '';
18957			var maximizeIcon = this.settings.showMaximizeIcon
18958				? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>"
18959				: '';
18960			var template = "\n        <div class=\"" + containerClassName + "\" id=\"" + this.getIdName('lg-container') + "\" tabindex=\"-1\" aria-modal=\"true\" " + ariaLabelledby + " " + ariaDescribedby + " role=\"dialog\"\n        >\n            <div id=\"" + this.getIdName('lg-backdrop') + "\" class=\"lg-backdrop\"></div>\n\n            <div id=\"" + this.getIdName('lg-outer') + "\" class=\"lg-outer lg-use-css3 lg-css3 lg-hide-items " + addClasses + " \">\n\n              <div id=\"" + this.getIdName('lg-content') + "\" class=\"lg-content\">\n                <div id=\"" + this.getIdName('lg-inner') + "\" class=\"lg-inner\">\n                </div>\n                " + controls + "\n              </div>\n                <div id=\"" + this.getIdName('lg-toolbar') + "\" class=\"lg-toolbar lg-group\">\n                    " + maximizeIcon + "\n                    " + closeIcon + "\n                    </div>\n                    " + (this.settings.appendSubHtmlTo === '.lg-outer'
18961				? subHtmlCont
18962				: '') + "\n                <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n                    " + (this.settings.appendSubHtmlTo === '.lg-sub-html'
18963				? subHtmlCont
18964				: '') + "\n                </div>\n            </div>\n        </div>\n        ";
18965			$LG(this.settings.container).append(template);
18966			if (document.body !== this.settings.container) {
18967				$LG(this.settings.container).css('position', 'relative');
18968			}
18969			this.outer = this.getElementById('lg-outer');
18970			this.$lgComponents = this.getElementById('lg-components');
18971			this.$backdrop = this.getElementById('lg-backdrop');
18972			this.$container = this.getElementById('lg-container');
18973			this.$inner = this.getElementById('lg-inner');
18974			this.$content = this.getElementById('lg-content');
18975			this.$toolbar = this.getElementById('lg-toolbar');
18976			this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms');
18977			var outerClassNames = this.settings.mode + " ";
18978			this.manageSingleSlideClassName();
18979			if (this.settings.enableDrag) {
18980				outerClassNames += 'lg-grab ';
18981			}
18982			this.outer.addClass(outerClassNames);
18983			this.$inner.css('transition-timing-function', this.settings.easing);
18984			this.$inner.css('transition-duration', this.settings.speed + 'ms');
18985			if (this.settings.download) {
18986				this.$toolbar.append("<a id=\"" + this.getIdName('lg-download') + "\" target=\"_blank\" rel=\"noopener\" aria-label=\"" + this.settings.strings['download'] + "\" download class=\"lg-download lg-icon\"></a>");
18987			}
18988			this.counter();
18989			$LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () {
18990				_this.refreshOnResize();
18991			});
18992			this.hideBars();
18993			this.manageCloseGallery();
18994			this.toggleMaximize();
18995			this.initModules();
18996		};
18997		LightGallery.prototype.refreshOnResize = function () {
18998			if (this.lgOpened) {
18999				var currentGalleryItem = this.galleryItems[this.index];
19000				var __slideVideoInfo = currentGalleryItem.__slideVideoInfo;
19001				this.mediaContainerPosition = this.getMediaContainerPosition();
19002				var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom;
19003				//Uncode edit ##START##
19004				this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]);
19005				// this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize);
19006				//Uncode edit ##END##
19007				if (__slideVideoInfo) {
19008					this.resizeVideoSlide(this.index, this.currentImageSize);
19009				}
19010				if (this.zoomFromOrigin && !this.isDummyImageRemoved) {
19011					var imgStyle = this.getDummyImgStyles(this.currentImageSize);
19012					this.outer
19013						.find('.lg-current .lg-dummy-img')
19014						.first()
19015						.attr('style', imgStyle);
19016				}
19017				this.LGel.trigger(lGEvents.containerResize);
19018			}
19019		};
19020		LightGallery.prototype.resizeVideoSlide = function (index, imageSize) {
19021			var lgVideoStyle = this.getVideoContStyle(imageSize);
19022			var currentSlide = this.getSlideItem(index);
19023			currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle);
19024		};
19025		/**
19026		 * Update slides dynamically.
19027		 * Add, edit or delete slides dynamically when lightGallery is opened.
19028		 * Modify the current gallery items and pass it via updateSlides method
19029		 * @note
19030		 * - Do not mutate existing lightGallery items directly.
19031		 * - Always pass new list of gallery items
19032		 * - You need to take care of thumbnails outside the gallery if any
19033		 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method.
19034		 * @param items Gallery items
19035		 * @param index After the update operation, which slide gallery should navigate to
19036		 * @category lGPublicMethods
19037		 * @example
19038		 * const plugin = lightGallery();
19039		 *
19040		 * // Adding slides dynamically
19041		 * let galleryItems = [
19042		 * // Access existing lightGallery items
19043		 * // galleryItems are automatically generated internally from the gallery HTML markup
19044		 * // or directly from galleryItems when dynamic gallery is used
19045		 *   ...plugin.galleryItems,
19046		 *     ...[
19047		 *       {
19048		 *         src: 'img/img-1.png',
19049		 *           thumb: 'img/thumb1.png',
19050		 *         },
19051		 *     ],
19052		 *   ];
19053		 *   plugin.updateSlides(
19054		 *     galleryItems,
19055		 *     plugin.index,
19056		 *   );
19057		 *
19058		 *
19059		 * // Remove slides dynamically
19060		 * galleryItems = JSON.parse(
19061		 *   JSON.stringify(updateSlideInstance.galleryItems),
19062		 * );
19063		 * galleryItems.shift();
19064		 * updateSlideInstance.updateSlides(galleryItems, 1);
19065		 * @see <a href="/demos/update-slides/">Demo</a>
19066		 */
19067		LightGallery.prototype.updateSlides = function (items, index) {
19068			if (this.index > items.length - 1) {
19069				this.index = items.length - 1;
19070			}
19071			if (items.length === 1) {
19072				this.index = 0;
19073			}
19074			if (!items.length) {
19075				this.closeGallery();
19076				return;
19077			}
19078			var currentSrc = this.galleryItems[index].src;
19079			this.galleryItems = items;
19080			this.updateControls();
19081			this.$inner.empty();
19082			this.currentItemsInDom = [];
19083			var _index = 0;
19084			// Find the current index based on source value of the slide
19085			this.galleryItems.some(function (galleryItem, itemIndex) {
19086				if (galleryItem.src === currentSrc) {
19087					_index = itemIndex;
19088					return true;
19089				}
19090				return false;
19091			});
19092			this.currentItemsInDom = this.organizeSlideItems(_index, -1);
19093			this.loadContent(_index, true);
19094			this.getSlideItem(_index).addClass('lg-current');
19095			this.index = _index;
19096			this.updateCurrentCounter(_index);
19097			this.LGel.trigger(lGEvents.updateSlides);
19098		};
19099		// Get gallery items based on multiple conditions
19100		LightGallery.prototype.getItems = function () {
19101			// Gallery items
19102			this.items = [];
19103			if (!this.settings.dynamic) {
19104				if (this.settings.selector === 'this') {
19105					this.items.push(this.el);
19106				}
19107				else if (this.settings.selector) {
19108					if (typeof this.settings.selector === 'string') {
19109						if (this.settings.selectWithin) {
19110							var selectWithin = $LG(this.settings.selectWithin);
19111							this.items = selectWithin
19112								.find(this.settings.selector)
19113								.get();
19114						}
19115						else {
19116							this.items = this.el.querySelectorAll(this.settings.selector);
19117						}
19118					}
19119					else {
19120						this.items = this.settings.selector;
19121					}
19122				}
19123				else {
19124					this.items = this.el.children;
19125				}
19126				return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage);
19127			}
19128			else {
19129				return this.settings.dynamicEl || [];
19130			}
19131		};
19132		LightGallery.prototype.shouldHideScrollbar = function () {
19133			return (this.settings.hideScrollbar &&
19134				document.body === this.settings.container);
19135		};
19136		LightGallery.prototype.hideScrollbar = function () {
19137			if (!this.shouldHideScrollbar()) {
19138				return;
19139			}
19140			this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight);
19141			var bodyRect = document.documentElement.getBoundingClientRect();
19142			var scrollbarWidth = window.innerWidth - bodyRect.width;
19143			$LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px');
19144			$LG(document.body).addClass('lg-overlay-open');
19145		};
19146		LightGallery.prototype.resetScrollBar = function () {
19147			if (!this.shouldHideScrollbar()) {
19148				return;
19149			}
19150			$LG(document.body).css('padding-right', this.bodyPaddingRight + 'px');
19151			$LG(document.body).removeClass('lg-overlay-open');
19152		};
19153		/**
19154		 * Open lightGallery.
19155		 * Open gallery with specific slide by passing index of the slide as parameter.
19156		 * @category lGPublicMethods
19157		 * @param {Number} index  - index of the slide
19158		 * @param {HTMLElement} element - Which image lightGallery should zoom from
19159		 *
19160		 * @example
19161		 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo');
19162		 * const dynamicGallery = lightGallery($dynamicGallery, {
19163		 *     dynamic: true,
19164		 *     dynamicEl: [
19165		 *         {
19166		 *              src: 'img/1.jpg',
19167		 *              thumb: 'img/thumb-1.jpg',
19168		 *              subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>',
19169		 *         },
19170		 *         ...
19171		 *     ],
19172		 * });
19173		 * $dynamicGallery.addEventListener('click', function () {
19174		 *     // Starts with third item.(Optional).
19175		 *     // This is useful if you want use dynamic mode with
19176		 *     // custom thumbnails (thumbnails outside gallery),
19177		 *     dynamicGallery.openGallery(2);
19178		 * });
19179		 *
19180		 */
19181		LightGallery.prototype.openGallery = function (index, element) {
19182			var _this = this;
19183			if (index === void 0) { index = this.settings.index; }
19184			// prevent accidental double execution
19185			if (this.lgOpened)
19186				return;
19187			this.lgOpened = true;
19188			this.outer.removeClass('lg-hide-items');
19189			this.hideScrollbar();
19190			// Add display block, but still has opacity 0
19191			this.$container.addClass('lg-show');
19192			var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index);
19193			this.currentItemsInDom = itemsToBeInsertedToDom;
19194			var items = '';
19195			itemsToBeInsertedToDom.forEach(function (item) {
19196				items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>");
19197			});
19198			this.$inner.append(items);
19199			this.addHtml(index);
19200			var transform = '';
19201			this.mediaContainerPosition = this.getMediaContainerPosition();
19202			var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
19203			if (!this.settings.allowMediaOverlap) {
19204				this.setMediaContainerPosition(top, bottom);
19205			}
19206			var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo;
19207			if (this.zoomFromOrigin && element) {
19208				//Uncode edit ##START##
19209				this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]);
19210				// this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize);
19211				//Uncode edit ##END##
19212				transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize);
19213			}
19214			if (!this.zoomFromOrigin || !transform) {
19215				this.outer.addClass(this.settings.startClass);
19216				this.getSlideItem(index).removeClass('lg-complete');
19217			}
19218			var timeout = this.settings.zoomFromOrigin
19219				? 100
19220				: this.settings.backdropDuration;
19221			setTimeout(function () {
19222				_this.outer.addClass('lg-components-open');
19223			}, timeout);
19224			this.index = index;
19225			//Uncode edit ##START##
19226			// this.LGel.trigger(lGEvents.beforeOpen);
19227			this.LGel.trigger(lGEvents.beforeOpen, {
19228				galleryItems: this.galleryItems,
19229				items: this.items,
19230				outer: this.outer,
19231			});
19232			//Uncode edit ##END##
19233			// add class lg-current to remove initial transition
19234			this.getSlideItem(index).addClass('lg-current');
19235			this.lGalleryOn = false;
19236			// Store the current scroll top value to scroll back after closing the gallery..
19237			this.prevScrollTop = $LG(window).scrollTop();
19238			setTimeout(function () {
19239				// Need to check both zoomFromOrigin and transform values as we need to set set the
19240				// default opening animation if user missed to add the lg-size attribute
19241				if (_this.zoomFromOrigin && transform) {
19242					var currentSlide_1 = _this.getSlideItem(index);
19243					currentSlide_1.css('transform', transform);
19244					setTimeout(function () {
19245						currentSlide_1
19246							.addClass('lg-start-progress lg-start-end-progress')
19247							.css('transition-duration', _this.settings.startAnimationDuration + 'ms');
19248						_this.outer.addClass('lg-zoom-from-image');
19249					});
19250					setTimeout(function () {
19251						currentSlide_1.css('transform', 'translate3d(0, 0, 0)');
19252					}, 100);
19253				}
19254				setTimeout(function () {
19255					_this.$backdrop.addClass('in');
19256					_this.$container.addClass('lg-show-in');
19257				}, 10);
19258				setTimeout(function () {
19259					if (_this.settings.trapFocus &&
19260						document.body === _this.settings.container) {
19261						_this.trapFocus();
19262					}
19263				}, _this.settings.backdropDuration + 50);
19264				// lg-visible class resets gallery opacity to 1
19265				if (!_this.zoomFromOrigin || !transform) {
19266					setTimeout(function () {
19267						_this.outer.addClass('lg-visible');
19268					}, _this.settings.backdropDuration);
19269				}
19270				// initiate slide function
19271				_this.slide(index, false, false, false);
19272				_this.LGel.trigger(lGEvents.afterOpen);
19273			});
19274			if (document.body === this.settings.container) {
19275				$LG('html').addClass('lg-on');
19276			}
19277		};
19278		/**
19279		 * Note - Changing the position of the media on every slide transition creates a flickering effect.
19280		 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption.
19281		 * if you have dynamic captions for each media,
19282		 * you can provide an appropriate height for the captions via allowMediaOverlap option
19283		 */
19284		LightGallery.prototype.getMediaContainerPosition = function () {
19285			if (this.settings.allowMediaOverlap) {
19286				return {
19287					top: 0,
19288					bottom: 0,
19289				};
19290			}
19291			var top = this.$toolbar.get().clientHeight || 0;
19292			var subHtml = this.outer.find('.lg-components .lg-sub-html').get();
19293			var captionHeight = this.settings.defaultCaptionHeight ||
19294				(subHtml && subHtml.clientHeight) ||
19295				0;
19296			var thumbContainer = this.outer.find('.lg-thumb-outer').get();
19297			var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0;
19298			var bottom = thumbHeight + captionHeight;
19299			//Uncode edit ##START##
19300			bottom = bottom < 55 ? 55 : bottom;
19301			//Uncode edit ##END##
19302			return {
19303				top: top,
19304				bottom: bottom,
19305			};
19306		};
19307		LightGallery.prototype.setMediaContainerPosition = function (top, bottom) {
19308			if (top === void 0) { top = 0; }
19309			if (bottom === void 0) { bottom = 0; }
19310			this.$content.css('top', top + 'px').css('bottom', bottom + 'px');
19311		};
19312		LightGallery.prototype.hideBars = function () {
19313			var _this = this;
19314			// Hide controllers if mouse doesn't move for some period
19315			setTimeout(function () {
19316				_this.outer.removeClass('lg-hide-items');
19317				if (_this.settings.hideBarsDelay > 0) {
19318					_this.outer.on('mousemove.lg click.lg touchstart.lg', function () {
19319						_this.outer.removeClass('lg-hide-items');
19320						clearTimeout(_this.hideBarTimeout);
19321						// Timeout will be cleared on each slide movement also
19322						_this.hideBarTimeout = setTimeout(function () {
19323							_this.outer.addClass('lg-hide-items');
19324						}, _this.settings.hideBarsDelay);
19325					});
19326					_this.outer.trigger('mousemove.lg');
19327				}
19328			}, this.settings.showBarsAfter);
19329		};
19330		LightGallery.prototype.initPictureFill = function ($img) {
19331			if (this.settings.supportLegacyBrowser) {
19332				try {
19333					picturefill({
19334						elements: [$img.get()],
19335					});
19336				}
19337				catch (e) {
19338					console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.');
19339				}
19340			}
19341		};
19342		/**
19343		 *  @desc Create image counter
19344		 *  Ex: 1/10
19345		 */
19346		LightGallery.prototype.counter = function () {
19347			if (this.settings.counter) {
19348				var counterHtml = "<div class=\"lg-counter\" role=\"status\" aria-live=\"polite\">\n                <span id=\"" + this.getIdName('lg-counter-current') + "\" class=\"lg-counter-current\">" + (this.index + 1) + " </span> /\n                <span id=\"" + this.getIdName('lg-counter-all') + "\" class=\"lg-counter-all\">" + this.galleryItems.length + " </span></div>";
19349				this.outer.find(this.settings.appendCounterTo).append(counterHtml);
19350			}
19351		};
19352		/**
19353		 *  @desc add sub-html into the slide
19354		 *  @param {Number} index - index of the slide
19355		 */
19356		LightGallery.prototype.addHtml = function (index) {
19357			var subHtml;
19358			var subHtmlUrl;
19359			if (this.galleryItems[index].subHtmlUrl) {
19360				subHtmlUrl = this.galleryItems[index].subHtmlUrl;
19361			}
19362			else {
19363				subHtml = this.galleryItems[index].subHtml;
19364			}
19365			if (!subHtmlUrl) {
19366				if (subHtml) {
19367					// get first letter of sub-html
19368					// if first letter starts with . or # get the html form the jQuery object
19369					var fL = subHtml.substring(0, 1);
19370					if (fL === '.' || fL === '#') {
19371						if (this.settings.subHtmlSelectorRelative &&
19372							!this.settings.dynamic) {
19373							subHtml = $LG(this.items)
19374								.eq(index)
19375								.find(subHtml)
19376								.first()
19377								.html();
19378						}
19379						else {
19380							subHtml = $LG(subHtml).first().html();
19381						}
19382					}
19383				}
19384				else {
19385					subHtml = '';
19386				}
19387			}
19388			if (this.settings.appendSubHtmlTo !== '.lg-item') {
19389				if (subHtmlUrl) {
19390					this.outer.find('.lg-sub-html').load(subHtmlUrl);
19391				}
19392				else {
19393					this.outer.find('.lg-sub-html').html(subHtml);
19394				}
19395			}
19396			else {
19397				var currentSlide = $LG(this.getSlideItemId(index));
19398				if (subHtmlUrl) {
19399					currentSlide.load(subHtmlUrl);
19400				}
19401				else {
19402					currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>");
19403				}
19404			}
19405			// Add lg-empty-html class if title doesn't exist
19406			if (typeof subHtml !== 'undefined' && subHtml !== null) {
19407				if (subHtml === '') {
19408					this.outer
19409						.find(this.settings.appendSubHtmlTo)
19410						.addClass('lg-empty-html');
19411				}
19412				else {
19413					this.outer
19414						.find(this.settings.appendSubHtmlTo)
19415						.removeClass('lg-empty-html');
19416				}
19417			}
19418			this.LGel.trigger(lGEvents.afterAppendSubHtml, {
19419				index: index,
19420			});
19421		};
19422		/**
19423		 *  @desc Preload slides
19424		 *  @param {Number} index - index of the slide
19425		 * @todo preload not working for the first slide, Also, should work for the first and last slide as well
19426		 */
19427		LightGallery.prototype.preload = function (index) {
19428			for (var i = 1; i <= this.settings.preload; i++) {
19429				if (i >= this.galleryItems.length - index) {
19430					break;
19431				}
19432				this.loadContent(index + i, false);
19433			}
19434			for (var j = 1; j <= this.settings.preload; j++) {
19435				if (index - j < 0) {
19436					break;
19437				}
19438				this.loadContent(index - j, false);
19439			}
19440		};
19441		LightGallery.prototype.getDummyImgStyles = function (imageSize) {
19442			if (!imageSize)
19443				return '';
19444			return "width:" + imageSize.width + "px;\n                margin-left: -" + imageSize.width / 2 + "px;\n                margin-top: -" + imageSize.height / 2 + "px;\n                height:" + imageSize.height + "px";
19445		};
19446		LightGallery.prototype.getVideoContStyle = function (imageSize) {
19447			if (!imageSize)
19448				return '';
19449			return "width:" + imageSize.width + "px;\n                height:" + imageSize.height + "px";
19450		};
19451		LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) {
19452			var $currentItem;
19453			if (!this.settings.dynamic) {
19454				$currentItem = $LG(this.items).eq(index);
19455			}
19456			if ($currentItem) {
19457				var _dummyImgSrc = void 0;
19458				if (!this.settings.exThumbImage) {
19459					_dummyImgSrc = $currentItem.find('img').first().attr('src');
19460				}
19461				else {
19462					_dummyImgSrc = $currentItem.attr(this.settings.exThumbImage);
19463				}
19464				if (!_dummyImgSrc)
19465					return '';
19466				var imgStyle = this.getDummyImgStyles(this.currentImageSize);
19467				var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />";
19468				$currentSlide.addClass('lg-first-slide');
19469				this.outer.addClass('lg-first-slide-loading');
19470				return dummyImgContent;
19471			}
19472			return '';
19473		};
19474		LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) {
19475			var currentGalleryItem = this.galleryItems[index];
19476			var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
19477			// Use the thumbnail as dummy image which will be resized to actual image size and
19478			// displayed on top of actual image
19479			var imgContent = '';
19480			var altAttr = alt ? 'alt="' + alt + '"' : '';
19481			if (this.isFirstSlideWithZoomAnimation()) {
19482				imgContent = this.getDummyImageContent($currentSlide, index, altAttr);
19483			}
19484			else {
19485				imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources);
19486			}
19487			var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>";
19488			$currentSlide.prepend(imgMarkup);
19489		};
19490		LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) {
19491			var mediaObject = $slide.find('.lg-object').first();
19492			if (utils.isImageLoaded(mediaObject.get()) ||
19493				isHTML5VideoWithoutPoster) {
19494				onLoad();
19495			}
19496			else {
19497				mediaObject.on('load.lg error.lg', function () {
19498					onLoad && onLoad();
19499				});
19500				mediaObject.on('error.lg', function () {
19501					onError && onError();
19502				});
19503			}
19504		};
19505		/**
19506		 *
19507		 * @param $el Current slide item
19508		 * @param index
19509		 * @param delay Delay is 0 except first time
19510		 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin
19511		 * @param isFirstSlide
19512		 */
19513		LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) {
19514			var _this = this;
19515			//Uncode edit ##START##
19516			var $item = _this.galleryItems[index],
19517				type = $item.type;
19518
19519			if ( typeof $item.src !== 'undefined' ) {
19520				var inline_id = $item.src.replace('#', ''),
19521					$inline = document.getElementById(inline_id),
19522					inline_html;
19523
19524				if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) {
19525					inline_html = $inline.innerHTML;
19526				} else {
19527					inline_html = '';
19528				}
19529			}
19530			//Uncode edit ##END##
19531			this.onSlideObjectLoad(currentSlide, true, function () {
19532				_this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide);
19533			}, function () {
19534				currentSlide.addClass('lg-complete lg-complete_');
19535				//Uncode edit ##START##
19536				// currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>');
19537				if ( inline_html !== '' ) {
19538					currentSlide.html(inline_html);
19539				} else {
19540					currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>');
19541				}
19542				//Uncode edit ##END##
19543			});
19544		};
19545		LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) {
19546			var _this = this;
19547			var currentGalleryItem = this.galleryItems[index];
19548			// Adding delay for video slides without poster for better performance and user experience
19549			// Videos should start playing once once the gallery is completely loaded
19550			var _speed = isFirstSlide &&
vendor: 3,676 bytes, lines 19551-19639
19551				this.getSlideType(currentGalleryItem) === 'video' &&
19552				!currentGalleryItem.poster
19553				? speed
19554				: 0;
19555			setTimeout(function () {
19556				$currentSlide.addClass('lg-complete lg-complete_');
19557				_this.LGel.trigger(lGEvents.slideItemLoad, {
19558					index: index,
19559					delay: delay || 0,
19560					isFirstSlide: isFirstSlide,
19561				});
19562			}, _speed);
19563		};
19564		LightGallery.prototype.isFirstSlideWithZoomAnimation = function () {
19565			return !!(!this.lGalleryOn &&
19566				this.zoomFromOrigin &&
19567				this.currentImageSize);
19568		};
19569		// Add video slideInfo
19570		LightGallery.prototype.addSlideVideoInfo = function (items) {
19571			var _this = this;
19572			items.forEach(function (element, index) {
19573				element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index);
19574				if (element.__slideVideoInfo &&
19575					_this.settings.loadYouTubePoster &&
19576					!element.poster &&
19577					element.__slideVideoInfo.youtube) {
19578					element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg";
19579				}
19580			});
19581		};
19582		/**
19583		 *  Load slide content into slide.
19584		 *  This is used to load content into slides that is not visible too
19585		 *  @param {Number} index - index of the slide.
19586		 *  @param {Boolean} rec - if true call loadcontent() function again.
19587		 */
19588		LightGallery.prototype.loadContent = function (index, rec) {
19589			var _this = this;
19590			var currentGalleryItem = this.galleryItems[index];
19591			var $currentSlide = $LG(this.getSlideItemId(index));
19592			var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
19593			var src = currentGalleryItem.src;
19594			var video = currentGalleryItem.video;
19595			var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video;
19596			if (currentGalleryItem.responsive) {
19597				var srcDyItms = currentGalleryItem.responsive.split(',');
19598				src = utils.getResponsiveSrc(srcDyItms) || src;
19599			}
19600			var videoInfo = currentGalleryItem.__slideVideoInfo;
19601			var lgVideoStyle = '';
19602			var iframe = !!currentGalleryItem.iframe;
19603			var isFirstSlide = !this.lGalleryOn;
19604			// delay for adding complete class. it is 0 except first time.
19605			var delay = 0;
19606			if (isFirstSlide) {
19607				if (this.zoomFromOrigin && this.currentImageSize) {
19608					delay = this.settings.startAnimationDuration + 10;
19609				}
19610				else {
19611					delay = this.settings.backdropDuration + 10;
19612				}
19613			}
19614			if (!$currentSlide.hasClass('lg-loaded')) {
19615				if (videoInfo) {
19616					var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom;
19617					//Uncode edit ##START##
19618					var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]);
19619					// var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize);
19620					//Uncode edit ##END##
19621					lgVideoStyle = this.getVideoContStyle(videoSize);
19622				}
19623				if (iframe) {
19624					var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle);
19625					$currentSlide.prepend(markup);
19626				}
19627				else if (poster) {
19628					var dummyImg = '';
19629					var hasStartAnimation = isFirstSlide &&
19630						this.zoomFromOrigin &&
19631						this.currentImageSize;
19632					if (hasStartAnimation) {
19633						dummyImg = this.getDummyImageContent($currentSlide, index, '');
19634					}
19635					var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo);
19636					$currentSlide.prepend(markup);
19637				}
19638				//Uncode edit ##START##
19639				// else if (videoInfo) {
19640				else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') {
19641					if (! _html5Video) {
19642						var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>";
19643					}
19644					//Uncode edit ##END##
19645					$currentSlide.prepend(markup);
19646				}
19647				else {
19648					//Uncode edit ##START##
19649					var $item = _this.galleryItems[index],
19650						type = $item.type;
19651
19652					if ( typeof $item.src !== 'undefined' ) {
19653						var inline_id = $item.src.replace('#', ''),
19654							$inline = document.getElementById(inline_id),
19655							inline_html;
19656
19657						if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) {
19658							inline_html = $inline.innerHTML;
19659						} else {
19660							inline_html = '';
19661						}
19662					}
19663					if ( inline_html !== '' ) {
19664						$currentSlide.html(inline_html);
19665					} else {
19666						this.setImgMarkup(src, $currentSlide, index);
19667						if (srcset || sources) {
19668							var $img = $currentSlide.find('.lg-object');
19669							this.initPictureFill($img);
19670						}
19671					}
19672					/*this.setImgMarkup(src, $currentSlide, index);
19673					if (srcset || sources) {
19674						var $img = $currentSlide.find('.lg-object');
19675						this.initPictureFill($img);
19676					}*/
19677					//Uncode edit ##END##
19678				}
19679				if (poster || videoInfo) {
19680					this.LGel.trigger(lGEvents.hasVideo, {
19681						index: index,
19682						src: src,
19683						html5Video: _html5Video,
19684						hasPoster: !!poster,
19685					});
19686				}
19687				this.LGel.trigger(lGEvents.afterAppendSlide, { index: index });
19688				if (this.lGalleryOn &&
19689					this.settings.appendSubHtmlTo === '.lg-item') {
19690					this.addHtml(index);
19691				}
19692			}
19693			// For first time add some delay for displaying the start animation.
19694			var _speed = 0;
19695			// Do not change the delay value because it is required for zoom plugin.
19696			// If gallery opened from direct url (hash) speed value should be 0
19697			if (delay && !$LG(document.body).hasClass('lg-from-hash')) {
19698				_speed = delay;
19699			}
19700			// Only for first slide and zoomFromOrigin is enabled
19701			if (this.isFirstSlideWithZoomAnimation()) {
19702				setTimeout(function () {
19703					$currentSlide
19704						.removeClass('lg-start-end-progress lg-start-progress')
19705						.removeAttr('style');
19706				}, this.settings.startAnimationDuration + 100);
19707				if (!$currentSlide.hasClass('lg-loaded')) {
19708					setTimeout(function () {
19709						if (_this.getSlideType(currentGalleryItem) === 'image') {
19710							var alt = currentGalleryItem.alt;
19711							var altAttr = alt ? 'alt="' + alt + '"' : '';
19712							$currentSlide
19713								.find('.lg-img-wrap')
19714								.append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources));
19715							if (srcset || sources) {
19716								var $img = $currentSlide.find('.lg-object');
19717								_this.initPictureFill($img);
19718							}
19719						}
19720						if (_this.getSlideType(currentGalleryItem) === 'image' ||
19721							(_this.getSlideType(currentGalleryItem) === 'video' &&
19722								poster)) {
19723							_this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false);
19724							// load remaining slides once the slide is completely loaded
19725							_this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () {
19726								_this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
19727							}, function () {
19728								_this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
19729							});
19730						}
19731					}, this.settings.startAnimationDuration + 100);
19732				}
19733			}
19734			// SLide content has been added to dom
19735			$currentSlide.addClass('lg-loaded');
19736			if (!this.isFirstSlideWithZoomAnimation() ||
19737				(this.getSlideType(currentGalleryItem) === 'video' && !poster)) {
19738				//Uncode edit ##START##
19739				// this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster));
19740				this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.get
vendor: 31,133 bytes, lines 19740-20664
19740SlideType(currentGalleryItem) === 'audio'));
19741				//Uncode edit ##END##
19742			}
19743			// When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling
19744			if ((!this.zoomFromOrigin || !this.currentImageSize) &&
19745				$currentSlide.hasClass('lg-complete_') &&
19746				!this.lGalleryOn) {
19747				setTimeout(function () {
19748					$currentSlide.addClass('lg-complete');
19749				}, this.settings.backdropDuration);
19750			}
19751			// Content loaded
19752			// Need to set lGalleryOn before calling preload function
19753			this.lGalleryOn = true;
19754			if (rec === true) {
19755				if (!$currentSlide.hasClass('lg-complete_')) {
19756					$currentSlide
19757						.find('.lg-object')
19758						.first()
19759						.on('load.lg error.lg', function () {
19760						_this.preload(index);
19761					});
19762				}
19763				else {
19764					this.preload(index);
19765				}
19766			}
19767		};
19768		/**
19769		 * @desc Remove dummy image content and load next slides
19770		 * Called only for the first time if zoomFromOrigin animation is enabled
19771		 * @param index
19772		 * @param $currentSlide
19773		 * @param speed
19774		 */
19775		LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) {
19776			var _this = this;
19777			setTimeout(function () {
19778				$currentSlide.find('.lg-dummy-img').remove();
19779				$currentSlide.removeClass('lg-first-slide');
19780				_this.outer.removeClass('lg-first-slide-loading');
19781				_this.isDummyImageRemoved = true;
19782				_this.preload(index);
19783			}, speed + 300);
19784		};
19785		LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) {
19786			var _this = this;
19787			if (numberOfItems === void 0) { numberOfItems = 0; }
19788			var itemsToBeInsertedToDom = [];
19789			// Minimum 2 items should be there
19790			var possibleNumberOfItems = Math.max(numberOfItems, 3);
19791			possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length);
19792			var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex;
19793			if (this.galleryItems.length <= 3) {
19794				this.galleryItems.forEach(function (_element, index) {
19795					itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index);
19796				});
19797				return itemsToBeInsertedToDom;
19798			}
19799			if (index < (this.galleryItems.length - 1) / 2) {
19800				for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) {
19801					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
19802				}
19803				var numberOfExistingItems = itemsToBeInsertedToDom.length;
19804				for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
19805					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1));
19806				}
19807			}
19808			else {
19809				for (var idx = index; idx <= this.galleryItems.length - 1 &&
19810					idx < index + possibleNumberOfItems / 2; idx++) {
19811					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
19812				}
19813				var numberOfExistingItems = itemsToBeInsertedToDom.length;
19814				for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
19815					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1));
19816				}
19817			}
19818			if (this.settings.loop) {
19819				if (index === this.galleryItems.length - 1) {
19820					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0);
19821				}
19822				else if (index === 0) {
19823					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1));
19824				}
19825			}
19826			if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {
19827				itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex);
19828			}
19829			return itemsToBeInsertedToDom;
19830		};
19831		LightGallery.prototype.organizeSlideItems = function (index, prevIndex) {
19832			var _this = this;
19833			var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom);
19834			itemsToBeInsertedToDom.forEach(function (item) {
19835				if (_this.currentItemsInDom.indexOf(item) === -1) {
19836					_this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>");
19837				}
19838			});
19839			this.currentItemsInDom.forEach(function (item) {
19840				if (itemsToBeInsertedToDom.indexOf(item) === -1) {
19841					$LG("#" + item).remove();
19842				}
19843			});
19844			return itemsToBeInsertedToDom;
19845		};
19846		/**
19847		 * Get previous index of the slide
19848		 */
19849		LightGallery.prototype.getPreviousSlideIndex = function () {
19850			var prevIndex = 0;
19851			try {
19852				var currentItemId = this.outer
19853					.find('.lg-current')
19854					.first()
19855					.attr('id');
19856				prevIndex = parseInt(currentItemId.split('-')[3]) || 0;
19857			}
19858			catch (error) {
19859				prevIndex = 0;
19860			}
19861			return prevIndex;
19862		};
19863		LightGallery.prototype.setDownloadValue = function (index) {
19864			if (this.settings.download) {
19865				var currentGalleryItem = this.galleryItems[index];
19866				var hideDownloadBtn = currentGalleryItem.downloadUrl === false ||
19867					currentGalleryItem.downloadUrl === 'false';
19868				if (hideDownloadBtn) {
19869					this.outer.addClass('lg-hide-download');
19870				}
19871				else {
19872					var $download = this.getElementById('lg-download');
19873					this.outer.removeClass('lg-hide-download');
19874					$download.attr('href', currentGalleryItem.downloadUrl ||
19875						currentGalleryItem.src);
19876					if (currentGalleryItem.download) {
19877						//Uncode edit ##START##
19878						if ( typeof currentGalleryItem.video !== 'undefined' && currentGalleryItem.video ) {
19879							var currentVideo = JSON.parse( currentGalleryItem.video ),
19880								download_name = currentVideo.source[0].src;
19881							$download.attr('href', download_name).removeAttr('download');
19882						} else {
19883							var download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src,
19884								download_name = download_url.substring(download_url.lastIndexOf('/')+1);
19885							$download.attr('download', download_name);
19886						}
19887						// $download.attr('download', currentGalleryItem.download);
19888						//Uncode edit ##END##
19889					}
19890				}
19891			}
19892		};
19893		LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) {
19894			var _this = this;
19895			if (this.lGalleryOn) {
19896				previousSlideItem.addClass('lg-slide-progress');
19897			}
19898			setTimeout(function () {
19899				// remove all transitions
19900				_this.outer.addClass('lg-no-trans');
19901				_this.outer
19902					.find('.lg-item')
19903					.removeClass('lg-prev-slide lg-next-slide');
19904				if (direction === 'prev') {
19905					//prevslide
19906					currentSlideItem.addClass('lg-prev-slide');
19907					previousSlideItem.addClass('lg-next-slide');
19908				}
19909				else {
19910					// next slide
19911					currentSlideItem.addClass('lg-next-slide');
19912					previousSlideItem.addClass('lg-prev-slide');
19913				}
19914				// give 50 ms for browser to add/remove class
19915				setTimeout(function () {
19916					_this.outer.find('.lg-item').removeClass('lg-current');
19917					currentSlideItem.addClass('lg-current');
19918					// reset all transitions
19919					_this.outer.removeClass('lg-no-trans');
19920				}, 50);
19921			}, this.lGalleryOn ? this.settings.slideDelay : 0);
19922		};
19923		/**
19924		 * Goto a specific slide.
19925		 * @param {Number} index - index of the slide
19926		 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
19927		 * @param {Boolean} fromThumb - true if slide function called via thumbnail click
19928		 * @param {String} direction - Direction of the slide(next/prev)
19929		 * @category lGPublicMethods
19930		 * @example
19931		 *  const plugin = lightGallery();
19932		 *  // to go to 3rd slide
19933		 *  plugin.slide(2);
19934		 *
19935		 */
19936		LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) {
19937			var _this = this;
19938			var prevIndex = this.getPreviousSlideIndex();
19939			this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);
19940			// Prevent multiple call, Required for hsh plugin
19941			if (this.lGalleryOn && prevIndex === index) {
19942				return;
19943			}
19944			var numberOfGalleryItems = this.galleryItems.length;
19945			if (!this.lgBusy) {
19946				if (this.settings.counter) {
19947					this.updateCurrentCounter(index);
19948				}
19949				var currentSlideItem = this.getSlideItem(index);
19950				var previousSlideItem_1 = this.getSlideItem(prevIndex);
19951				var currentGalleryItem = this.galleryItems[index];
19952				var videoInfo = currentGalleryItem.__slideVideoInfo;
19953				this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem));
19954				this.setDownloadValue(index);
19955				if (videoInfo) {
19956					var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom;
19957					//Uncode edit ##START##
19958					var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]);
19959					// var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize);
19960					//Uncode edit ##END##
19961					this.resizeVideoSlide(index, videoSize);
19962				}
19963				this.LGel.trigger(lGEvents.beforeSlide, {
19964					prevIndex: prevIndex,
19965					index: index,
19966					fromTouch: !!fromTouch,
19967					fromThumb: !!fromThumb,
19968					//Uncode edit ##START##
19969					currentSlide: currentSlideItem,
19970					previousSlide: previousSlideItem_1,
19971					info: currentGalleryItem,
19972					item: this.items[index]
19973					//Uncode edit ##END##
19974				});
19975				this.lgBusy = true;
19976				clearTimeout(this.hideBarTimeout);
19977				this.arrowDisable(index);
19978				if (!direction) {
19979					if (index < prevIndex) {
19980						direction = 'prev';
19981					}
19982					else if (index > prevIndex) {
19983						direction = 'next';
19984					}
19985				}
19986				if (!fromTouch) {
19987					this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1);
19988				}
19989				else {
19990					this.outer
19991						.find('.lg-item')
19992						.removeClass('lg-prev-slide lg-current lg-next-slide');
19993					var touchPrev = void 0;
19994					var touchNext = void 0;
19995					if (numberOfGalleryItems > 2) {
19996						touchPrev = index - 1;
19997						touchNext = index + 1;
19998						if (index === 0 && prevIndex === numberOfGalleryItems - 1) {
19999							// next slide
20000							touchNext = 0;
20001							touchPrev = numberOfGalleryItems - 1;
20002						}
20003						else if (index === numberOfGalleryItems - 1 &&
20004							prevIndex === 0) {
20005							// prev slide
20006							touchNext = 0;
20007							touchPrev = numberOfGalleryItems - 1;
20008						}
20009					}
20010					else {
20011						touchPrev = 0;
20012						touchNext = 1;
20013					}
20014					if (direction === 'prev') {
20015						this.getSlideItem(touchNext).addClass('lg-next-slide');
20016					}
20017					else {
20018						this.getSlideItem(touchPrev).addClass('lg-prev-slide');
20019					}
20020					currentSlideItem.addClass('lg-current');
20021				}
20022				// Do not put load content in set timeout as it needs to load immediately when the gallery is opened
20023				if (!this.lGalleryOn) {
20024					this.loadContent(index, true);
20025				}
20026				else {
20027					setTimeout(function () {
20028						_this.loadContent(index, true);
20029						// Add title if this.settings.appendSubHtmlTo === lg-sub-html
20030						if (_this.settings.appendSubHtmlTo !== '.lg-item') {
20031							_this.addHtml(index);
20032						}
20033					}, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));
20034				}
20035				setTimeout(function () {
20036					_this.lgBusy = false;
20037					previousSlideItem_1.removeClass('lg-slide-progress');
20038					_this.LGel.trigger(lGEvents.afterSlide, {
20039						prevIndex: prevIndex,
20040						index: index,
20041						fromTouch: fromTouch,
20042						fromThumb: fromThumb,
20043					});
20044				}, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));
20045			}
20046			this.index = index;
20047		};
20048		LightGallery.prototype.updateCurrentCounter = function (index) {
20049			this.getElementById('lg-counter-current').html(index + 1 + '');
20050		};
20051		LightGallery.prototype.updateCounterTotal = function () {
20052			this.getElementById('lg-counter-all').html(this.galleryItems.length + '');
20053		};
20054		LightGallery.prototype.getSlideType = function (item) {
20055			if (item.__slideVideoInfo) {
20056				return 'video';
20057			}
20058			else if (item.iframe) {
20059				return 'iframe';
20060			}
20061			//Uncode edit ##START##
20062			else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) {
20063				return 'audio';
20064			}
20065			//Uncode edit ##END##
20066			else {
20067				return 'image';
20068			}
20069		};
20070		LightGallery.prototype.touchMove = function (startCoords, endCoords, e) {
20071			var distanceX = endCoords.pageX - startCoords.pageX;
20072			var distanceY = endCoords.pageY - startCoords.pageY;
20073			var allowSwipe = false;
20074			if (this.swipeDirection) {
20075				allowSwipe = true;
20076			}
20077			else {
20078				if (Math.abs(distanceX) > 15) {
20079					this.swipeDirection = 'horizontal';
20080					allowSwipe = true;
20081				}
20082				else if (Math.abs(distanceY) > 15) {
20083					this.swipeDirection = 'vertical';
20084					allowSwipe = true;
20085				}
20086			}
20087			if (!allowSwipe) {
20088				return;
20089			}
20090			var $currentSlide = this.getSlideItem(this.index);
20091			if (this.swipeDirection === 'horizontal') {
20092				e === null || e === void 0 ? void 0 : e.preventDefault();
20093				// reset opacity and transition duration
20094				this.outer.addClass('lg-dragging');
20095				// move current slide
20096				this.setTranslate($currentSlide, distanceX, 0);
20097				// move next and prev slide with current slide
20098				var width = $currentSlide.get().offsetWidth;
20099				var slideWidthAmount = (width * 15) / 100;
20100				var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100);
20101				this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0);
20102				this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0);
20103			}
20104			else if (this.swipeDirection === 'vertical') {
20105				if (this.settings.swipeToClose) {
20106					e === null || e === void 0 ? void 0 : e.preventDefault();
20107					this.$container.addClass('lg-dragging-vertical');
20108					var opacity = 1 - Math.abs(distanceY) / window.innerHeight;
20109					this.$backdrop.css('opacity', opacity);
20110					var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2);
20111					this.setTranslate($currentSlide, 0, distanceY, scale, scale);
20112					if (Math.abs(distanceY) > 100) {
20113						this.outer
20114							.addClass('lg-hide-items')
20115							.removeClass('lg-components-open');
20116					}
20117				}
20118			}
20119		};
20120		LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) {
20121			var _this = this;
20122			var distance;
20123			// keep slide animation for any mode while dragg/swipe
20124			if (this.settings.mode !== 'lg-slide') {
20125				this.outer.addClass('lg-slide');
20126			}
20127			// set transition duration
20128			setTimeout(function () {
20129				_this.$container.removeClass('lg-dragging-vertical');
20130				_this.outer
20131					.removeClass('lg-dragging lg-hide-items')
20132					.addClass('lg-components-open');
20133				var triggerClick = true;
20134				if (_this.swipeDirection === 'horizontal') {
20135					distance = endCoords.pageX - startCoords.pageX;
20136					var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX);
20137					if (distance < 0 &&
20138						distanceAbs > _this.settings.swipeThreshold) {
20139						_this.goToNextSlide(true);
20140						triggerClick = false;
20141					}
20142					else if (distance > 0 &&
20143						distanceAbs > _this.settings.swipeThreshold) {
20144						_this.goToPrevSlide(true);
20145						triggerClick = false;
20146					}
20147				}
20148				else if (_this.swipeDirection === 'vertical') {
20149					distance = Math.abs(endCoords.pageY - startCoords.pageY);
20150					if (_this.settings.closable &&
20151						_this.settings.swipeToClose &&
20152						distance > 100) {
20153						_this.closeGallery();
20154						return;
20155					}
20156					else {
20157						_this.$backdrop.css('opacity', 1);
20158					}
20159				}
20160				_this.outer.find('.lg-item').removeAttr('style');
20161				if (triggerClick &&
20162					Math.abs(endCoords.pageX - startCoords.pageX) < 5) {
20163					// Trigger click if distance is less than 5 pix
20164					var target = $LG(event.target);
20165					if (_this.isPosterElement(target)) {
20166						_this.LGel.trigger(lGEvents.posterClick);
20167					}
20168				}
20169				_this.swipeDirection = undefined;
20170			});
20171			// remove slide class once drag/swipe is completed if mode is not slide
20172			setTimeout(function () {
20173				if (!_this.outer.hasClass('lg-dragging') &&
20174					_this.settings.mode !== 'lg-slide') {
20175					_this.outer.removeClass('lg-slide');
20176				}
20177			}, this.settings.speed + 100);
20178		};
20179		LightGallery.prototype.enableSwipe = function () {
20180			var _this = this;
20181			var startCoords = {};
20182			var endCoords = {};
20183			var isMoved = false;
20184			var isSwiping = false;
20185			if (this.settings.enableSwipe) {
20186				this.$inner.on('touchstart.lg', function (e) {
20187					_this.dragOrSwipeEnabled = true;
20188					var $item = _this.getSlideItem(_this.index);
20189					if (($LG(e.target).hasClass('lg-item') ||
20190						$item.get().contains(e.target)) &&
20191						!_this.outer.hasClass('lg-zoomed') &&
20192						!_this.lgBusy &&
20193						e.targetTouches.length === 1) {
20194						isSwiping = true;
20195						_this.touchAction = 'swipe';
20196						_this.manageSwipeClass();
20197						startCoords = {
20198							pageX: e.targetTouches[0].pageX,
20199							pageY: e.targetTouches[0].pageY,
20200						};
20201					}
20202				});
20203				this.$inner.on('touchmove.lg', function (e) {
20204					if (isSwiping &&
20205						_this.touchAction === 'swipe' &&
20206						e.targetTouches.length === 1) {
20207						endCoords = {
20208							pageX: e.targetTouches[0].pageX,
20209							pageY: e.targetTouches[0].pageY,
20210						};
20211						_this.touchMove(startCoords, endCoords, e);
20212						isMoved = true;
20213					}
20214				});
20215				this.$inner.on('touchend.lg', function (event) {
20216					if (_this.touchAction === 'swipe') {
20217						if (isMoved) {
20218							isMoved = false;
20219							_this.touchEnd(endCoords, startCoords, event);
20220						}
20221						else if (isSwiping) {
20222							var target = $LG(event.target);
20223							if (_this.isPosterElement(target)) {
20224								_this.LGel.trigger(lGEvents.posterClick);
20225							}
20226						}
20227						_this.touchAction = undefined;
20228						isSwiping = false;
20229					}
20230				});
20231			}
20232		};
20233		LightGallery.prototype.enableDrag = function () {
20234			var _this = this;
20235			var startCoords = {};
20236			var endCoords = {};
20237			var isDraging = false;
20238			var isMoved = false;
20239			if (this.settings.enableDrag) {
20240				this.outer.on('mousedown.lg', function (e) {
20241					_this.dragOrSwipeEnabled = true;
20242					var $item = _this.getSlideItem(_this.index);
20243					if ($LG(e.target).hasClass('lg-item') ||
20244						$item.get().contains(e.target)) {
20245						if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) {
20246							e.preventDefault();
20247							if (!_this.lgBusy) {
20248								_this.manageSwipeClass();
20249								startCoords = {
20250									pageX: e.pageX,
20251									pageY: e.pageY,
20252								};
20253								isDraging = true;
20254								// ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
20255								_this.outer.get().scrollLeft += 1;
20256								_this.outer.get().scrollLeft -= 1;
20257								// *
20258								_this.outer
20259									.removeClass('lg-grab')
20260									.addClass('lg-grabbing');
20261								_this.LGel.trigger(lGEvents.dragStart);
20262							}
20263						}
20264					}
20265				});
20266				$LG(window).on("mousemove.lg.global" + this.lgId, function (e) {
20267					if (isDraging && _this.lgOpened) {
20268						isMoved = true;
20269						endCoords = {
20270							pageX: e.pageX,
20271							pageY: e.pageY,
20272						};
20273						_this.touchMove(startCoords, endCoords);
20274						_this.LGel.trigger(lGEvents.dragMove);
20275					}
20276				});
20277				$LG(window).on("mouseup.lg.global" + this.lgId, function (event) {
20278					if (!_this.lgOpened) {
20279						return;
20280					}
20281					var target = $LG(event.target);
20282					if (isMoved) {
20283						isMoved = false;
20284						_this.touchEnd(endCoords, startCoords, event);
20285						_this.LGel.trigger(lGEvents.dragEnd);
20286					}
20287					else if (_this.isPosterElement(target)) {
20288						_this.LGel.trigger(lGEvents.posterClick);
20289					}
20290					// Prevent execution on click
20291					if (isDraging) {
20292						isDraging = false;
20293						_this.outer.removeClass('lg-grabbing').addClass('lg-grab');
20294					}
20295				});
20296			}
20297		};
20298		LightGallery.prototype.triggerPosterClick = function () {
20299			var _this = this;
20300			this.$inner.on('click.lg', function (event) {
20301				if (!_this.dragOrSwipeEnabled &&
20302					_this.isPosterElement($LG(event.target))) {
20303					_this.LGel.trigger(lGEvents.posterClick);
20304				}
20305			});
20306		};
20307		LightGallery.prototype.manageSwipeClass = function () {
20308			var _touchNext = this.index + 1;
20309			var _touchPrev = this.index - 1;
20310			if (this.settings.loop && this.galleryItems.length > 2) {
20311				if (this.index === 0) {
20312					_touchPrev = this.galleryItems.length - 1;
20313				}
20314				else if (this.index === this.galleryItems.length - 1) {
20315					_touchNext = 0;
20316				}
20317			}
20318			this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');
20319			if (_touchPrev > -1) {
20320				this.getSlideItem(_touchPrev).addClass('lg-prev-slide');
20321			}
20322			this.getSlideItem(_touchNext).addClass('lg-next-slide');
20323		};
20324		/**
20325		 * Go to next slide
20326		 * @param {Boolean} fromTouch - true if slide function called via touch event
20327		 * @category lGPublicMethods
20328		 * @example
20329		 *  const plugin = lightGallery();
20330		 *  plugin.goToNextSlide();
20331		 * @see <a href="/demos/methods/">Demo</a>
20332		 */
20333		LightGallery.prototype.goToNextSlide = function (fromTouch) {
20334			var _this = this;
20335			var _loop = this.settings.loop;
20336			if (fromTouch && this.galleryItems.length < 3) {
20337				_loop = false;
20338			}
20339			if (!this.lgBusy) {
20340				if (this.index + 1 < this.galleryItems.length) {
20341					this.index++;
20342					this.LGel.trigger(lGEvents.beforeNextSlide, {
20343						index: this.index,
20344					});
20345					this.slide(this.index, !!fromTouch, false, 'next');
20346				}
20347				else {
20348					if (_loop) {
20349						this.index = 0;
20350						this.LGel.trigger(lGEvents.beforeNextSlide, {
20351							index: this.index,
20352						});
20353						this.slide(this.index, !!fromTouch, false, 'next');
20354					}
20355					else if (this.settings.slideEndAnimation && !fromTouch) {
20356						this.outer.addClass('lg-right-end');
20357						setTimeout(function () {
20358							_this.outer.removeClass('lg-right-end');
20359						}, 400);
20360					}
20361				}
20362			}
20363		};
20364		/**
20365		 * Go to previous slides
20366		 * @param {Boolean} fromTouch - true if slide function called via touch event
20367		 * @category lGPublicMethods
20368		 * @example
20369		 *  const plugin = lightGallery({});
20370		 *  plugin.goToPrevSlide();
20371		 * @see <a href="/demos/methods/">Demo</a>
20372		 *
20373		 */
20374		LightGallery.prototype.goToPrevSlide = function (fromTouch) {
20375			var _this = this;
20376			var _loop = this.settings.loop;
20377			if (fromTouch && this.galleryItems.length < 3) {
20378				_loop = false;
20379			}
20380			if (!this.lgBusy) {
20381				if (this.index > 0) {
20382					this.index--;
20383					this.LGel.trigger(lGEvents.beforePrevSlide, {
20384						index: this.index,
20385						fromTouch: fromTouch,
20386					});
20387					this.slide(this.index, !!fromTouch, false, 'prev');
20388				}
20389				else {
20390					if (_loop) {
20391						this.index = this.galleryItems.length - 1;
20392						this.LGel.trigger(lGEvents.beforePrevSlide, {
20393							index: this.index,
20394							fromTouch: fromTouch,
20395						});
20396						this.slide(this.index, !!fromTouch, false, 'prev');
20397					}
20398					else if (this.settings.slideEndAnimation && !fromTouch) {
20399						this.outer.addClass('lg-left-end');
20400						setTimeout(function () {
20401							_this.outer.removeClass('lg-left-end');
20402						}, 400);
20403					}
20404				}
20405			}
20406		};
20407		LightGallery.prototype.keyPress = function () {
20408			var _this = this;
20409			$LG(window).on("keydown.lg.global" + this.lgId, function (e) {
20410				if (_this.lgOpened &&
20411					_this.settings.escKey === true &&
20412					e.keyCode === 27) {
20413					e.preventDefault();
20414					if (_this.settings.allowMediaOverlap &&
20415						_this.outer.hasClass('lg-can-toggle') &&
20416						_this.outer.hasClass('lg-components-open')) {
20417						_this.outer.removeClass('lg-components-open');
20418					}
20419					else {
20420						_this.closeGallery();
20421					}
20422				}
20423				if (_this.lgOpened && _this.galleryItems.length > 1) {
20424					if (e.keyCode === 37) {
20425						e.preventDefault();
20426						_this.goToPrevSlide();
20427					}
20428					if (e.keyCode === 39) {
20429						e.preventDefault();
20430						_this.goToNextSlide();
20431					}
20432				}
20433			});
20434		};
20435		LightGallery.prototype.arrow = function () {
20436			var _this = this;
20437			this.getElementById('lg-prev').on('click.lg', function () {
20438				_this.goToPrevSlide();
20439			});
20440			this.getElementById('lg-next').on('click.lg', function () {
20441				_this.goToNextSlide();
20442			});
20443		};
20444		LightGallery.prototype.arrowDisable = function (index) {
20445			// Disable arrows if settings.hideControlOnEnd is true
20446			if (!this.settings.loop && this.settings.hideControlOnEnd) {
20447				var $prev = this.getElementById('lg-prev');
20448				var $next = this.getElementById('lg-next');
20449				if (index + 1 === this.galleryItems.length) {
20450					$next.attr('disabled', 'disabled').addClass('disabled');
20451				}
20452				else {
20453					$next.removeAttr('disabled').removeClass('disabled');
20454				}
20455				if (index === 0) {
20456					$prev.attr('disabled', 'disabled').addClass('disabled');
20457				}
20458				else {
20459					$prev.removeAttr('disabled').removeClass('disabled');
20460				}
20461			}
20462		};
20463		LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) {
20464			if (scaleX === void 0) { scaleX = 1; }
20465			if (scaleY === void 0) { scaleY = 1; }
20466			$el.css('transform', 'translate3d(' +
20467				xValue +
20468				'px, ' +
20469				yValue +
20470				'px, 0px) scale3d(' +
20471				scaleX +
20472				', ' +
20473				scaleY +
20474				', 1)');
20475		};
20476		LightGallery.prototype.mousewheel = function () {
20477			var _this = this;
20478			var lastCall = 0;
20479			this.outer.on('wheel.lg', function (e) {
20480				if (!e.deltaY || _this.galleryItems.length < 2) {
20481					return;
20482				}
20483				e.preventDefault();
20484				var now = new Date().getTime();
20485				if (now - lastCall < 1000) {
20486					return;
20487				}
20488				lastCall = now;
20489				if (e.deltaY > 0) {
20490					_this.goToNextSlide();
20491				}
20492				else if (e.deltaY < 0) {
20493					_this.goToPrevSlide();
20494				}
20495			});
20496		};
20497		LightGallery.prototype.isSlideElement = function (target) {
20498			return (target.hasClass('lg-outer') ||
20499				target.hasClass('lg-item') ||
20500				target.hasClass('lg-img-wrap'));
20501		};
20502		LightGallery.prototype.isPosterElement = function (target) {
20503			var playButton = this.getSlideItem(this.index)
20504				.find('.lg-video-play-button')
20505				.get();
20506			return (target.hasClass('lg-video-poster') ||
20507				target.hasClass('lg-video-play-button') ||
20508				(playButton && playButton.contains(target.get())));
20509		};
20510		/**
20511		 * Maximize minimize inline gallery.
20512		 * @category lGPublicMethods
20513		 */
20514		LightGallery.prototype.toggleMaximize = function () {
20515			var _this = this;
20516			this.getElementById('lg-maximize').on('click.lg', function () {
20517				_this.$container.toggleClass('lg-inline');
20518				_this.refreshOnResize();
20519			});
20520		};
20521		LightGallery.prototype.invalidateItems = function () {
20522			for (var index = 0; index < this.items.length; index++) {
20523				var element = this.items[index];
20524				var $element = $LG(element);
20525				$element.off("click.lgcustom-item-" + $element.attr('data-lg-id'));
20526			}
20527		};
20528		LightGallery.prototype.trapFocus = function () {
20529			var _this = this;
20530			this.$container.get().focus({
20531				preventScroll: true,
20532			});
20533			$LG(window).on("keydown.lg.global" + this.lgId, function (e) {
20534				if (!_this.lgOpened) {
20535					return;
20536				}
20537				var isTabPressed = e.key === 'Tab' || e.keyCode === 9;
20538				if (!isTabPressed) {
20539					return;
20540				}
20541				var focusableEls = utils.getFocusableElements(_this.$container.get());
20542				var firstFocusableEl = focusableEls[0];
20543				var lastFocusableEl = focusableEls[focusableEls.length - 1];
20544				if (e.shiftKey) {
20545					if (document.activeElement === firstFocusableEl) {
20546						lastFocusableEl.focus();
20547						e.preventDefault();
20548					}
20549				}
20550				else {
20551					if (document.activeElement === lastFocusableEl) {
20552						firstFocusableEl.focus();
20553						e.preventDefault();
20554					}
20555				}
20556			});
20557		};
20558		LightGallery.prototype.manageCloseGallery = function () {
20559			var _this = this;
20560			if (!this.settings.closable)
20561				return;
20562			var mousedown = false;
20563			this.getElementById('lg-close').on('click.lg', function () {
20564				_this.closeGallery();
20565			});
20566			if (this.settings.closeOnTap) {
20567				// If you drag the slide and release outside gallery gets close on chrome
20568				// for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
20569				this.outer.on('mousedown.lg', function (e) {
20570					var target = $LG(e.target);
20571					if (_this.isSlideElement(target)) {
20572						mousedown = true;
20573					}
20574					else {
20575						mousedown = false;
20576					}
20577				});
20578				this.outer.on('mousemove.lg', function () {
20579					mousedown = false;
20580				});
20581				this.outer.on('mouseup.lg', function (e) {
20582					var target = $LG(e.target);
20583					if (_this.isSlideElement(target) && mousedown) {
20584						if (!_this.outer.hasClass('lg-dragging')) {
20585							_this.closeGallery();
20586						}
20587					}
20588				});
20589			}
20590		};
20591		/**
20592		 * Close lightGallery if it is opened.
20593		 *
20594		 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery
20595		 * @return returns the estimated time to close gallery completely including the close animation duration
20596		 * @category lGPublicMethods
20597		 * @example
20598		 *  const plugin = lightGallery();
20599		 *  plugin.closeGallery();
20600		 *
20601		 */
20602		LightGallery.prototype.closeGallery = function (force) {
20603			var _this = this;
20604			if (!this.lgOpened || (!this.settings.closable && !force)) {
20605				return 0;
20606			}
20607			this.LGel.trigger(lGEvents.beforeClose);
20608			if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {
20609				$LG(window).scrollTop(this.prevScrollTop);
20610			}
20611			var currentItem = this.items[this.index];
20612			var transform;
20613			if (this.zoomFromOrigin && currentItem) {
20614				var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom;
20615				var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster;
20616				//Uncode edit ##START##
20617				var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]);
20618				// var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize);
20619				//Uncode edit ##END##
20620				transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize);
20621			}
20622			if (this.zoomFromOrigin && transform) {
20623				this.outer.addClass('lg-closing lg-zoom-from-image');
20624				this.getSlideItem(this.index)
20625					.addClass('lg-start-end-progress')
20626					.css('transition-duration', this.settings.startAnimationDuration + 'ms')
20627					.css('transform', transform);
20628			}
20629			else {
20630				this.outer.addClass('lg-hide-items');
20631				// lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true
20632				// If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts
20633				this.outer.removeClass('lg-zoom-from-image');
20634			}
20635			// Unbind all events added by lightGallery
20636			// @todo
20637			//this.$el.off('.lg.tm');
20638			this.destroyModules();
20639			this.lGalleryOn = false;
20640			this.isDummyImageRemoved = false;
20641			this.zoomFromOrigin = this.settings.zoomFromOrigin;
20642			clearTimeout(this.hideBarTimeout);
20643			this.hideBarTimeout = false;
20644			$LG('html').removeClass('lg-on');
20645			this.outer.removeClass('lg-visible lg-components-open');
20646			// Resetting opacity to 0 isd required as  vertical swipe to close function adds inline opacity.
20647			this.$backdrop.removeClass('in').css('opacity', 0);
20648			var removeTimeout = this.zoomFromOrigin && transform
20649				? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration)
20650				: this.settings.backdropDuration;
20651			this.$container.removeClass('lg-show-in');
20652			// Once the closign animation is completed and gallery is invisible
20653			setTimeout(function () {
20654				if (_this.zoomFromOrigin && transform) {
20655					_this.outer.removeClass('lg-zoom-from-image');
20656				}
20657				_this.$container.removeClass('lg-show');
20658				// Reset scrollbar
20659				_this.resetScrollBar();
20660				// Need to remove inline opacity as it is used in the stylesheet as well
20661				_this.$backdrop
20662					.removeAttr('style')
20663					.css('transition-duration', _this.settings.backdropDuration + 'ms');
20664				_this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 20665-20868
20665				_this.getSlideItem(_this.index).removeClass('lg-start-end-progress');
20666				_this.$inner.empty();
20667				if (_this.lgOpened) {
20668					_this.LGel.trigger(lGEvents.afterClose, {
20669						instance: _this,
20670					});
20671				}
20672				if (_this.$container.get()) {
20673					_this.$container.get().blur();
20674				}
20675				_this.lgOpened = false;
20676			}, removeTimeout + 100);
20677			return removeTimeout + 100;
20678		};
20679		LightGallery.prototype.initModules = function () {
20680			this.plugins.forEach(function (module) {
20681				try {
20682					module.init();
20683				}
20684				catch (err) {
20685					console.warn("lightGallery:- make sure lightGallery module is properly initiated");
20686				}
20687			});
20688		};
20689		LightGallery.prototype.destroyModules = function (destroy) {
20690			this.plugins.forEach(function (module) {
20691				try {
20692					if (destroy) {
20693						module.destroy();
20694					}
20695					else {
20696						module.closeGallery && module.closeGallery();
20697					}
20698				}
20699				catch (err) {
20700					console.warn("lightGallery:- make sure lightGallery module is properly destroyed");
20701				}
20702			});
20703		};
20704		/**
20705		 * Refresh lightGallery with new set of children.
20706		 *
20707		 * @description This is useful to update the gallery when the child elements are changed without calling destroy method.
20708		 *
20709		 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery
20710		 * @see <a href="/demos/dynamic-mode/">Demo</a>
20711		 * @category lGPublicMethods
20712		 * @example
20713		 *  const plugin = lightGallery();
20714		 *  // Delete or add children, then call
20715		 *  plugin.refresh();
20716		 *
20717		 */
20718		LightGallery.prototype.refresh = function (galleryItems) {
20719			if (!this.settings.dynamic) {
20720				this.invalidateItems();
20721			}
20722			if (galleryItems) {
20723				this.galleryItems = galleryItems;
20724			}
20725			else {
20726				this.galleryItems = this.getItems();
20727			}
20728			this.updateControls();
20729			this.openGalleryOnItemClick();
20730			this.LGel.trigger(lGEvents.updateSlides);
20731		};
20732		LightGallery.prototype.updateControls = function () {
20733			this.addSlideVideoInfo(this.galleryItems);
20734			this.updateCounterTotal();
20735			this.manageSingleSlideClassName();
20736		};
20737		/**
20738		 * Destroy lightGallery.
20739		 * Destroy lightGallery and its plugin instances completely
20740		 *
20741		 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.
20742		 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.
20743		 * You can use refresh method most of the times.
20744		 * @category lGPublicMethods
20745		 * @example
20746		 *  const plugin = lightGallery();
20747		 *  plugin.destroy();
20748		 *
20749		 */
20750		LightGallery.prototype.destroy = function () {
20751			var _this = this;
20752			var closeTimeout = this.closeGallery(true);
20753			setTimeout(function () {
20754				_this.destroyModules(true);
20755				if (!_this.settings.dynamic) {
20756					_this.invalidateItems();
20757				}
20758				$LG(window).off(".lg.global" + _this.lgId);
20759				_this.LGel.off('.lg');
20760				_this.$container.remove();
20761			}, closeTimeout);
20762			return closeTimeout;
20763		};
20764		return LightGallery;
20765	}());
20766
20767	function lightGallery(el, options) {
20768		return new LightGallery(el, options);
20769	}
20770
20771	return lightGallery;
20772
20773})));
20774
20775/*!
20776 * lightgallery | 2.5.0 | June 13th 2022
20777 * http://www.lightgalleryjs.com/
20778 * Copyright (c) 2020 Sachin Neravath;
20779 * @license GPLv3
20780 */
20781
20782(function (global, factory) {
20783	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
20784	typeof define === 'function' && define.amd ? define(factory) :
20785	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory());
20786}(this, (function () { 'use strict';
20787
20788	/*! *****************************************************************************
20789	Copyright (c) Microsoft Corporation.
20790
20791	Permission to use, copy, modify, and/or distribute this software for any
20792	purpose with or without fee is hereby granted.
20793
20794	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
20795	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20796	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
20797	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
20798	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20799	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20800	PERFORMANCE OF THIS SOFTWARE.
20801	***************************************************************************** */
20802
20803	var __assign = function() {
20804		__assign = Object.assign || function __assign(t) {
20805			for (var s, i = 1, n = arguments.length; i < n; i++) {
20806				s = arguments[i];
20807				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
20808			}
20809			return t;
20810		};
20811		return __assign.apply(this, arguments);
20812	};
20813
20814	var zoomSettings = {
20815		scale: 1,
20816		zoom: true,
20817		actualSize: true,
20818		showZoomInOutIcons: false,
20819		actualSizeIcons: {
20820			zoomIn: 'lg-zoom-in',
20821			zoomOut: 'lg-zoom-out',
20822		},
20823		enableZoomAfter: 300,
20824		zoomPluginStrings: {
20825			zoomIn: 'Zoom in',
20826			zoomOut: 'Zoom out',
20827			viewActualSize: 'View actual size',
20828		},
20829	};
20830
20831	/**
20832	 * List of lightGallery events
20833	 * All events should be documented here
20834	 * Below interfaces are used to build the website documentations
20835	 * */
20836	var lGEvents = {
20837		afterAppendSlide: 'lgAfterAppendSlide',
20838		init: 'lgInit',
20839		hasVideo: 'lgHasVideo',
20840		containerResize: 'lgContainerResize',
20841		updateSlides: 'lgUpdateSlides',
20842		afterAppendSubHtml: 'lgAfterAppendSubHtml',
20843		beforeOpen: 'lgBeforeOpen',
20844		afterOpen: 'lgAfterOpen',
20845		slideItemLoad: 'lgSlideItemLoad',
20846		beforeSlide: 'lgBeforeSlide',
20847		afterSlide: 'lgAfterSlide',
20848		posterClick: 'lgPosterClick',
20849		dragStart: 'lgDragStart',
20850		dragMove: 'lgDragMove',
20851		dragEnd: 'lgDragEnd',
20852		beforeNextSlide: 'lgBeforeNextSlide',
20853		beforePrevSlide: 'lgBeforePrevSlide',
20854		beforeClose: 'lgBeforeClose',
20855		afterClose: 'lgAfterClose',
20856		rotateLeft: 'lgRotateLeft',
20857		rotateRight: 'lgRotateRight',
20858		flipHorizontal: 'lgFlipHorizontal',
20859		flipVertical: 'lgFlipVertical',
20860		autoplay: 'lgAutoplay',
20861		autoplayStart: 'lgAutoplayStart',
20862		autoplayStop: 'lgAutoplayStop',
20863	};
20864
20865	var Zoom = /** @class */ (function () {
20866		function Zoom(instance, $LG) {
20867			// get lightGallery core plugin instance
20868			this.core = instance;
20869			this.$LG = $LG;
20870			this.settings = __assign(__assign({}, zoomSettings), this.core.settings);
20871			return this;
20872		}
20873		// Append Zoom controls. Actual size, Zoom-in, Zoom-out
20874		Zoom.prototype.buildTemplates = function () {
20875			var zoomIcons = this.settings.showZoomInOutIcons
20876				? "<button id=\"" + this.core.getIdName('lg-zoom-in') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['zoomIn'] + "\" class=\"lg-zoom-in lg-icon\"></button><button id=\"" + this.core.getIdName('lg-zoom-out') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['zoomIn'] + "\" class=\"lg-zoom-out lg-icon\"></button>"
20877				: '';
20878			if (this.settings.actualSize) {
20879				zoomIcons += "<button id=\"" + this.core.getIdName('lg-actual-size') + "\" type=\"button\" aria-label=\"" + this.settings.zoomPluginStrings['viewActualSize'] + "\" class=\"" + this.settings.actualSizeIcons.zoomIn + " lg-icon\"></button>";
20880			}
20881			this.core.outer.addClass('lg-use-transition-for-zoom');
20882			this.core.$toolbar.first().append(zoomIcons);
20883		};
20884		/**
20885		 * @desc Enable zoom option only once the image is completely loaded
20886		 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted
20887		 *
20888		 * Zoom styles are defined under lg-zoomable CSS class.
20889		 */
20890		Zoom.prototype.enableZoom = function (event) {
20891			var _this = this;
20892			// delay will be 0 except first time
20893			var _speed = this.settings.enableZoomAfter + event.detail.delay;
20894			// set _speed value 0 if gallery opened from direct url and if it is first slide
20895			if (this.$LG('body').first().hasClass('lg-from-hash') &&
20896				event.detail.delay) {
20897				// will execute only once
20898				_speed = 0;
20899			}
20900			else {
20901				// Remove lg-from-hash to enable starting animation.
20902				this.$LG('body').first().removeClass('lg-from-hash');
20903			}
20904			this.zoomableTimeout = setTimeout(function () {
20905				if (!_this.isImageSlide()) {
20906					return;
20907				}
20908				_this.core.getSlideItem(event.detail.index).addClass('lg-zoomable');
20909				if (event.detail.index === _this.core.index) {
20910					_this.setZoomEssentials();
20911				}
20912			}, _speed + 30);
20913		};
20914		Zoom.prototype.enableZoomOnSlideItemLoad = function () {
20915			// Add zoomable class
20916			this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this));
20917		};
20918		Zoom.prototype.getModifier = function (rotateValue, axis, el) {
20919			var originalRotate = rotateValue;
20920			rotateValue = Math.abs(rotateValue);
20921			var transformValues = this.getCurrentTransform(el);
20922			if (!transformValues) {
20923				return 1;
20924			}
20925			var modifier = 1;
20926			if (axis === 'X') {
20927				var flipHorizontalValue = Math.sign(parseFloat(transformValues[0]));
20928				if (rotateValue === 0 || rotateValue === 180) {
20929					modifier = 1;
20930				}
20931				else if (rotateValue === 90) {
20932					if ((originalRotate === -90 && flipHorizontalValue === 1) ||
20933						(originalRotate === 90 && flipHorizontalValue === -1)) {
20934						modifier = -1;
20935					}
20936					else {
20937						modifier = 1;
20938					}
20939				}
20940				modifier = modifier * flipHorizontalValue;
20941			}
20942			else {
20943				var flipVerticalValue = Math.sign(parseFloat(transformValues[3]));
20944				if (rotateValue === 0 || rotateValue === 180) {
20945					modifier = 1;
20946				}
20947				else if (rotateValue === 90) {
20948					var sinX = parseFloat(transformValues[1]);
20949					var sinMinusX = parseFloat(transformValues[2]);
20950					modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue);
20951				}
20952				modifier = modifier * flipVerticalValue;
20953			}
20954			return modifier;
20955		};
20956		Zoom.prototype.getImageSize = function ($image, rotateValue, axis) {
20957			var imageSizes = {
20958				y: 'offsetHeight',
20959				x: 'offsetWidth',
20960			};
20961			if (Math.abs(rotateValue) === 90) {
20962				// Swap axis
20963				if (axis === 'x') {
20964					axis = 'y';
20965				}
20966				else {
20967					axis = 'x';
20968				}
20969			}
20970			return $image[imageSizes[axis]];
20971		};
20972		Zoom.prototype.getDragCords = function (e, rotateValue) {
20973			if (rotateValue === 90) {
20974				return {
20975					x: e.pageY,
20976					y: e.pageX,
20977				};
20978			}
20979			else {
20980				return {
20981					x: e.pageX,
20982					y: e.pageY,
20983				};
20984			}
20985		};
20986		Zoom.prototype.getSwipeCords = function (e, rotateValue) {
20987			var x = e.targetTouches[0].pageX;
20988			var y = e.targetTouches[0].pageY;
20989			if (rotateValue === 90) {
20990				return {
20991					x: y,
20992					y: x,
20993				};
20994			}
20995			else {
20996				return {
20997					x: x,
20998					y: y,
20999				};
21000			}
21001		};
21002		Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) {
21003			scale = scale || this.scale || 1;
21004			var allowY = this.imageYSize * scale > this.containerRect.height;
21005			var allowX = this.imageXSize * scale > this.containerRect.width;
21006			if (rotateValue === 90) {
21007				return {
21008					allowX: allowY,
21009					allowY: allowX,
21010				};
21011			}
21012			else {
21013				return {
21014					allowX: allowX,
21015					allowY: allowY,
21016				};
21017			}
21018		};
21019		/**
21020		 *
21021		 * @param {Element} el
21022		 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0);
21023		 * Get the current transform value
21024		 */
21025		Zoom.prototype.getCurrentTransform = function (el) {
21026			if (!el) {
21027				return;
21028			}
21029			var st = window.getComputedStyle(el, null);
21030			var tm = st.getPropertyValue('-webkit-transform') ||
21031				st.getPropertyValue('-moz-transform') ||
21032				st.getPropertyValue('-ms-transform') ||
21033				st.getPropertyValue('-o-transform') ||
21034				st.getPropertyValue('transform') ||
21035				'none';
21036			if (tm !== 'none') {
21037				return tm.split('(')[1].split(')')[0].split(',');
21038			}
21039			return;
21040		};
21041		Zoom.prototype.getCurrentRotation = function (el) {
21042			if (!el) {
21043				return 0;
21044			}
21045			var values = this.getCurrentTransform(el);
21046			if (values) {
21047				return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) *
21048					(180 / Math.PI));
21049				// If you want rotate in 360
21050				//return (angle < 0 ? angle + 360 : angle);
21051			}
21052			return 0;
21053		};
21054		Zoom.prototype.setZoomEssentials = function () {
21055			var $image = this.core
21056				.getSlideItem(this.core.index)
21057				.find('.lg-image')
21058				.first();
21059			var rotateEl = this.core
21060				.getSlideItem(this.core.index)
21061				.find('.lg-img-rotate')
21062				.first()
21063				.get();
21064			this.rotateValue = this.getCurrentRotation(rotateEl);
21065			this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y');
21066			this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x');
21067			this.containerRect = this.core.outer.get().getBoundingClientRect();
21068			this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl);
21069			this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl);
21070		};
21071		/**
21072		 * @desc Image zoom
21073		 * Translate the wrap and scale the image to get better user experience
21074		 *
21075		 * @param {String} scale - Zoom decrement/increment value
21076		 */
21077		Zoom.prototype.zoomImage = function (scale) {
21078			// Find offset manually to avoid issue after zoom
21079			var offsetX = (this.containerRect.width - this.imageXSize) / 2 +
21080				this.containerRect.left;
21081			var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
21082			var topBottomSpacing = Math.abs(top - bottom) / 2;
21083			var offsetY = (this.containerRect.height -
21084				this.imageYSize -
21085				topBottomSpacing * this.modifierX) /
21086				2 +
21087				this.scrollTop +
21088				this.containerRect.top;
21089			var originalX;
21090			var originalY;
21091			if (scale === 1) {
21092				this.positionChanged = false;
21093			}
21094			var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale);
21095			var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX;
21096			if (this.positionChanged) {
21097				originalX = this.left / (this.scale - 1);
21098				originalY = this.top / (this.scale - 1);
21099				this.pageX = Math.abs(originalX) + offsetX;
21100				this.pageY = Math.abs(originalY) + offsetY;
21101				this.positionChanged = false;
21102			}
21103			var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale);
21104			var _x = offsetX - this.pageX;
21105			var _y = offsetY - this.pageY;
21106			var x = (scale - 1) * _x;
21107			var y = (scale - 1) * _y;
21108			if (allowX) {
21109				if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) {
21110					x = possibleSwipeCords.minX;
21111				}
21112				else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) {
21113					x = possibleSwipeCords.maxX;
21114				}
21115			}
21116			else {
21117				if (scale > 1) {
21118					if (x < possibleSwipeCords.minX) {
21119						x = possibleSwipeCords.minX;
21120					}
21121					else if (x > possibleSwipeCords.maxX) {
21122						x = possibleSwipeCords.maxX;
21123					}
21124				}
21125			}
21126			if (allowY) {
21127				if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) {
21128					y = possibleSwipeCords.minY;
21129				}
21130				else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) {
21131					y = possibleSwipeCords.maxY;
21132				}
21133			}
21134			else {
21135				// If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out
21136				if (scale > 1) {
21137					//If image goes beyond viewport top, use the minim possible translate value
21138					if (y < possibleSwipeCords.minY) {
21139						y = possibleSwipeCords.minY;
21140					}
21141					else if (y > possibleSwipeCords.maxY) {
21142						y = possibleSwipeCords.maxY;
21143					}
21144				}
21145			}
21146			this.setZoomStyles({
21147				x: x,
21148				y: y,
21149				scale: scale,
21150			});
21151		};
21152		/**
21153		 * @desc apply scale3d to image and translate to image wrap
21154		 * @param {style} X,Y and scale
21155		 */
21156		Zoom.prototype.setZoomStyles = function (style) {
21157			var $image = this.core
21158				.getSlideItem(this.core.index)
21159				.find('.lg-image')
21160				.first();
21161			var $dummyImage = this.core.outer
21162				.find('.lg-current .lg-dummy-img')
21163				.first();
21164			var $imageWrap = $image.parent();
21165			this.scale = style.scale;
21166			$image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');
21167			$dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');
21168			var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)';
21169			$imageWrap.css('transform', transform);
21170			this.left = style.x;
21171			this.top = style.y;
21172		};
21173		/**
21174		 * @param index - Index of the current slide
21175		 * @param event - event will be available only if the function is called on clicking/taping the imags
21176		 */
21177		Zoom.prototype.setActualSize = function (index, event) {
21178			var _this = this;
21179			// Allow zoom only on image
21180			if (!this.isImageSlide() ||
21181				this.core.outer.hasClass('lg-first-slide-loading')) {
21182				return;
21183			}
21184			var scale = this.getCurrentImageActualSizeScale();
21185			if (this.core.outer.hasClass('lg-zoomed')) {
21186				this.scale = 1;
21187			}
21188			else {
21189				this.scale = this.getScale(scale);
21190			}
21191			this.setPageCords(event);
21192			this.beginZoom(this.scale);
21193			this.zoomImage(this.scale);
21194			setTimeout(function () {
21195				_this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');
21196			}, 10);
21197		};
21198		Zoom.prototype.getNaturalWidth = function (index) {
21199			var $image = this.core.getSlideItem(index).find('.lg-image').first();
21200			var naturalWidth = this.core.galleryItems[index].width;
21201			return naturalWidth
21202				? parseFloat(naturalWidth)
21203				: $image.get().naturalWidth;
21204		};
21205		Zoom.prototype.getActualSizeScale = function (naturalWidth, width) {
21206			var _scale;
21207			var scale;
21208			if (naturalWidth > width) {
21209				_scale = naturalWidth / width;
21210				scale = _scale || 2;
21211			}
21212			else {
21213				scale = 1;
21214			}
21215			return scale;
21216		};
21217		Zoom.prototype.getCurrentImageActualSizeScale = function () {
21218			var $image = this.core
21219				.getSlideItem(this.core.index)
21220				.find('.lg-image')
21221				.first();
21222			var width = $image.get().offsetWidth;
21223			var naturalWidth = this.getNaturalWidth(this.core.index) || width;
21224			return this.getActualSizeScale(naturalWidth, width);
21225		};
21226		Zoom.prototype.getPageCords = function (event) {
21227			var cords = {};
21228			if (event) {
21229				cords.x = event.pageX || event.targetTouches[0].pageX;
21230				cords.y = event.pageY || event.targetTouches[0].pageY;
21231			}
21232			else {
21233				var containerRect = this.core.outer.get().getBoundingClientRect();
21234				cords.x = containerRect.width / 2 + containerRect.left;
21235				cords.y =
21236					containerRect.height / 2 + this.scrollTop + containerRect.top;
21237			}
21238			return cords;
21239		};
21240		Zoom.prototype.setPageCords = function (event) {
21241			var pageCords = this.getPageCords(event);
21242			this.pageX = pageCords.x;
21243			this.pageY = pageCords.y;
21244		};
21245		// If true, zoomed - in else zoomed out
21246		Zoom.prototype.beginZoom = function (scale) {
21247			this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');
21248			if (scale > 1) {
21249				this.core.outer.addClass('lg-zoomed');
21250				var $actualSize = this.core.getElementById('lg-actual-size');
21251				$actualSize
21252					.removeClass(this.settings.actualSizeIcons.zoomIn)
21253					.addClass(this.settings.actualSizeIcons.zoomOut);
21254			}
21255			else {
21256				this.resetZoom();
21257			}
21258			return scale > 1;
21259		};
21260		Zoom.prototype.getScale = function (scale) {
21261			var actualSizeScale = this.getCurrentImageActualSizeScale();
21262			if (scale < 1) {
21263				scale = 1;
21264			}
21265			else if (scale > actualSizeScale) {
21266				scale = actualSizeScale;
21267			}
21268			return scale;
21269		};
21270		Zoom.prototype.init = function () {
21271			var _this = this;
21272			if (!this.settings.zoom) {
21273				return;
21274			}
21275			this.buildTemplates();
21276			this.enableZoomOnSlideItemLoad();
21277			var tapped = null;
21278			this.core.outer.on('dblclick.lg', function (event) {
21279				if (!_this.$LG(event.target).hasClass('lg-image')) {
21280					return;
21281				}
21282				_this.setActualSize(_this.core.index, event);
21283			});
21284			this.core.outer.on('touchstart.lg', function (event) {
21285				var $target = _this.$LG(event.target);
21286				if (event.targetTouches.length === 1 &&
21287					$target.hasClass('lg-image')) {
21288					if (!tapped) {
21289						tapped = setTimeout(function () {
21290							tapped = null;
21291						}, 300);
21292					}
21293					else {
21294						clearTimeout(tapped);
21295						tapped = null;
21296						event.preventDefault();
21297						_this.setActualSize(_this.core.index, event);
21298					}
21299				}
21300			});
21301			// Update zoom on resize and orientationchange
21302			this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () {
21303				if (!_this.core.lgOpened || !_this.isImageSlide())
21304					return;
21305				_this.setPageCords();
21306				_this.setZoomEssentials();
21307				_this.zoomImage(_this.scale);
21308			});
21309			// Update zoom on resize and orientationchange
21310			this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () {
21311				if (!_this.core.lgOpened)
21312					return;
21313				_this.scrollTop = _this.$LG(window).scrollTop();
21314			});
21315			this.core.getElementById('lg-zoom-out').on('click.lg', function () {
21316				if (_this.core.outer.find('.lg-current .lg-image').get()) {
21317					_this.scale -= _this.settings.scale;
21318					_this.scale = _this.getScale(_this.scale);
21319					_this.beginZoom(_this.scale);
21320					_this.zoomImage(_this.scale);
21321				}
21322			});
21323			this.core.getElementById('lg-zoom-in').on('click.lg', function () {
21324				_this.zoomIn();
21325			});
21326			this.core.getElementById('lg-actual-size').on('click.lg', function () {
21327				_this.setActualSize(_this.core.index);
21328			});
21329			this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () {
21330				_this.core.outer.find('.lg-item').removeClass('lg-zoomable');
21331			});
21332			this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () {
21333				_this.scrollTop = _this.$LG(window).scrollTop();
21334				// Set the initial value center
21335				_this.pageX = _this.core.outer.width() / 2;
21336				_this.pageY = _this.core.outer.height() / 2 + _this.scrollTop;
21337				_this.scale = 1;
21338			});
21339			// Reset zoom on slide change
21340			this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) {
21341				var prevIndex = event.detail.prevIndex;
21342				_this.scale = 1;
21343				_this.positionChanged = false;
21344				_this.resetZoom(prevIndex);
21345				if (_this.isImageSlide()) {
21346					_this.setZoomEssentials();
21347				}
21348			});
21349			// Drag option after zoom
21350			this.zoomDrag();
21351			this.pinchZoom();
21352			this.zoomSwipe();
21353			// Store the zoomable timeout value just to clear it while closing
21354			this.zoomableTimeout = false;
21355			this.positionChanged = false;
21356		};
21357		Zoom.prototype.zoomIn = function (scale) {
21358			// Allow zoom only on image
21359			if (!this.isImageSlide()) {
21360				return;
21361			}
21362			if (scale) {
21363				this.scale = scale;
21364			}
21365			else {
21366				this.scale += this.settings.scale;
21367			}
21368			this.scale = this.getScale(this.scale);
21369			this.beginZoom(this.scale);
21370			this.zoomImage(this.scale);
21371		};
21372		// Reset zoom effect
21373		Zoom.prototype.resetZoom = function (index) {
21374			this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition');
21375			var $actualSize = this.core.getElementById('lg-actual-size');
21376			var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index);
21377			$actualSize
21378				.removeClass(this.settings.actualSizeIcons.zoomOut)
21379				.addClass(this.settings.actualSizeIcons.zoomIn);
21380			$item.find('.lg-img-wrap').first().removeAttr('style');
21381			$item.find('.lg-image').first().removeAttr('style');
21382			this.scale = 1;
21383			this.left = 0;
21384			this.top = 0;
21385			// Reset pagx pagy values to center
21386			this.setPageCords();
21387		};
21388		Zoom.prototype.getTouchDistance = function (e) {
21389			return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) *
21390				(e.targetTouches[0].pageX - e.targetTouches[1].pageX) +
21391				(e.targetTouches[0].pageY - e.targetTouches[1].pageY) *
21392					(e.targetTouches[0].pageY - e.targetTouches[1].pageY));
21393		};
21394		Zoom.prototype.pinchZoom = function () {
21395			var _this = this;
21396			var startDist = 0;
21397			var pinchStarted = false;
21398			var initScale = 1;
21399			var $item = this.core.getSlideItem(this.core.index);
21400			this.core.$inner.on('touchstart.lg', function (e) {
21401				$item = _this.core.getSlideItem(_this.core.index);
21402				if (!_this.isImageSlide()) {
21403					return;
21404				}
21405				if (e.targetTouches.length === 2 &&
21406					!_this.core.outer.hasClass('lg-first-slide-loading') &&
21407					(_this.$LG(e.target).hasClass('lg-item') ||
21408						$item.get().contains(e.target))) {
21409					initScale = _this.scale || 1;
21410					_this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');
21411					_this.core.touchAction = 'pinch';
21412					startDist = _this.getTouchDistance(e);
21413				}
21414			});
21415			this.core.$inner.on('touchmove.lg', function (e) {
21416				if (e.targetTouches.length === 2 &&
21417					_this.core.touchAction === 'pinch' &&
21418					(_this.$LG(e.target).hasClass('lg-item') ||
21419						$item.get().contains(e.target))) {
21420					e.preventDefault();
21421					var endDist = _this.getTouchDistance(e);
21422					var distance = startDist - endDist;
21423					if (!pinchStarted && Math.abs(distance) > 5) {
21424						pinchStarted = true;
21425					}
21426					if (pinchStarted) {
21427						_this.scale = Math.max(1, initScale + -distance * 0.008);
21428						_this.zoomImage(_this.scale);
21429					}
21430				}
21431			});
21432			this.core.$inner.on('touchend.lg', function (e) {
21433				if (_this.core.touchAction === 'pinch' &&
21434					(_this.$LG(e.target).hasClass('lg-item') ||
21435						$item.get().contains(e.target))) {
21436					pinchStarted = false;
21437					startDist = 0;
21438					if (_this.scale <= 1) {
21439						_this.resetZoom();
21440					}
21441					else {
21442						_this.scale = _this.getScale(_this.scale);
21443						_this.zoomImage(_this.scale);
21444						_this.core.outer.addClass('lg-zoomed');
21445					}
21446					_this.core.touchAction = undefined;
21447				}
21448			});
21449		};
21450		Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) {
21451			var distanceXnew = endCoords.x - startCoords.x;
21452			var distanceYnew = endCoords.y - startCoords.y;
21453			var speedX = Math.abs(distanceXnew) / touchDuration + 1;
21454			var speedY = Math.abs(distanceYnew) / touchDuration + 1;
21455			if (speedX > 2) {
21456				speedX += 1;
21457			}
21458			if (speedY > 2) {
21459				speedY += 1;
21460			}
21461			distanceXnew = distanceXnew * speedX;
21462			distanceYnew = distanceYnew * speedY;
21463			var _LGel = this.core
21464				.getSlideItem(this.core.index)
21465				.find('.lg-img-wrap')
21466				.first();
21467			var distance = {};
21468			distance.x = this.left + distanceXnew * this.modifierX;
21469			distance.y = this.top + distanceYnew * this.modifierY;
21470			var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue);
21471			if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) {
21472				if (allowY) {
21473					if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
21474						distance.y = possibleSwipeCords.minY;
21475					}
21476					else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
21477						distance.y = possibleSwipeCords.maxY;
21478					}
21479				}
21480				if (allowX) {
21481					if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
21482						distance.x = possibleSwipeCords.minX;
21483					}
21484					else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
21485						distance.x = possibleSwipeCords.maxX;
21486					}
21487				}
21488				if (allowY) {
21489					this.top = distance.y;
21490				}
21491				else {
21492					distance.y = this.top;
21493				}
21494				if (allowX) {
21495					this.left = distance.x;
21496				}
21497				else {
21498					distance.x = this.left;
21499				}
21500				this.setZoomSwipeStyles(_LGel, distance);
21501				this.positionChanged = true;
21502			}
21503		};
21504		Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) {
21505			var distance = {};
21506			if (allowY) {
21507				distance.y =
21508					this.top + (endCoords.y - startCoords.y) * this.modifierY;
21509				if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
21510					var diffMinY = possibleSwipeCords.minY - distance.y;
21511					distance.y = possibleSwipeCords.minY - diffMinY / 6;
21512				}
21513				else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
21514					var diffMaxY = distance.y - possibleSwipeCords.maxY;
21515					distance.y = possibleSwipeCords.maxY + diffMaxY / 6;
21516				}
21517			}
21518			else {
21519				distance.y = this.top;
21520			}
21521			if (allowX) {
21522				distance.x =
21523					this.left + (endCoords.x - startCoords.x) * this.modifierX;
21524				if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
21525					var diffMinX = possibleSwipeCords.minX - distance.x;
21526					distance.x = possibleSwipeCords.minX - diffMinX / 6;
21527				}
21528				else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
21529					var difMaxX = distance.x - possibleSwipeCords.maxX;
21530					distance.x = possibleSwipeCords.maxX + difMaxX / 6;
21531				}
21532			}
21533			else {
21534				distance.x = this.left;
21535			}
21536			return distance;
21537		};
21538		Zoom.prototype.isBeyondPossibleLeft = function (x, minX) {
21539			return x >= minX;
21540		};
21541		Zoom.prototype.isBeyondPossibleRight = function (x, maxX) {
21542			return x <= maxX;
21543		};
21544		Zoom.prototype.isBeyondPossibleTop = function (y, minY) {
21545			return y >= minY;
21546		};
21547		Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) {
21548			return y <= maxY;
21549		};
21550		Zoom.prototype.isImageSlide = function () {
21551			var currentItem = this.core.galleryItems[this.core.index];
21552			return this.core.getSlideType(currentItem) === 'image';
21553		};
21554		Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) {
21555			var dataScale = scale || this.scale || 1;
21556			var elDataScale = Math.abs(dataScale);
21557			var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
21558			var topBottomSpacing = Math.abs(top - bottom) / 2;
21559			var minY = (this.imageYSize - this.containerRect.height) / 2 +
21560				topBottomSpacing * this.modifierX;
21561			var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY;
21562			var minX = (this.imageXSize - this.containerRect.width) / 2;
21563			var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX;
21564			var possibleSwipeCords = {
21565				minY: minY,
21566				maxY: maxY,
21567				minX: minX,
21568				maxX: maxX,
21569			};
21570			if (Math.abs(rotateValue) === 90) {
21571				possibleSwipeCords = {
21572					minY: minX,
21573					maxY: maxX,
21574					minX: minY,
21575					maxX: maxY,
21576				};
21577			}
21578			return possibleSwipeCords;
21579		};
21580		Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) {
21581			LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)');
21582		};
21583		Zoom.prototype.zoomSwipe = function () {
21584			var _this = this;
21585			var startCoords = {};
21586			var endCoords = {};
21587			var isMoved = false;
21588			// Allow x direction drag
21589			var allowX = false;
21590			// Allow Y direction drag
21591			var allowY = false;
21592			var startTime = new Date();
21593			var endTime = new Date();
21594			var possibleSwipeCords;
21595			var _LGel;
21596			var $item = this.core.getSlideItem(this.core.index);
21597			this.core.$inner.on('touchstart.lg', function (e) {
21598				// Allow zoom only on image
21599				if (!_this.isImageSlide()) {
21600					return;
21601				}
21602				$item = _this.core.getSlideItem(_this.core.index);
21603				if ((_this.$LG(e.target).hasClass('lg-item') ||
21604					$item.get().contains(e.target)) &&
21605					e.targetTouches.length === 1 &&
21606					_this.core.outer.hasClass('lg-zoomed')) {
21607					e.preventDefault();
21608					startTime = new Date();
21609					_this.core.touchAction = 'zoomSwipe';
21610					_LGel = _this.core
21611						.getSlideItem(_this.core.index)
21612						.find('.lg-img-wrap')
21613						.first();
21614					var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue));
21615					allowY = dragAllowedAxises.allowY;
21616					allowX = dragAllowedAxises.allowX;
21617					if (allowX || allowY) {
21618						startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue));
21619					}
21620					possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue);
21621					// reset opacity and transition duration
21622					_this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition');
21623				}
21624			});
21625			this.core.$inner.on('touchmove.lg', function (e) {
21626				if (e.targetTouches.length === 1 &&
21627					_this.core.touchAction === 'zoomSwipe' &&
21628					(_this.$LG(e.target).hasClass('lg-item') ||
21629						$item.get().contains(e.target))) {
21630					e.preventDefault();
21631					_this.core.touchAction = 'zoomSwipe';
21632					endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue));
21633					var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);
21634					if (Math.abs(endCoords.x - startCoords.x) > 15 ||
21635						Math.abs(endCoords.y - startCoords.y) > 15) {
21636						isMoved = true;
21637						_this.setZoomSwipeStyles(_LGel, distance);
21638					}
21639				}
21640			});
21641			this.core.$inner.on('touchend.lg', function (e) {
21642				if (_this.core.touchAction === 'zoomSwipe' &&
21643					(_this.$LG(e.target).hasClass('lg-item') ||
21644						$item.get().contains(e.target))) {
21645					_this.core.touchAction = undefined;
21646					_this.core.outer.removeClass('lg-zoom-dragging');
21647					if (!isMoved) {
21648						return;
21649					}
21650					isMoved = false;
21651					endTime = new Date();
21652					var touchDuration = endTime.valueOf() - startTime.valueOf();
21653					_this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue);
21654				}
21655			});
21656		};
21657		Zoom.prototype.zoomDrag = function () {
21658			var _this = this;
21659			var startCoords = {};
21660			var endCoords = {};
21661			var isDragging = false;
21662			var isMoved = false;
21663			// Allow x direction drag
21664			var allowX = false;
21665			// Allow Y direction drag
21666			var allowY = false;
21667			var startTime;
21668			var endTime;
21669			var possibleSwipeCords;
21670			var _LGel;
21671			this.core.outer.on('mousedown.lg.zoom', function (e) {
21672				// Allow zoom only on image
21673				if (!_this.isImageSlide()) {
21674					return;
21675				}
21676				var $item = _this.core.getSlideItem(_this.core.index);
21677				if (_this.$LG(e.target).hasClass('lg-item') ||
21678					$item.get().contains(e.target)) {
21679					startTime = new Date();
21680					_LGel = _this.core
21681						.getSlideItem(_this.core.index)
21682						.find('.lg-img-wrap')
21683						.first();
21684					var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue));
21685					allowY = dragAllowedAxises.allowY;
21686					allowX = dragAllowedAxises.allowX;
21687					if (_this.core.outer.hasClass('lg-zoomed')) {
21688						if (_this.$LG(e.target).hasClass('lg-object') &&
21689							(allowX || allowY)) {
21690							e.preventDefault();
21691							startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
21692							possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue);
21693							isDragging = true;
21694							// ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
21695							_this.core.outer.get().scrollLeft += 1;
21696							_this.core.outer.get().scrollLeft -= 1;
21697							_this.core.outer
21698								.removeClass('lg-grab')
21699								.addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging');
21700							// reset opacity and transition duration
21701						}
21702					}
21703				}
21704			});
21705			this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) {
21706				if (isDragging) {
21707					isMoved = true;
21708					endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
21709					var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);
21710					_this.setZoomSwipeStyles(_LGel, distance);
21711				}
21712			});
21713			this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) {
21714				if (isDragging) {
21715					endTime = new Date();
21716					isDragging = false;
21717					_this.core.outer.removeClass('lg-zoom-dragging');
21718					// Fix for chrome mouse move on click
21719					if (isMoved &&
21720						(startCoords.x !== endCoords.x ||
21721							startCoords.y !== endCoords.y)) {
21722						endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
21723						var touchDuration = endTime.valueOf() - startTime.valueOf();
21724						_this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue);
21725					}
21726					isMoved = false;
21727				}
21728				_this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');
21729			});
21730		};
21731		Zoom.prototype.closeGallery = function () {
21732			this.resetZoom();
21733		};
21734		Zoom.prototype.destroy = function () {
21735			// Unbind all events added by lightGallery zoom plugin
21736			this.$LG(window).off(".lg.zoom.global" + this.core.lgId);
21737			this.core.LGel.off('.lg.zoom');
21738			this.core.LGel.off('.zoom');
21739			clearTimeout(this.zoomableTimeout);
21740			this.zoomableTimeout = false;
21741		};
21742		return Zoom;
21743	}());
21744
21745	return Zoom;
21746
21747})));
21748/*!
21749 * lightgallery | 2.5.0 | June 13th 2022
21750 * http://www.lightgalleryjs.com/
21751 * Copyright (c) 2020 Sachin Neravath;
21752 * @license GPLv3
21753 */
21754
21755(function (global, factory) {
21756	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
21757	typeof define === 'function' && define.amd ? define(factory) :
21758	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory());
21759}(this, (function () { 'use strict';
21760
21761	/*! *****************************************************************************
21762	Copyright (c) Microsoft Corporation.
21763
21764	Permission to use, copy, modify, and/or distribute this software for any
21765	purpose with or without fee is hereby granted.
21766
21767	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
21768	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21769	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
21770	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21771	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21772	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21773	PERFORMANCE OF THIS SOFTWARE.
21774	***************************************************************************** */
21775
21776	var __assign = function() {
21777		__assign = Object.assign || function __assign(t) {
21778			for (var s, i = 1, n = arguments.length; i < n; i++) {
21779				s = arguments[i];
21780				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
21781			}
21782			return t;
21783		};
21784		return __assign.apply(this, arguments);
21785	};
21786
21787	var fullscreenSettings = {
21788		fullScreen: true,
21789		fullscreenPluginStrings: {
21790			toggleFullscreen: 'Toggle Fullscreen',
21791		},
21792	};
21793
21794	var FullScreen = /** @class */ (function () {
21795		function FullScreen(instance, $LG) {
21796			// get lightGallery core plugin instance
21797			this.core = instance;
21798			this.$LG = $LG;
21799			// extend module default settings with lightGallery core settings
21800			this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings);
21801			return this;
21802		}
21803		FullScreen.prototype.init = function () {
21804			var fullScreen = '';
21805			if (this.settings.fullScreen) {
21806				// check for fullscreen browser support
21807				if (!document.fullscreenEnabled &&
21808					!document.webkitFullscreenEnabled &&
21809					!document.mozFullScreenEnabled &&
21810					!document.msFullscreenEnabled) {
21811					return;
21812				}
21813				else {
21814					fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>";
21815					this.core.$toolbar.append(fullScreen);
21816					this.fullScreen();
21817				}
21818			}
21819		};
21820		FullScreen.prototype.isFullScreen = function () {
21821			return (document.fullscreenElement ||
21822				document.mozFullScreenElement ||
21823				document.webkitFullscreenElement ||
21824				document.msFullscreenElement);
21825		};
21826		FullScreen.prototype.requestFullscreen = function () {
21827			var el = document.documentElement;
21828			if (el.requestFullscreen) {
21829				el.requestFullscreen();
21830			}
21831			else if (el.msRequestFullscreen) {
21832				el.msRequestFullscreen();
21833			}
21834			else if (el.mozRequestFullScreen) {
21835				el.mozRequestFullScreen();
21836			}
21837			else if (el.webkitRequestFullscreen) {
21838				el.webkitRequestFullscreen();
21839			}
21840		};
21841		FullScreen.prototype.exitFullscreen = function () {
21842			if (document.exitFullscreen) {
21843				document.exitFullscreen();
21844			}
21845			else if (document.msExitFullscreen) {
21846				document.msExitFullscreen();
21847			}
21848			else if (document.mozCancelFullScreen) {
21849				document.mozCancelFullScreen();
21850			}
21851			else if (document.webkitExitFullscreen) {
21852				document.webkitExitFullscreen();
21853			}
21854		};
21855		// https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode
21856		FullScreen.prototype.fullScreen = function () {
21857			var _this = this;
21858			this.$LG(document).on("fullscreenchange.lg.global" + this.core.lgId + " \n            webkitfullscreenchange.lg.global" + this.core.lgId + " \n            mozfullscreenchange.lg.global" + this.core.lgId + " \n            MSFullscreenChange.lg.global" + this.core.lgId, function () {
21859				if (!_this.core.lgOpened)
21860					return;
21861				_this.core.outer.toggleClass('lg-fullscreen-on');
21862			});
21863			this.core.outer
21864				.find('.lg-fullscreen')
21865				.first()
21866				.on('click.lg', function () {
21867				if (_this.isFullScreen()) {
21868					_this.exitFullscreen();
21869				}
21870				else {
21871					_this.requestFullscreen();
21872				}
21873			});
21874		};
21875		FullScreen.prototype.closeGallery = function () {
21876			// exit from fullscreen if activated
21877			if (this.isFullScreen()) {
21878				this.exitFullscreen();
21879			}
21880		};
21881		FullScreen.prototype.destroy = function () {
21882			this.$LG(document).off("fullscreenchange.lg.global" + this.core.lgId + " \n            webkitfullscreenchange.lg.global" + this.core.lgId + " \n            mozfullscreenchange.lg.global" + this.core.lgId + " \n            MSFullscreenChange.lg.global" + this.core.lgId);
21883		};
21884		return FullScreen;
21885	}());
21886
21887	return FullScreen;
21888
21889})));
21890
21891/*!
21892 * lightgallery | 2.5.0 | June 13th 2022
21893 * http://www.lightgalleryjs.com/
21894 * Copyright (c) 2020 Sachin Neravath;
21895 * @license GPLv3
21896 */
21897
21898(function (global, factory) {
21899	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
21900	typeof define === 'function' && define.amd ? define(factory) :
21901	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory());
21902}(this, (function () { 'use strict';
21903
21904	/*! *****************************************************************************
21905	Copyright (c) Microsoft Corporation.
21906
21907	Permission to use, copy, modify, and/or distribute this software for any
21908	purpose with or without fee is hereby granted.
21909
21910	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
21911	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21912	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
21913	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21914	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21915	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21916	PERFORMANCE OF THIS SOFTWARE.
21917	***************************************************************************** */
21918
21919	var __assign = function() {
21920		__assign = Object.assign || function __assign(t) {
21921			for (var s, i = 1, n = arguments.length; i < n; i++) {
21922				s = arguments[i];
21923				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
21924			}
21925			return t;
21926		};
21927		return __assign.apply(this, arguments);
21928	};
21929
21930	/**
21931	 * List of lightGallery events
21932	 * All events should be documented here
21933	 * Below interfaces are used to build the website documentations
21934	 * */
21935	var lGEvents = {
21936		afterAppendSlide: 'lgAfterAppendSlide',
21937		init: 'lgInit',
21938		hasVideo: 'lgHasVideo',
21939		containerResize: 'lgContainerResize',
21940		updateSlides: 'lgUpdateSlides',
21941		afterAppendSubHtml: 'lgAfterAppendSubHtml',
21942		beforeOpen: 'lgBeforeOpen',
21943		afterOpen: 'lgAfterOpen',
21944		slideItemLoad: 'lgSlideItemLoad',
21945		beforeSlide: 'lgBeforeSlide',
21946		afterSlide: 'lgAfterSlide',
21947		posterClick: 'lgPosterClick',
21948		dragStart: 'lgDragStart',
21949		dragMove: 'lgDragMove',
21950		dragEnd: 'lgDragEnd',
21951		beforeNextSlide: 'lgBeforeNextSlide',
21952		beforePrevSlide: 'lgBeforePrevSlide',
21953		beforeClose: 'lgBeforeClose',
21954		afterClose: 'lgAfterClose',
21955		rotateLeft: 'lgRotateLeft',
21956		rotateRight: 'lgRotateRight',
21957		flipHorizontal: 'lgFlipHorizontal',
21958		flipVertical: 'lgFlipVertical',
21959		autoplay: 'lgAutoplay',
21960		autoplayStart: 'lgAutoplayStart',
21961		autoplayStop: 'lgAutoplayStop',
21962	};
21963
21964	var hashSettings = {
21965		hash: true,
21966		galleryId: '1',
21967		customSlideName: false,
21968	};
21969
21970	var Hash = /** @class */ (function () {
21971		function Hash(instance, $LG) {
21972			// get lightGallery core plugin instance
21973			this.core = instance;
21974			this.$LG = $LG;
21975			// extend module default settings with lightGallery core settings
21976			this.settings = __assign(__assign({}, hashSettings), this.core.settings);
21977			return this;
21978		}
21979		Hash.prototype.init = function () {
21980			var _this = this;
21981			if (!this.settings.hash) {
21982				return;
21983			}
21984			this.oldHash = window.location.hash;
21985			setTimeout(function () {
21986				_this.buildFromHash();
21987			}, 100);
21988			// Change hash value on after each slide transition
21989			this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this));
21990			this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this));
21991			// Listen hash change and change the slide according to slide value
21992			this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this));
21993		};
21994		Hash.prototype.onAfterSlide = function (event) {
21995			var slideName = this.core.galleryItems[event.detail.index].slideName;
21996			slideName = this.settings.customSlideName
21997				? slideName || event.detail.index
21998				: event.detail.index;
21999			if (history.replaceState) {
22000				history.replaceState(null, '', window.location.pathname +
22001					window.location.search +
22002					'#lg=' +
22003					this.settings.galleryId +
22004					'&slide=' +
22005					slideName);
22006			}
22007			else {
22008				window.location.hash =
22009					'lg=' + this.settings.galleryId + '&slide=' + slideName;
22010			}
22011		};
22012		/**
22013		 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin
22014		 * @param {String} hash
22015		 * @returns {Number} Index of the slide.
22016		 */
22017		Hash.prototype.getIndexFromUrl = function (hash) {
22018			if (hash === void 0) { hash = window.location.hash; }
22019			var slideName = hash.split('&slide=')[1];
22020			var _idx = 0;
22021			if (this.settings.customSlideName) {
22022				for (var index = 0; index < this.core.galleryItems.length; index++) {
22023					var dynamicEl = this.core.galleryItems[index];
22024					if (dynamicEl.slideName === slideName) {
22025						_idx = index;
22026						break;
22027					}
22028				}
22029			}
22030			else {
22031				_idx = parseInt(slideName, 10);
22032			}
22033			return isNaN(_idx) ? 0 : _idx;
22034		};
22035		// Build Gallery if gallery id exist in the URL
22036		Hash.prototype.buildFromHash = function () {
22037			// if dynamic option is enabled execute immediately
22038			var _hash = window.location.hash;
22039			//Uncode edit ##START##
22040			// if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) {
22041			if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) {
22042			//Uncode edit ##END##
22043				// This class is used to remove the initial animation if galleryId present in the URL
22044				this.$LG(document.body).addClass('lg-from-hash');
22045				var index = this.getIndexFromUrl(_hash);
22046				this.core.openGallery(index);
22047				return true;
22048			}
22049		};
22050		Hash.prototype.onCloseAfter = function () {
22051			// Reset to old hash value
22052			if (this.oldHash &&
22053				this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) {
22054				if (history.replaceState) {
22055					history.replaceState(null, '', this.oldHash);
22056				}
22057				else {
22058					window.location.hash = this.oldHash;
22059				}
22060			}
22061			else {
22062				if (history.replaceState) {
22063					history.replaceState(null, document.title, window.location.pathname + window.location.search);
22064				}
22065				else {
22066					window.location.hash = '';
22067				}
22068			}
22069		};
22070		Hash.prototype.onHashchange = function () {
22071			if (!this.core.lgOpened)
22072				return;
22073			var _hash = window.location.hash;
22074			var index = this.getIndexFromUrl(_hash);
22075			// it galleryId doesn't exist in the url close the gallery
22076			if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) {
22077				this.core.slide(index, false, false);
22078			}
22079			else if (this.core.lGalleryOn) {
22080				this.core.closeGallery();
22081			}
22082		};
22083		Hash.prototype.closeGallery = function () {
22084			if (this.settings.hash) {
22085				this.$LG(document.body).removeClass('lg-from-hash');
22086			}
22087		};
22088		Hash.prototype.destroy = function () {
22089			this.core.LGel.off('.lg.hash');
22090			this.core.LGel.off('.hash');
22091			this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId);
22092		};
22093		return Hash;
22094	}());
22095
22096	return Hash;
22097
22098})));
22099/*!
22100 * lightgallery | 2.5.0 | June 13th 2022
22101 * http://www.lightgalleryjs.com/
22102 * Copyright (c) 2020 Sachin Neravath;
22103 * @license GPLv3
22104 */
22105
22106(function (global, factory) {
22107	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
22108	typeof define === 'function' && define.amd ? define(factory) :
22109	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory());
22110}(this, (function () { 'use strict';
22111
22112	/*! *****************************************************************************
22113	Copyright (c) Microsoft Corporation.
22114
22115	Permission to use, copy, modify, and/or distribute this software for any
22116	purpose with or without fee is hereby granted.
22117
22118	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22119	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22120	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22121	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22122	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22123	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22124	PERFORMANCE OF THIS SOFTWARE.
22125	***************************************************************************** */
22126
22127	var __assign = function() {
22128		__assign = Object.assign || function __assign(t) {
22129			for (var s, i = 1, n = arguments.length; i < n; i++) {
22130				s = arguments[i];
22131				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
22132			}
22133			return t;
22134		};
22135		return __assign.apply(this, arguments);
22136	};
22137
22138	function __spreadArrays() {
22139		for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
22140		for (var r = Array(s), k = 0, i = 0; i < il; i++)
22141			for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
22142				r[k] = a[j];
22143		return r;
22144	}
22145
22146	var shareSettings = {
22147		share: true,
22148		facebook: true,
22149		facebookDropdownText: 'Facebook',
22150		twitter: true,
22151		twitterDropdownText: 'Twitter',
22152		pinterest: true,
22153		pinterestDropdownText: 'Pinterest',
22154		additionalShareOptions: [],
22155		sharePluginStrings: { share: 'Share' },
22156	};
22157
22158	function getFacebookShareLink(galleryItem) {
22159		var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u=';
22160		return (facebookBaseUrl +
22161			encodeURIComponent(galleryItem.facebookShareUrl || window.location.href));
22162	}
22163
22164	function getTwitterShareLink(galleryItem) {
22165		var twitterBaseUrl = '//twitter.com/intent/tweet?text=';
22166		var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href);
22167		var text = galleryItem.tweetText;
22168		return twitterBaseUrl + text + '&url=' + url;
22169	}
22170
22171	function getPinterestShareLink(galleryItem) {
22172		var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url=';
22173		var description = galleryItem.pinterestText;
22174		var media = encodeURIComponent(galleryItem.src);
22175		var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href);
22176		return (pinterestBaseUrl +
22177			url +
22178			'&media=' +
22179			media +
22180			'&description=' +
22181			description);
22182	}
22183
22184	/**
22185	 * List of lightGallery events
22186	 * All events should be documented here
22187	 * Below interfaces are used to build the website documentations
22188	 * */
22189	var lGEvents = {
22190		afterAppendSlide: 'lgAfterAppendSlide',
22191		init: 'lgInit',
22192		hasVideo: 'lgHasVideo',
22193		containerResize: 'lgContainerResize',
22194		updateSlides: 'lgUpdateSlides',
22195		afterAppendSubHtml: 'lgAfterAppendSubHtml',
22196		beforeOpen: 'lgBeforeOpen',
22197		afterOpen: 'lgAfterOpen',
22198		slideItemLoad: 'lgSlideItemLoad',
22199		beforeSlide: 'lgBeforeSlide',
22200		afterSlide: 'lgAfterSlide',
22201		posterClick: 'lgPosterClick',
22202		dragStart: 'lgDragStart',
22203		dragMove: 'lgDragMove',
22204		dragEnd: 'lgDragEnd',
22205		beforeNextSlide: 'lgBeforeNextSlide',
22206		beforePrevSlide: 'lgBeforePrevSlide',
22207		beforeClose: 'lgBeforeClose',
22208		afterClose: 'lgAfterClose',
22209		rotateLeft: 'lgRotateLeft',
22210		rotateRight: 'lgRotateRight',
22211		flipHorizontal: 'lgFlipHorizontal',
22212		flipVertical: 'lgFlipVertical',
22213		autoplay: 'lgAutoplay',
22214		autoplayStart: 'lgAutoplayStart',
22215		autoplayStop: 'lgAutoplayStop',
22216	};
22217
22218	var Share = /** @class */ (function () {
22219		function Share(instance) {
22220			this.shareOptions = [];
22221			// get lightGallery core plugin instance
22222			this.core = instance;
22223			// extend module default settings with lightGallery core settings
22224			this.settings = __assign(__assign({}, shareSettings), this.core.settings);
22225			return this;
22226		}
22227		Share.prototype.init = function () {
22228			if (!this.settings.share) {
22229				return;
22230			}
22231			this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions);
22232			this.setLgShareMarkup();
22233			this.core.outer
22234				.find('.lg-share .lg-dropdown')
22235				.append(this.getShareListHtml());
22236			this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this));
22237		};
22238		Share.prototype.getShareListHtml = function () {
22239			var shareHtml = '';
22240			this.shareOptions.forEach(function (shareOption) {
22241				shareHtml += shareOption.dropdownHTML;
22242			});
22243			return shareHtml;
22244		};
22245		Share.prototype.setLgShareMarkup = function () {
22246			var _this = this;
22247			this.core.$toolbar.append("<button type=\"button\" aria-label=\"" + this.settings.sharePluginStrings['share'] + "\" aria-haspopup=\"true\" aria-expanded=\"false\" class=\"lg-share lg-icon\">\n                <ul class=\"lg-dropdown\" style=\"position: absolute;\"></ul></button>");
22248			this.core.outer.append('<div class="lg-dropdown-overlay"></div>');
22249			var $shareButton = this.core.outer.find('.lg-share');
22250			$shareButton.first().on('click.lg', function () {
22251				_this.core.outer.toggleClass('lg-dropdown-active');
22252				if (_this.core.outer.hasClass('lg-dropdown-active')) {
22253					_this.core.outer.attr('aria-expanded', true);
22254				}
22255				else {
22256					_this.core.outer.attr('aria-expanded', false);
22257				}
22258			});
22259			this.core.outer
22260				.find('.lg-dropdown-overlay')
22261				.first()
22262				.on('click.lg', function () {
22263				_this.core.outer.removeClass('lg-dropdown-active');
22264				_this.core.outer.attr('aria-expanded', false);
22265			});
22266		};
22267		Share.prototype.onAfterSlide = function (event) {
22268			var _this = this;
22269			var index = event.detail.index;
22270			var currentItem = this.core.galleryItems[index];
22271			setTimeout(function () {
22272				_this.shareOptions.forEach(function (shareOption) {
22273					var selector = shareOption.selector;
22274					_this.core.outer
22275						.find(selector)
22276						.attr('href', shareOption.generateLink(currentItem));
22277				});
22278			}, 100);
22279		};
22280		Share.prototype.getShareListItemHTML = function (type, text) {
22281			return "<li><a class=\"lg-share-" + type + "\" rel=\"noopener\" target=\"_blank\"><span class=\"lg-icon\"></span><span class=\"lg-dropdown-text\">" + text + "</span></a></li>";
22282		};
22283		Share.prototype.getDefaultShareOptions = function () {
22284			return __spreadArrays((this.settings.facebook
22285				? [
22286					{
22287						type: 'facebook',
22288						generateLink: getFacebookShareLink,
22289						dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText),
22290						selector: '.lg-share-facebook',
22291					},
22292				]
22293				: []), (this.settings.twitter
22294				? [
22295					{
22296						type: 'twitter',
22297						generateLink: getTwitterShareLink,
22298						dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText),
22299						selector: '.lg-share-twitter',
22300					},
22301				]
22302				: []), (this.settings.pinterest
22303				? [
22304					{
22305						type: 'pinterest',
22306						generateLink: getPinterestShareLink,
22307						dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText),
22308						selector: '.lg-share-pinterest',
22309					},
22310				]
22311				: []));
22312		};
22313		Share.prototype.destroy = function () {
22314			this.core.outer.find('.lg-dropdown-overlay').remove();
22315			this.core.outer.find('.lg-share').remove();
22316			this.core.LGel.off('.lg.share');
22317			this.core.LGel.off('.share');
22318		};
22319		return Share;
22320	}());
22321
22322	return Share;
22323
22324})));
22325/*!
22326 * lightgallery | 2.5.0 | June 13th 2022
22327 * http://www.lightgalleryjs.com/
22328 * Copyright (c) 2020 Sachin Neravath;
22329 * @license GPLv3
22330 */
22331
22332(function (global, factory) {
22333	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
22334	typeof define === 'function' && define.amd ? define(factory) :
22335	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory());
22336}(this, (function () { 'use strict';
22337
22338	/*! *****************************************************************************
22339	Copyright (c) Microsoft Corporation.
22340
22341	Permission to use, copy, modify, and/or distribute this software for any
22342	purpose with or without fee is hereby granted.
22343
22344	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22345	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22346	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22347	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22348	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22349	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22350	PERFORMANCE OF THIS SOFTWARE.
22351	***************************************************************************** */
22352
22353	var __assign = function() {
22354		__assign = Object.assign || function __assign(t) {
22355			for (var s, i = 1, n = arguments.length; i < n; i++) {
22356				s = arguments[i];
22357				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
22358			}
22359			return t;
22360		};
22361		return __assign.apply(this, arguments);
22362	};
22363
22364	var thumbnailsSettings = {
22365		thumbnail: true,
22366		animateThumb: true,
22367		currentPagerPosition: 'middle',
22368		alignThumbnails: 'middle',
22369		thumbWidth: 100,
22370		thumbHeight: '80px',
22371		thumbMargin: 5,
22372		appendThumbnailsTo: '.lg-components',
22373		toggleThumb: false,
22374		enableThumbDrag: true,
22375		enableThumbSwipe: true,
22376		thumbnailSwipeThreshold: 10,
22377		loadYouTubeThumbnail: true,
22378		youTubeThumbSize: 1,
22379		thumbnailPluginStrings: {
22380			toggleThumbnails: 'Toggle thumbnails',
22381		},
22382	};
22383
22384	/**
22385	 * List of lightGallery events
22386	 * All events should be documented here
22387	 * Below interfaces are used to build the website documentations
22388	 * */
22389	var lGEvents = {
22390		afterAppendSlide: 'lgAfterAppendSlide',
22391		init: 'lgInit',
22392		hasVideo: 'lgHasVideo',
22393		containerResize: 'lgContainerResize',
22394		updateSlides: 'lgUpdateSlides',
22395		afterAppendSubHtml: 'lgAfterAppendSubHtml',
22396		beforeOpen: 'lgBeforeOpen',
22397		afterOpen: 'lgAfterOpen',
22398		slideItemLoad: 'lgSlideItemLoad',
22399		beforeSlide: 'lgBeforeSlide',
22400		afterSlide: 'lgAfterSlide',
22401		posterClick: 'lgPosterClick',
22402		dragStart: 'lgDragStart',
22403		dragMove: 'lgDragMove',
22404		dragEnd: 'lgDragEnd',
22405		beforeNextSlide: 'lgBeforeNextSlide',
22406		beforePrevSlide: 'lgBeforePrevSlide',
22407		beforeClose: 'lgBeforeClose',
22408		afterClose: 'lgAfterClose',
22409		rotateLeft: 'lgRotateLeft',
22410		rotateRight: 'lgRotateRight',
22411		flipHorizontal: 'lgFlipHorizontal',
22412		flipVertical: 'lgFlipVertical',
22413		autoplay: 'lgAutoplay',
22414		autoplayStart: 'lgAutoplayStart',
22415		autoplayStop: 'lgAutoplayStop',
22416	};
22417
22418	var Thumbnail = /** @class */ (function () {
22419		function Thumbnail(instance, $LG) {
22420			this.thumbOuterWidth = 0;
22421			this.thumbTotalWidth = 0;
22422			this.translateX = 0;
22423			this.thumbClickable = false;
22424			// get lightGallery core plugin instance
22425			this.core = instance;
22426			this.$LG = $LG;
22427			return this;
22428		}
22429		Thumbnail.prototype.init = function () {
22430			// extend module default settings with lightGallery core settings
22431			this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings);
22432			this.thumbOuterWidth = 0;
22433			this.thumbTotalWidth =
22434				this.core.galleryItems.length *
22435					(this.settings.thumbWidth + this.settings.thumbMargin);
22436			// Thumbnail animation value
22437			this.translateX = 0;
22438			this.setAnimateThumbStyles();
22439			if (!this.core.settings.allowMediaOverlap) {
22440				this.settings.toggleThumb = false;
22441			}
22442			if (this.settings.thumbnail) {
22443				this.build();
22444				if (this.settings.animateThumb) {
22445					if (this.settings.enableThumbDrag) {
22446						this.enableThumbDrag();
22447					}
22448					if (this.settings.enableThumbSwipe) {
22449						this.enableThumbSwipe();
22450					}
22451					this.thumbClickable = false;
22452				}
22453				else {
22454					this.thumbClickable = true;
22455				}
22456				this.toggleThumbBar();
22457				this.thumbKeyPress();
22458			}
22459		};
22460		Thumbnail.prototype.build = function () {
22461			var _this = this;
22462			this.setThumbMarkup();
22463			this.manageActiveClassOnSlideChange();
22464			this.$lgThumb.first().on('click.lg touchend.lg', function (e) {
22465				var $target = _this.$LG(e.target);
22466				if (!$target.hasAttribute('data-lg-item-id')) {
22467					return;
22468				}
22469				setTimeout(function () {
22470					// In IE9 and bellow touch does not support
22471					// Go to slide if browser does not support css transitions
22472					if (_this.thumbClickable && !_this.core.lgBusy) {
22473						var index = parseInt($target.attr('data-lg-item-id'));
22474						_this.core.slide(index, false, true, false);
22475					}
22476				}, 50);
22477			});
22478			//Uncode edit ##START##
22479			// this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) {
22480			this.core.LGel.on(lGEvents.beforeSlide, function (event) {
22481			//Uncode edit ##END##
22482				var index = event.detail.index;
22483				_this.animateThumb(index);
22484			});
22485			//Uncode edit ##START##
22486			// this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () {
22487			this.core.LGel.on(lGEvents.beforeOpen, function () {
22488			//Uncode edit ##END##
22489				_this.thumbOuterWidth = _this.core.outer.get().offsetWidth;
22490			});
22491			//Uncode edit ##START##
22492			// this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () {
22493			this.core.LGel.on(lGEvents.updateSlides, function () {
22494			//Uncode edit ##END##
22495				_this.rebuildThumbnails();
22496			});
22497			//Uncode edit ##START##
22498			// this.core.LGel.on(lGEvents.containerResize + ".thumb", function () {
22499			this.core.LGel.on(lGEvents.containerResize, function () {
22500			//Uncode edit ##END##
22501				if (!_this.core.lgOpened)
22502					return;
22503				setTimeout(function () {
22504					_this.thumbOuterWidth = _this.core.outer.get().offsetWidth;
22505					_this.animateThumb(_this.core.index);
22506					_this.thumbOuterWidth = _this.core.outer.get().offsetWidth;
22507				}, 50);
22508			});
22509		};
22510		Thumbnail.prototype.setThumbMarkup = function () {
22511			var thumbOuterClassNames = 'lg-thumb-outer ';
22512			if (this.settings.alignThumbnails) {
22513				thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails;
22514			}
22515			var html = "<div class=\"" + thumbOuterClassNames + "\">\n        <div class=\"lg-thumb lg-group\">\n        </div>\n        </div>";
22516			this.core.outer.addClass('lg-has-thumb');
22517			if (this.settings.appendThumbnailsTo === '.lg-components') {
22518				this.core.$lgComponents.append(html);
22519			}
22520			else {
22521				this.core.outer.append(html);
22522			}
22523			this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first();
22524			this.$lgThumb = this.core.outer.find('.lg-thumb').first();
22525			if (this.settings.animateThumb) {
22526				this.core.outer
22527					.find('.lg-thumb')
22528					.css('transition-duration', this.core.settings.speed + 'ms')
22529					.css('width', this.thumbTotalWidth + 'px')
22530					.css('position', 'relative');
22531			}
22532			this.setThumbItemHtml(this.core.galleryItems);
22533		};
22534		Thumbnail.prototype.enableThumbDrag = function () {
22535			var _this = this;
22536			var thumbDragUtils = {
22537				cords: {
22538					startX: 0,
22539					endX: 0,
22540				},
22541				isMoved: false,
22542				newTranslateX: 0,
22543				startTime: new Date(),
22544				endTime: new Date(),
22545				touchMoveTime: 0,
22546			};
22547			var isDragging = false;
22548			this.$thumbOuter.addClass('lg-grab');
22549			this.core.outer
22550				.find('.lg-thumb')
22551				.first()
22552				.on('mousedown.lg.thumb', function (e) {
22553				if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
22554					// execute only on .lg-object
22555					e.preventDefault();
22556					thumbDragUtils.cords.startX = e.pageX;
22557					thumbDragUtils.startTime = new Date();
22558					_this.thumbClickable = false;
22559					isDragging = true;
22560					// ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
22561					_this.core.outer.get().scrollLeft += 1;
22562					_this.core.outer.get().scrollLeft -= 1;
22563					// *
22564					_this.$thumbOuter
22565						.removeClass('lg-grab')
22566						.addClass('lg-grabbing');
22567				}
22568			});
22569			this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) {
22570				if (!_this.core.lgOpened)
22571					return;
22572				if (isDragging) {
22573					thumbDragUtils.cords.endX = e.pageX;
22574					thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils);
22575				}
22576			});
22577			this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () {
22578				if (!_this.core.lgOpened)
22579					return;
22580				if (thumbDragUtils.isMoved) {
22581					thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils);
22582				}
22583				else {
22584					_this.thumbClickable = true;
22585				}
22586				if (isDragging) {
22587					isDragging = false;
22588					_this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab');
22589				}
22590			});
22591		};
22592		Thumbnail.prototype.enableThumbSwipe = function () {
22593			var _this = this;
22594			var thumbDragUtils = {
22595				cords: {
22596					startX: 0,
22597					endX: 0,
22598				},
22599				isMoved: false,
22600				newTranslateX: 0,
22601				startTime: new Date(),
22602				endTime: new Date(),
22603				touchMoveTime: 0,
22604			};
22605			this.$lgThumb.on('touchstart.lg', function (e) {
22606				if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
22607					e.preventDefault();
22608					thumbDragUtils.cords.startX = e.targetTouches[0].pageX;
22609					_this.thumbClickable = false;
22610					thumbDragUtils.startTime = new Date();
22611				}
22612			});
22613			this.$lgThumb.on('touchmove.lg', function (e) {
22614				if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
22615					e.preventDefault();
22616					thumbDragUtils.cords.endX = e.targetTouches[0].pageX;
22617					thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils);
22618				}
22619			});
22620			this.$lgThumb.on('touchend.lg', function () {
22621				if (thumbDragUtils.isMoved) {
22622					thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils);
22623				}
22624				else {
22625					_this.thumbClickable = true;
22626				}
22627			});
22628		};
22629		// Rebuild thumbnails
22630		Thumbnail.prototype.rebuildThumbnails = function () {
22631			var _this = this;
22632			// Remove transitions
22633			this.$thumbOuter.addClass('lg-rebuilding-thumbnails');
22634			setTimeout(function () {
22635				_this.thumbTotalWidth =
22636					_this.core.galleryItems.length *
22637						(_this.settings.thumbWidth + _this.settings.thumbMargin);
22638				_this.$lgThumb.css('width', _this.thumbTotalWidth + 'px');
22639				_this.$lgThumb.empty();
22640				_this.setThumbItemHtml(_this.core.galleryItems);
22641				_this.animateThumb(_this.core.index);
22642			}, 50);
22643			setTimeout(function () {
22644				_this.$thumbOuter.removeClass('lg-rebuilding-thumbnails');
22645			}, 200);
22646		};
22647		// @ts-check
22648		Thumbnail.prototype.setTranslate = function (value) {
22649			this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)');
22650		};
22651		Thumbnail.prototype.getPossibleTransformX = function (left) {
22652			if (left > this.thumbTotalWidth - this.thumbOuterWidth) {
22653				left = this.thumbTotalWidth - this.thumbOuterWidth;
22654			}
22655			if (left < 0) {
22656				left = 0;
22657			}
22658			return left;
22659		};
22660		Thumbnail.prototype.animateThumb = function (index) {
22661			this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms');
22662			if (this.settings.animateThumb) {
22663				var position = 0;
22664				switch (this.settings.currentPagerPosition) {
22665					case 'left':
22666						position = 0;
22667						break;
22668					case 'middle':
22669						position =
22670							this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2;
22671						break;
22672					case 'right':
22673						position = this.thumbOuterWidth - this.settings.thumbWidth;
22674				}
22675				this.translateX =
22676					(this.settings.thumbWidth + this.settings.thumbMargin) * index -
22677						1 -
22678						position;
22679				if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) {
22680					this.translateX = this.thumbTotalWidth - this.thumbOuterWidth;
22681				}
22682				if (this.translateX < 0) {
22683					this.translateX = 0;
22684				}
22685				this.setTranslate(this.translateX);
22686			}
22687		};
22688		Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) {
22689			thumbDragUtils.newTranslateX = this.translateX;
22690			thumbDragUtils.isMoved = true;
22691			thumbDragUtils.touchMoveTime = new Date().valueOf();
22692			thumbDragUtils.newTranslateX -=
22693				thumbDragUtils.cords.endX - thumbDragUtils.cords.startX;
22694			thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX);
22695			// move current slide
22696			this.setTranslate(thumbDragUtils.newTranslateX);
22697			this.$thumbOuter.addClass('lg-dragging');
22698			return thumbDragUtils;
22699		};
22700		Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) {
22701			thumbDragUtils.isMoved = false;
22702			thumbDragUtils.endTime = new Date();
22703			this.$thumbOuter.removeClass('lg-dragging');
22704			var touchDuration = thumbDragUtils.endTime.valueOf() -
22705				thumbDragUtils.startTime.valueOf();
22706			var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX;
22707			var speedX = Math.abs(distanceXnew) / touchDuration;
22708			// Some magical numbers
22709			// Can be improved
22710			if (speedX > 0.15 &&
22711				thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) {
22712				speedX += 1;
22713				if (speedX > 2) {
22714					speedX += 1;
22715				}
22716				speedX =
22717					speedX +
22718						speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth);
22719				this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings');
22720				distanceXnew = distanceXnew * speedX;
22721				this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew);
22722				this.setTranslate(this.translateX);
22723			}
22724			else {
22725				this.translateX = thumbDragUtils.newTranslateX;
22726			}
22727			if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) <
22728				this.settings.thumbnailSwipeThreshold) {
22729				this.thumbClickable = true;
22730			}
22731			return thumbDragUtils;
22732		};
22733		Thumbnail.prototype.getThumbHtml = function (thumb, index) {
22734			var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
22735			var thumbImg,
22736				altTh = this.core.galleryItems[index].subHtml,
22737				altApp = '';
22738			if (slideVideoInfo.youtube) {
22739				if (this.settings.loadYouTubeThumbnail) {
22740					thumbImg =
22741						'//img.youtube.com/vi/' +
22742							slideVideoInfo.youtube[1] +
22743							'/' +
22744							this.settings.youTubeThumbSize +
22745							'.jpg';
22746				}
22747				else {
22748					thumbImg = thumb;
22749				}
22750			}
22751			else {
22752				thumbImg = thumb;
22753			}
22754
22755			if ( altTh ) {
22756				altTh = altTh.replace(/<\/?[^>]+(>|$)/g, "");
22757				altApp = 'alt=\"' + altTh + ' \" ';
22758			}
22759
22760			if ( thumbImg ) {
22761				return "<div data-lg-item-id=\"" + index + "\" class=\"lg-thumb-item " + (index === this.core.index ? ' active' : '') + "\" \n        style=\"width:" + this.settings.thumbWidth + "px; height: " + this.settings.thumbHeight + ";\n            margin-right: " + this.settings.thumbMargin + "px;\">\n            <img data-lg-item-id=\"" + index + "\" " + altApp + "src=\"" + thumbImg + "\" />\n        </div>";
22762			} else {
22763				return "<div data-lg-item-id=\"" + index + "\" class=\"lg-thumb-item " + (index === this.core.index ? ' active' : '') + "\" \n        style=\"width:" + this.settings.thumbWidth + "px; height: " + this.settings.thumbHeight + ";\n            margin-right: " + this.settings.thumbMargin + "px;\">\n        </div>";
22764			}
22765		};
22766		Thumbnail.prototype.getThumbItemHtml = function (items) {
22767			var thumbList = '';
22768			for (var i = 0; i < items.length; i++) {
22769				thumbList += this.getThumbHtml(items[i].thumb, i);
22770			}
22771			return thumbList;
22772		};
22773		Thumbnail.prototype.setThumbItemHtml = function (items) {
22774			var thumbList = this.getThumbItemHtml(items);
22775			this.$lgThumb.html(thumbList);
22776		};
22777		Thumbnail.prototype.setAnimateThumbStyles = function () {
22778			if (this.settings.animateThumb) {
22779				this.core.outer.addClass('lg-animate-thumb');
22780			}
22781		};
22782		// Manage thumbnail active calss
22783		Thumbnail.prototype.manageActiveClassOnSlideChange = function () {
22784			var _this = this;
22785			// manage active class for thumbnail
22786			//Uncode edit ##START##
22787			// this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) {
22788			this.core.LGel.on(lGEvents.beforeSlide, function (event) {
22789			//Uncode edit ##END##
22790				var $thumb = _this.core.outer.find('.lg-thumb-item');
22791				var index = event.detail.index;
22792				$thumb.removeClass('active');
22793				$thumb.eq(index).addClass('active');
22794			});
22795		};
22796		// Toggle thumbnail bar
22797		Thumbnail.prototype.toggleThumbBar = function () {
22798			var _this = this;
22799			if (this.settings.toggleThumb) {
22800				this.core.outer.addClass('lg-can-toggle');
22801				this.core.$toolbar.append('<button type="button" aria-label="' +
22802					this.settings.thumbnailPluginStrings['toggleThumbnails'] +
22803					'" class="lg-toggle-thumb lg-icon"></button>');
22804				this.core.outer
22805					.find('.lg-toggle-thumb')
22806					.first()
22807					.on('click.lg', function () {
22808					_this.core.outer.toggleClass('lg-components-open');
22809				});
22810			}
22811		};
22812		Thumbnail.prototype.thumbKeyPress = function () {
22813			var _this = this;
22814			this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) {
22815				if (!_this.core.lgOpened || !_this.settings.toggleThumb)
22816					return;
22817				if (e.keyCode === 38) {
22818					e.preventDefault();
22819					_this.core.outer.addClass('lg-components-open');
22820				}
22821				else if (e.keyCode === 40) {
22822					e.preventDefault();
22823					_this.core.outer.removeClass('lg-components-open');
22824				}
22825			});
22826		};
22827		Thumbnail.prototype.destroy = function () {
22828			if (this.settings.thumbnail) {
22829				this.$LG(window).off(".lg.thumb.global" + this.core.lgId);
22830				this.core.LGel.off('.lg.thumb');
22831				this.core.LGel.off('.thumb');
22832				this.$thumbOuter.remove();
22833				this.core.outer.removeClass('lg-has-thumb');
22834			}
22835		};
22836		return Thumbnail;
22837	}());
22838
22839	return Thumbnail;
22840
22841})));
22842/*!
22843 * lightgallery | 2.5.0 | June 13th 2022
22844 * http://www.lightgalleryjs.com/
22845 * Copyright (c) 2020 Sachin Neravath;
22846 * @license GPLv3
22847 */
22848
22849(function (global, factory) {
22850	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
22851	typeof define === 'function' && define.amd ? define(factory) :
22852	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory());
22853}(this, (function () { 'use strict';
22854
22855	/*! *****************************************************************************
22856	Copyright (c) Microsoft Corporation.
22857
22858	Permission to use, copy, modify, and/or distribute this software for any
22859	purpose with or without fee is hereby granted.
22860
22861	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22862	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22863	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22864	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22865	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22866	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22867	PERFORMANCE OF THIS SOFTWARE.
22868	***************************************************************************** */
22869
22870	var __assign = function() {
22871		__assign = Object.assign || function __assign(t) {
22872			for (var s, i = 1, n = arguments.length; i < n; i++) {
22873				s = arguments[i];
22874				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
22875			}
22876			return t;
22877		};
22878		return __assign.apply(this, arguments);
22879	};
22880
22881	var videoSettings = {
22882		autoplayFirstVideo: true,
22883		youTubePlayerParams: false,
22884		vimeoPlayerParams: false,
22885		wistiaPlayerParams: false,
22886		gotoNextSlideOnVideoEnd: true,
22887		autoplayVideoOnSlide: false,
22888		videojs: false,
22889		videojsTheme: '',
22890		videojsOptions: {},
22891	};
22892
22893	/**
22894	 * List of lightGallery events
22895	 * All events should be documented here
22896	 * Below interfaces are used to build the website documentations
22897	 * */
22898	var lGEvents = {
22899		afterAppendSlide: 'lgAfterAppendSlide',
22900		init: 'lgInit',
22901		hasVideo: 'lgHasVideo',
22902		containerResize: 'lgContainerResize',
22903		updateSlides: 'lgUpdateSlides',
22904		afterAppendSubHtml: 'lgAfterAppendSubHtml',
22905		beforeOpen: 'lgBeforeOpen',
22906		afterOpen: 'lgAfterOpen',
22907		slideItemLoad: 'lgSlideItemLoad',
22908		beforeSlide: 'lgBeforeSlide',
22909		afterSlide: 'lgAfterSlide',
22910		posterClick: 'lgPosterClick',
22911		dragStart: 'lgDragStart',
22912		dragMove: 'lgDragMove',
22913		dragEnd: 'lgDragEnd',
22914		beforeNextSlide: 'lgBeforeNextSlide',
22915		beforePrevSlide: 'lgBeforePrevSlide',
22916		beforeClose: 'lgBeforeClose',
22917		afterClose: 'lgAfterClose',
22918		rotateLeft: 'lgRotateLeft',
22919		rotateRight: 'lgRotateRight',
22920		flipHorizontal: 'lgFlipHorizontal',
22921		flipVertical: 'lgFlipVertical',
22922		autoplay: 'lgAutoplay',
22923		autoplayStart: 'lgAutoplayStart',
22924		autoplayStop: 'lgAutoplayStop',
22925	};
22926
22927	var param = function (obj) {
22928		return Object.keys(obj)
22929			.map(function (k) {
22930			return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]);
22931		})
22932			.join('&');
22933	};
22934	var getVimeoURLParams = function (defaultParams, videoInfo) {
22935		if (!videoInfo || !videoInfo.vimeo)
22936			return '';
22937		var urlParams = videoInfo.vimeo[2] || '';
22938		var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0
22939			? '&' + param(defaultParams)
22940			: '';
22941		// Support private video
22942		var urlWithHash = videoInfo.vimeo[0].split('/').pop() || '';
22943		var urlWithHashWithParams = urlWithHash.split('?')[0] || '';
22944		var hash = urlWithHashWithParams.split('#')[0];
22945		var isPrivate = videoInfo.vimeo[1] !== hash;
22946		if (isPrivate) {
22947			urlParams = urlParams.replace("/" + hash, '');
22948		}
22949		urlParams =
22950			urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || '';
22951		// For vimeo last params gets priority if duplicates found
22952		// Uncode edit ##START##
22953		var vimeoPlayerParams = '?autoplay=0';
22954		if ( videoInfo.autoplay !== '' ) {
22955			vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' );
22956			vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' );
22957		} else {
22958			if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) {
22959				vimeoPlayerParams = SiteParameters.vimeoPlayerParams;
22960			}
22961		}
22962		if ( videoInfo.muted !== '' ) {
22963			vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes');
22964		} else {
22965			if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) {
22966				vimeoPlayerParams += '&muted=1';
22967			}
22968		}
22969		// var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams;
22970		vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams;
22971		// Uncode edit ##END##
22972		return vimeoPlayerParams;
22973	};
22974
22975	/**
22976	 * Video module for lightGallery
22977	 * Supports HTML5, YouTube, Vimeo, wistia videos
22978	 *
22979	 *
22980	 * @ref Wistia
22981	 * https://wistia.com/support/integrations/wordpress(How to get url)
22982	 * https://wistia.com/support/developers/embed-options#using-embed-options
22983	 * https://wistia.com/support/developers/player-api
22984	 * https://wistia.com/support/developers/construct-an-embed-code
22985	 * http://jsfiddle.net/xvnm7xLm/
22986	 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
22987	 * https://wistia.com/support/embed-and-share/sharing-videos
22988	 * https://private-sharing.wistia.com/medias/mwhrulrucj
22989	 *
22990	 * @ref Youtube
22991	 * https://developers.google.com/youtube/player_parameters#enablejsapi
22992	 * https://developers.google.com/youtube/iframe_api_reference
22993	 * https://developer.chrome.com/blog/autoplay/#iframe-delegation
22994	 *
22995	 * @ref Vimeo
22996	 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url
22997	 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode
22998	 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters
22999	 */
23000	var Video = /** @class */ (function () {
23001		function Video(instance) {
23002			// get lightGallery core plugin instance
23003			this.core = instance;
23004			this.settings = __assign(__assign({}, videoSettings), this.core.settings);
23005			return this;
23006		}
23007		Video.prototype.init = function () {
23008			var _this = this;
23009			/**
23010			 * Event triggered when video url found without poster
23011			 * Append video HTML
23012			 * Play if autoplayFirstVideo is true
23013			 */
23014			this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this));
23015			this.core.LGel.on(lGEvents.posterClick + ".video", function () {
23016				var $el = _this.core.getSlideItem(_this.core.index);
23017				_this.loadVideoOnPosterClick($el);
23018			});
23019			this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this));
23020			// @desc fired immediately before each slide transition.
23021			this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this));
23022			// @desc fired immediately after each slide transition.
23023			this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this));
23024		};
23025		/**
23026		 * @desc Event triggered when a slide is completely loaded
23027		 *
23028		 * @param {Event} event - lightGalley custom event
23029		 */
23030		Video.prototype.onSlideItemLoad = function (event) {
23031			var _this = this;
23032			var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index;
23033			// Should check the active slide as well as user may have moved to different slide before the first slide is loaded
23034			if (this.settings.autoplayFirstVideo &&
23035				isFirstSlide &&
23036				index === this.core.index) {
23037				// Delay is just for the transition effect on video load
23038				setTimeout(function () {
23039					_this.loadAndPlayVideo(index);
23040				}, 200);
23041			}
23042			// Should not call on first slide. should check only if the slide is active
23043			if (!isFirstSlide &&
23044				this.settings.autoplayVideoOnSlide &&
23045				index === this.core.index) {
23046					setTimeout(function () {
23047						_this.loadAndPlayVideo(index);
23048					}, 500);
23049				}
23050		};
23051		/**
23052		 * @desc Event triggered when video url or poster found
23053		 * Append video HTML is poster is not given
23054		 * Play if autoplayFirstVideo is true
23055		 *
23056		 * @param {Event} event - Javascript Event object.
23057		 */
23058		Video.prototype.onHasVideo = function (event) {
23059			var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster;
23060			if (!hasPoster) {
23061				// All functions are called separately if poster exist in loadVideoOnPosterClick function
23062				this.appendVideos(this.core.getSlideItem(index), {
23063					src: src,
23064					addClass: 'lg-object',
23065					index: index,
23066					html5Video: html5Video,
23067					// Uncode edit ##START##
23068					autoplay: event.target.getAttribute('data-lb-autoplay'),
23069					muted: event.target.getAttribute('data-lb-muted'),
23070					// Uncode edit ##END##
23071				});
23072				// Automatically navigate to next slide once video reaches the end.
23073				this.gotoNextSlideOnVideoEnd(src, index);
23074			}
23075		};
23076		/**
23077		 * @desc fired immediately before each slide transition.
23078		 * Pause the previous video
23079		 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos.
23080		 *
23081		 * @param {Event} event - Javascript Event object.
23082		 * @param {number} prevIndex - Previous index of the slide.
23083		 * @param {number} index - Current index of the slide
23084		 */
23085		Video.prototype.onBeforeSlide = function (event) {
23086			if (this.core.lGalleryOn) {
23087				var prevIndex = event.detail.prevIndex;
23088				this.pauseVideo(prevIndex);
23089			}
23090			// Uncode edit ##START##
23091			var _a = event.detail, index = _a.index;
23092			var $slide = this.core.getSlideItem(index);
23093			
23094			var iframe = $slide.selector.querySelector('iframe');
23095			if ( iframe != null ) {
23096
23097				var data_play = iframe.getAttribute('data-autoplay');
23098				if ( typeof data_play !== 'undefined' && data_play === '1' ) {
23099					this.loadAndPlayVideo(index);
23100
23101					var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {},
23102						$videoElement = this.core.getSlideItem(index).find('.lg-video-object').first();
23103					if (videoInfo.vimeo) {
23104						var vimeoPlayer = new Vimeo.Player($videoElement.get());
23105						vimeoPlayer.on('play', function () {
23106							vimeoPlayer.setCurrentTime(0);
23107						});
23108					} else if ( videoInfo.youtube ) {
23109						try {
23110							$videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*');
23111						}
23112						catch (e) {
23113							console.warn(e);
23114						}
23115					}
23116				}
23117			}
23118			// Uncode edit ##END##
23119		};
23120		/**
23121		 * @desc fired immediately after each slide transition.
23122		 * Play video if autoplayVideoOnSlide option is enabled.
23123		 *
23124		 * @param {Event} event - Javascript Event object.
23125		 * @param {number} prevIndex - Previous index of the slide.
23126		 * @param {number} index - Current index of the slide
23127		 * @todo should check on onSlideLoad as well if video is not loaded on after slide
23128		 */
23129		Video.prototype.onAfterSlide = function (event) {
23130			var _this = this;
23131			var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex;
23132			// Do not call on first slide
23133			var $slide = this.core.getSlideItem(index);
23134			if (this.settings.autoplayVideoOnSlide && index !== prevIndex) {
23135				if ($slide.hasClass('lg-complete')) {
23136					setTimeout(function () {
23137						_this.loadAndPlayVideo(index);
23138					}, 100);
23139				}
23140			}
23141		};
23142		Video.prototype.loadAndPlayVideo = function (index) {
23143			var $slide = this.core.getSlideItem(index);
23144			var currentGalleryItem = this.core.galleryItems[index];
23145			if (currentGalleryItem.poster) {
23146				this.loadVideoOnPosterClick($slide, true);
23147			}
23148			else {
23149				//Uncode edit ##START##
23150				// this.playVideo(index);
23151				var iframe = $slide.selector.querySelector('iframe');
23152				if ( iframe != null ) {
23153					var data_play = iframe.getAttribute('data-autoplay');
23154					if ( typeof data_play !== 'undefined' ) {
23155						if ( data_play === '1' && this.core.index == index ) {
23156							this.playVideo(index);
23157						} else {
23158							this.pauseVideo(index);
23159						}
23160					}
23161				}
23162				//Uncode edit ##END##
23163			}
23164		};
23165		/**
23166		 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
23167		 * @param {number} index - Index of the slide
23168		 */
23169		Video.prototype.playVideo = function (index) {
23170			this.controlVideo(index, 'play');
23171		};
23172		/**
23173		 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
23174		 * @param {number} index - Index of the slide
23175		 */
23176		Video.prototype.pauseVideo = function (index) {
23177			this.controlVideo(index, 'pause');
23178		};
23179		// Uncode edit ##START##
23180		//Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) {
23181		Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) {
23182		// Uncode edit ##END##
23183			var video = '';
23184			var videoInfo = this.core.galleryItems[index]
23185				.__slideVideoInfo || {};
23186			var currentGalleryItem = this.core.galleryItems[index];
23187			var videoTitle = currentGalleryItem.title || currentGalleryItem.alt;
23188			videoTitle = videoTitle ? 'title="' + videoTitle + '"' : '';
23189			var commonIframeProps = "allowtransparency=\"true\"\n            frameborder=\"0\"\n            scrolling=\"no\"\n            allowfullscreen\n            mozallowfullscreen\n            webkitallowfullscreen\n            oallowfullscreen\n            msallowfullscreen";
23190			if (videoInfo.youtube) {
23191				var videoId = 'lg-youtube' + index;
23192				var slideUrlParams = videoInfo.youtube[2]
23193					? videoInfo.youtube[2] + '&'
23194					: '';
23195				// For youtube first parms gets priority if duplicates found
23196				// Uncode edit ##START##
23197				// var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1";
23198				var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1";
23199				if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) {
23200					youTubePlayerParams += '&autoplay=0';
23201				}
23202				if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) {
23203					youTubePlayerParams += '&mute=1';
23204				}
23205				var data_video = '';
23206				if ( autoplay !== '' ) {
23207					//youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' );
23208					youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' );
23209					youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' );
23210					data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"';
23211				}
23212				// if ( muted !== '' ) {
23213				// 	youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' );
23214				// }
23215				youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' );
23216
23217				youTubePlayerParams = youTubePlayerParams.replace('??', '?');
23218				// Uncode edit ##END##
23219				var playerParams = youTubePlayerParams +
23220					(this.settings.youTubePlayerParams
23221						? '&' + param(this.settings.youTubePlayerParams)
23222						: '');
23223				// Uncode edit ##START##
23224				// video = "<iframe allow=\"autoplay\" id=" + videoId + " class=\"lg-video-object lg-youtube " + addClass + "\" " + videoTitle + " src=\"//www.youtube.com/embed/" + (videoInfo.youtube[1] + playerParams) + "\" " + commonIframeProps + "></iframe>";
23225				var nocookie = typeof SiteParameters.uncode_nocookie !== 'undefined' ? SiteParameters.uncode_nocookie : '';
23226				video = "<iframe allow=\"autoplay\"" + data_video + " id=" + videoId + " class=\"lg-video-object lg-youtube " + addClass + "\" " + videoTitle + " src=\"//www.youtube" + nocookie + ".com/embed/" + (videoInfo.youtube[1] + playerParams) + "\" " + commonIframeProps + "></iframe>";
23227				var tag = document.createElement('script');
23228				tag.src = "//www.youtube.com/player_api";
23229				var firstScriptTag = document.getElementsByTagName('script')[0];
23230				firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
23231
23232				// Replace the 'ytplayer' element with an <iframe> and
23233				// YouTube player after the API code downloads.
23234				var ytIframeplayer,
23235					setMute = muted === 'yes' ? 0 : 100;
23236				window.onYouTubePlayerAPIReady = function() {
23237					ytIframeplayer = new YT.Player(videoId, {
23238						videoId: videoInfo.youtube[1],
23239						events: {
23240							'onReady': function (event) {
23241								event.target.setVolume(setMute);
23242							}
23243						}
23244					});
23245				}
23246				// Uncode edit ##END##
23247			}
23248			else if (videoInfo.vimeo) {
23249				var videoId = 'lg-vimeo' + index;
23250				// Uncode edit ##START##
23251				videoInfo.autoplay = autoplay;
23252				videoInfo.muted = muted;
23253				// Uncode edit ##END##
23254				var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo);
23255				// Uncode edit ##START##
23256				// video = "<iframe allow=\"autoplay\" id=" + videoId + " class=\"lg-video-object lg-vimeo " + addClass + "\" " + videoTitle + " src=\"//player.vimeo.com/video/" + (videoInfo.vimeo[1] + playerParams) + "\" " + commonIframeProps + "></iframe>";
23257				var data_video = '';
23258				if ( autoplay !== '' ) {
23259					data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"';
23260				}
23261				video = "<iframe allow=\"autoplay\"" + data_video + " id=" + videoId + " class=\"lg-video-object lg-vimeo " + addClass + "\" " + videoTitle + " src=\"//player.vimeo.com/video/" + (videoInfo.vimeo[1] + playerParams) + "\" " + commonIframeProps + "></iframe>";
23262				// Uncode edit ##END##
23263			}
23264			else if (videoInfo.wistia) {
23265				var wistiaId = 'lg-wistia' + index;
23266				var playerParams = param(this.settings.wistiaPlayerParams);
23267				playerParams = playerParams ? '?' + playerParams : '';
23268				video = "<iframe allow=\"autoplay\" id=\"" + wistiaId + "\" src=\"//fast.wistia.net/embed/iframe/" + (videoInfo.wistia[4] + playerParams) + "\" " + videoTitle + " class=\"wistia_embed lg-video-object lg-wistia " + addClass + "\" name=\"wistia_embed\" " + commonIframeProps + "></iframe>";
23269			}
23270			else if (videoInfo.html5) {
23271				var html5VideoMarkup = '';
23272				for (var i = 0; i < html5Video.source.length; i++) {
23273					html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">";
23274				}
23275				if (html5Video.tracks) {
23276					var _loop_1 = function (i) {
23277						var trackAttributes = '';
23278						var track = html5Video.tracks[i];
23279						Object.keys(track || {}
23279).forEach(function (key) {
23280							trackAttributes += key + "=\"" + track[key] + "\" ";
23281						});
23282						html5VideoMarkup += "<track " + trackAttributes + ">";
23283					};
23284					for (var i = 0; i < html5Video.tracks.length; i++) {
23285						_loop_1(i);
23286					}
23287				}
23288				var html5VideoAttrs_1 = '';
23289				var videoAttributes_1 = html5Video.attributes || {};
23290				Object.keys(videoAttributes_1 || {}).forEach(function (key) {
23291					html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" ";
23292				});
23293				video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme
23294					? this.settings.videojsTheme + ' '
23295					: '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n                " + html5VideoMarkup + "\n                Your browser does not support HTML5 video.\n            </video>";
23296			}
23297			return video;
23298		};
23299		/**
23300		 * @desc - Append videos to the slide
23301		 *
23302		 * @param {HTMLElement} el - slide element
23303		 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo
23304		 */
23305		Video.prototype.appendVideos = function (el, videoParams) {
23306			var _a;
23307			// Uncode edit ##START##
23308			// var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video);
23309			var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted);
23310			// Uncode edit ##END##
23311			el.find('.lg-video-cont').append(videoHtml);
23312			var $videoElement = el.find('.lg-video-object').first();
23313			if (videoParams.html5Video) {
23314				$videoElement.on('mousedown.lg.video', function (e) {
23315					e.stopPropagation();
23316				});
23317			}
23318			if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) {
23319				try {
23320					return videojs($videoElement.get(), this.settings.videojsOptions);
23321				}
23322				catch (e) {
23323					console.warn('lightGallery:- Make sure you have included videojs');
23324				}
23325			}
23326		};
23327		Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) {
23328			var _this = this;
23329			var $videoElement = this.core
23330				.getSlideItem(index)
23331				.find('.lg-video-object')
23332				.first();
23333			var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
23334			if (this.settings.gotoNextSlideOnVideoEnd) {
23335				if (videoInfo.html5) {
23336					$videoElement.on('ended', function () {
23337						_this.core.goToNextSlide();
23338					});
23339				}
23340				else if (videoInfo.vimeo) {
23341					try {
23342						// https://github.com/vimeo/player.js/#ended
23343						new Vimeo.Player($videoElement.get()).on('ended', function () {
23344							_this.core.goToNextSlide();
23345						});
23346					}
23347					catch (e) {
23348						console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
23349					}
23350				}
23351				else if (videoInfo.wistia) {
23352					try {
23353						window._wq = window._wq || [];
23354						// @todo Event is gettign triggered multiple times
23355						window._wq.push({
23356							id: $videoElement.attr('id'),
23357							onReady: function (video) {
23358								video.bind('end', function () {
23359									_this.core.goToNextSlide();
23360								});
23361							},
23362						});
23363					}
23364					catch (e) {
23365						console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
23366					}
23367				}
23368			}
23369		};
23370		Video.prototype.controlVideo = function (index, action) {
23371			var $videoElement = this.core
23372				.getSlideItem(index)
23373				.find('.lg-video-object')
23374				.first();
23375			var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
23376			if (!$videoElement.get())
23377				return;
23378			if (videoInfo.youtube) {
23379				try {
23380					$videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*');
23381				}
23382				catch (e) {
23383					console.warn("lightGallery:- " + e);
23384				}
23385			}
23386			else if (videoInfo.vimeo) {
23387				try {
23388					new Vimeo.Player($videoElement.get())[action]();
23389				}
23390				catch (e) {
23391					console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
23392				}
23393			}
23394			else if (videoInfo.html5) {
23395				if (this.settings.videojs) {
23396					try {
23397						videojs($videoElement.get())[action]();
23398					}
23399					catch (e) {
23400						console.warn('lightGallery:- Make sure you have included videojs');
23401					}
23402				}
23403				else {
23404					$videoElement.get()[action]();
23405				}
23406			}
23407			else if (videoInfo.wistia) {
23408				try {
23409					window._wq = window._wq || [];
23410					// @todo Find a way to destroy wistia player instance
23411					window._wq.push({
23412						id: $videoElement.attr('id'),
23413						onReady: function (video) {
23414							video[action]();
23415						},
23416					});
23417				}
23418				catch (e) {
23419					console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
23420				}
23421			}
23422		};
23423		Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) {
23424			var _this = this;
23425			// check slide has poster
23426			if (!$el.hasClass('lg-video-loaded')) {
23427				// check already video element present
23428				if (!$el.hasClass('lg-has-video')) {
23429					$el.addClass('lg-has-video');
23430					var _html = void 0;
23431					var _src = this.core.galleryItems[this.core.index].src;
23432					var video = this.core.galleryItems[this.core.index].video;
23433					if (video) {
23434						_html =
23435							typeof video === 'string' ? JSON.parse(video) : video;
23436					}
23437					var videoJsPlayer_1 = this.appendVideos($el, {
23438						src: _src,
23439						addClass: '',
23440						index: this.core.index,
23441						html5Video: _html,
23442					});
23443					this.gotoNextSlideOnVideoEnd(_src, this.core.index);
23444					var $tempImg = $el.find('.lg-object').first().get();
23445					// @todo make sure it is working
23446					$el.find('.lg-video-cont').first().append($tempImg);
23447					$el.addClass('lg-video-loading');
23448					videoJsPlayer_1 &&
23449						videoJsPlayer_1.ready(function () {
23450							videoJsPlayer_1.on('loadedmetadata', function () {
23451								_this.onVideoLoadAfterPosterClick($el, _this.core.index);
23452							});
23453						});
23454					$el.find('.lg-video-object')
23455						.first()
23456						.on('load.lg error.lg loadedmetadata.lg', function () {
23457						setTimeout(function () {
23458							_this.onVideoLoadAfterPosterClick($el, _this.core.index);
23459						}, 50);
23460					});
23461				}
23462				else {
23463					this.playVideo(this.core.index);
23464				}
23465			}
23466			else if (forcePlay) {
23467				this.playVideo(this.core.index);
23468			}
23469		};
23470		Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) {
23471			$el.addClass('lg-video-loaded');
23472			this.playVideo(index);
23473		};
23474		Video.prototype.destroy = function () {
23475			this.core.LGel.off('.lg.video');
23476			this.core.LGel.off('.video');
23477		};
23478		return Video;
23479	}());
23480
23481	return Video;
23482
23483})));
23484
23485
23486/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */
23487!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).Vimeo=e.Vimeo||{},e.Vimeo.Player=t())}(this,function(){"use strict";function r(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}var e="undefined"!=typeof global&&"[object global]"==={}.toString.call(global);function i(e,t){return 0===e.indexOf(t.toLowerCase())?e:"".concat(t.toLowerCase()).concat(e.substr(0,1).toUpperCase()).concat(e.substr(1))}function c(e){return/^(https?:)?\/\/((player|www)\.)?vimeo\.com(?=$|\/)/.test(e)}function s(e){var t,n=0<arguments.length&&void 0!==e?e:{},r=n.id,o=n.url,i=r||o;if(!i)throw new Error("An id or url must be passed, either in an options object or as a data-vimeo-id or data-vimeo-url attribute.");if(t=i,!isNaN(parseFloat(t))&&isFinite(t)&&Math.floor(t)==t)return"https://vimeo.com/".concat(i);if(c(i))return i.replace("http:","https:");if(r)throw new TypeError("“".concat(r,"” is not a valid video id."));throw new TypeError("“".concat(i,"” is not a vimeo.com url."))}var t=void 0!==Array.prototype.indexOf,n="undefined"!=typeof window&&void 0!==window.postMessage;if(!(e||t&&n))throw new Error("Sorry, the Vimeo Player API is not available in this browser.");var o,a,u,l,f="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function d(){if(void 0===this)throw new TypeError("Constructor WeakMap requires 'new'");if(l(this,"_id","_WeakMap_"+v()+"."+v()),0<arguments.length)throw new TypeError("WeakMap iterable is not supported")}function h(e,t){if(!m(e)||!a.call(e,"_id"))throw new TypeError(t+" method called on incompatible receiver "+typeof e)}function v(){return Math.random().toString().substring(2)}function m(e){return Object(e)===e}(o="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:f).WeakMap||(a=Object.prototype.hasOwnProperty,u=Object.defineProperty&&function(){try{return 1===Object.defineProperty({},"x",{value:1}).x}catch(e){}}(),l=function(e,t,n){u?Object.defineProperty(e,t,{configurable:!0,writable:!0,value:n}):e[t]=n},o.WeakMap=(l(d.prototype,"delete",function(e){if(h(this,"delete"),!m(e))return!1;var t=e[this._id];return!(!t||t[0]!==e)&&(delete e[this._id],!0)}),l(d.prototype,"get",function(e){if(h(this,"get"),m(e)){var t=e[this._id];return t&&t[0]===e?t[1]:void 0}}),l(d.prototype,"has",function(e){if(h(this,"has"),!m(e))return!1;var t=e[this._id];return!(!t||t[0]!==e)}),l(d.prototype,"set",function(e,t){if(h(this,"set"),!m(e))throw new TypeError("Invalid value used as weak map key");var n=e[this._id];return n&&n[0]===e?n[1]=t:l(e,this._id,[e,t]),this}),l(d,"_polyfill",!0),d));var p,y=(function(e){var t,n,r;r=function(){var t,n,r,o,i,a,e=Object.prototype.toString,u="undefined"!=typeof setImmediate?function(e){return setImmediate(e)}:setTimeout;try{Object.defineProperty({},"x",{}),t=function(e,t,n,r){return Object.defineProperty(e,t,{value:n,writable:!0,configurable:!1!==r})}}catch(e){t=function(e,t,n){return e[t]=n,e}}function l(e,t){this.fn=e,this.self=t,this.next=void 0}function c(e,t){r.add(e,t),n=n||u(r.drain)}function s(e){var t,n=typeof e;return null==e||"object"!=n&&"function"!=n||(t=e.then),"function"==typeof t&&t}function f(){for(var e=0;e<this.chain.length;e++)!function(e,t,n){var r,o;try{!1===t?n.reject(e.msg):(r=!0===t?e.msg:t.call(void 0,e.msg))===n.promise?n.reject(TypeError("Promise-chain cycle")):(o=s(r))?o.call(r,n.resolve,n.reject):n.resolve(r)}catch(e){n.reject(e)}}(this,1===this.state?this.chain[e].success:this.chain[e].failure,this.chain[e]);this.chain.length=0}function d(e){var n,r=this;if(!r.triggered){r.triggered=!0,r.def&&(r=r.def);try{(n=s(e))?c(function(){var t=new m(r);try{n.call(e,function(){d.apply(t,arguments)},function(){h.apply(t,arguments)})}catch(e){h.call(t,e)}}):(r.msg=e,r.state=1,0<r.chain.length&&c(f,r))}catch(e){h.call(new m(r),e)}}}function h(e){var t=this;t.triggered||(t.triggered=!0,t.def&&(t=t.def),t.msg=e,t.state=2,0<t.chain.length&&c(f,t))}function v(e,n,r,o){for(var t=0;t<n.length;t++)!function(t){e.resolve(n[t]).then(function(e){r(t,e)},o)}(t)}function m(e){this.def=e,this.triggered=!1}function p(e){this.promise=e,this.state=0,this.triggered=!1,this.chain=[],this.msg=void 0}function y(e){if("function"!=typeof e)throw TypeError("Not a function");if(0!==this.__NPO__)throw TypeError("Not a promise");this.__NPO__=1;var r=new p(this);this.then=function(e,t){var n={success:"function"!=typeof e||e,failure:"function"==typeof t&&t};return n.promise=new this.constructor(function(e,t){if("function"!=typeof e||"function"!=typeof t)throw TypeError("Not a function");n.resolve=e,n.reject=t}),r.chain.push(n),0!==r.state&&c(f,r),n.promise},this.catch=function(e){return this.then(void 0,e)};try{e.call(void 0,function(e){d.call(r,e)},function(e){h.call(r,e)})}catch(e){h.call(r,e)}}var g=t({},"constructor",y,!(r={add:function(e,t){a=new l(e,t),i?i.next=a:o=a,i=a,a=void 0},drain:function(){var e=o;for(o=i=n=void 0;e;)e.fn.call(e.self),e=e.next}}));return t(y.prototype=g,"__NPO__",0,!1),t(y,"resolve",function(n){return n&&"object"==typeof n&&1===n.__NPO__?n:new this(function(e,t){if("function"!=typeof e||"function"!=typeof t)throw TypeError("Not a function");e(n)})}),t(y,"reject",function(n){return new this(function(e,t){if("function"!=typeof e||"function"!=typeof t)throw TypeError("Not a function");t(n)})}),t(y,"all",function(t){var a=this;return"[object Array]"!=e.call(t)?a.reject(TypeError("Not an array")):0===t.length?a.resolve([]):new a(function(n,e){if("function"!=typeof n||"function"!=typeof e)throw TypeError("Not a function");var r=t.length,o=Array(r),i=0;v(a,t,function(e,t){o[e]=t,++i===r&&n(o)},e)})}),t(y,"race",function(t){var r=this;return"[object Array]"!=e.call(t)?r.reject(TypeError("Not an array")):new r(function(n,e){if("function"!=typeof n||"function"!=typeof e)throw TypeError("Not a function");v(r,t,function(e,t){n(t)},e)})}),y},(n=f)[t="Promise"]=n[t]||r(),e.exports&&(e.exports=n[t])}(p={exports:{}}
23487),p.exports),g=new WeakMap;function w(e,t,n){var r=g.get(e.element)||{};t in r||(r[t]=[]),r[t].push(n),g.set(e.element,r)}function b(e,t){return(g.get(e.element)||{})[t]||[]}function k(e,t,n){var r=g.get(e.element)||{};if(!r[t])return!0;if(!n)return r[t]=[],g.set(e.element,r),!0;var o=r[t].indexOf(n);return-1!==o&&r[t].splice(o,1),g.set(e.element,r),r[t]&&0===r[t].length}function E(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){return console.warn(e),{}}return e}function T(e,t,n){var r,o;e.element.contentWindow&&e.element.contentWindow.postMessage&&(r={method:t},void 0!==n&&(r.value=n),8<=(o=parseFloat(navigator.userAgent.toLowerCase().replace(/^.*msie (\d+).*$/,"$1")))&&o<10&&(r=JSON.stringify(r)),e.element.contentWindow.postMessage(r,e.origin))}function P(n,r){var t,e,o=[];(r=E(r)).event?("error"===r.event&&b(n,r.data.method).forEach(function(e){var t=new Error(r.data.message);t.name=r.data.name,e.reject(t),k(n,r.data.method,e)}),o=b(n,"event:".concat(r.event)),t=r.data):!r.method||(e=function(e,t){var n=b(e,t);if(n.length<1)return!1;var r=n.shift();return k(e,t,r),r}(n,r.method))&&(o.push(e),t=r.value),o.forEach(function(e){try{if("function"==typeof e)return void e.call(n,t);e.resolve(t)}catch(e){}})}var M=["autopause","autoplay","background","byline","color","controls","dnt","height","id","interactive_params","keyboard","loop","maxheight","maxwidth","muted","playsinline","portrait","responsive","speed","texttrack","title","transparent","url","width"];function _(r,e){var t=1<arguments.length&&void 0!==e?e:{};return M.reduce(function(e,t){var n=r.getAttribute("data-vimeo-".concat(t));return!n&&""!==n||(e[t]=""===n?1:n),e},t)}function N(e,t){var n=e.html;if(!t)throw new TypeError("An element must be provided");if(null!==t.getAttribute("data-vimeo-initialized"))return t.querySelector("iframe");var r=document.createElement("div");return r.innerHTML=n,t.appendChild(r.firstChild),t.setAttribute("data-vimeo-initialized","true"),t.querySelector("iframe")}function F(i,e,t){var a=1<arguments.length&&void 0!==e?e:{},u=2<arguments.length?t:void 0;return new Promise(function(t,n){if(!c(i))throw new TypeError("“".concat(i,"” is not a vimeo.com url."));var e="https://vimeo.com/api/oembed.json?url=".concat(encodeURIComponent(i));for(var r in a)a.hasOwnProperty(r)&&(e+="&".concat(r,"=").concat(encodeURIComponent(a[r])));var o=new("XDomainRequest"in window?XDomainRequest:XMLHttpRequest);o.open("GET",e,!0),o.onload=function(){if(404!==o.status)if(403!==o.status)try{var e=JSON.parse(o.responseText);if(403===e.domain_status_code)return N(e,u),void n(new Error("“".concat(i,"” is not embeddable.")));t(e)}catch(e){n(e)}else n(new Error("“".concat(i,"” is not embeddable.")));else n(new Error("“".concat(i,"” was not found.")))},o.onerror=function(){var e=o.status?" (".concat(o.status,")"):"";n(new Error("There was an error fetching the embed code from Vimeo".concat(e,".")))},o.send()})}var x,C,j,A=new WeakMap,S=new WeakMap,q={},Player=function(){function Player(u){var e,t,l=this,n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};if(!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,Player),window.jQuery&&u instanceof jQuery&&(1<u.length&&window.console&&console.warn&&console.warn("A jQuery object with multiple elements was passed, using the first element."),u=u[0]),"undefined"!=typeof document&&"string"==typeof u&&(u=document.getElementById(u)),e=u,!Boolean(e&&1===e.nodeType&&"nodeName"in e&&e.ownerDocument&&e.ownerDocument.defaultView))throw new TypeError("You must pass either a valid element or a valid id.");if("IFRAME"===u.nodeName||(t=u.querySelector("iframe"))&&(u=t),"IFRAME"===u.nodeName&&!c(u.getAttribute("src")||""))throw new Error("The player element passed isn’t a Vimeo embed.");if(A.has(u))return A.get(u);this._window=u.ownerDocument.defaultView,this.element=u,this.origin="*";var r,o=new y(function(i,a){var e;l._onMessage=function(e){if(c(e.origin)&&l.element.contentWindow===e.source){"*"===l.origin&&(l.origin=e.origin);var t=E(e.data);if(t&&"error"===t.event&&t.data&&"ready"===t.data.method){var n=new Error(t.data.message);return n.name=t.data.name,void a(n)}
vendor: 5,252 bytes, line 23487
23487var r=t&&"ready"===t.event,o=t&&"ping"===t.method;if(r||o)return l.element.setAttribute("data-ready","true"),void i();P(l,t)}},l._window.addEventListener("message",l._onMessage),"IFRAME"!==l.element.nodeName&&F(s(e=_(u,n)),e,u).then(function(e){var t,n,r,o=N(e,u);return l.element=o,l._originalElement=u,t=u,n=o,r=g.get(t),g.set(n,r),g.delete(t),A.set(l.element,l),e}).catch(a)});return S.set(this,o),A.set(this.element,this),"IFRAME"===this.element.nodeName&&T(this,"ping"),q.isEnabled&&(r=function(){return q.exit()},this.fullscreenchangeHandler=function(){(q.isFullscreen?w:k)(l,"event:exitFullscreen",r),l.ready().then(function(){T(l,"fullscreenchange",q.isFullscreen)})},q.on("fullscreenchange",this.fullscreenchangeHandler)),this}var e,t,n;return e=Player,(t=[{key:"callMethod",value:function(n,e){var r=this,o=1<arguments.length&&void 0!==e?e:{};return new y(function(e,t){return r.ready().then(function(){w(r,n,{resolve:e,reject:t}),T(r,n,o)}).catch(t)})}},{key:"get",value:function(n){var r=this;return new y(function(e,t){return n=i(n,"get"),r.ready().then(function(){w(r,n,{resolve:e,reject:t}),T(r,n)}).catch(t)})}},{key:"set",value:function(n,r){var o=this;return new y(function(e,t){if(n=i(n,"set"),null==r)throw new TypeError("There must be a value to set.");return o.ready().then(function(){w(o,n,{resolve:e,reject:t}),T(o,n,r)}).catch(t)})}},{key:"on",value:function(e,t){if(!e)throw new TypeError("You must pass an event name.");if(!t)throw new TypeError("You must pass a callback function.");if("function"!=typeof t)throw new TypeError("The callback must be a function.");0===b(this,"event:".concat(e)).length&&this.callMethod("addEventListener",e).catch(function(){}),w(this,"event:".concat(e),t)}},{key:"off",value:function(e,t){if(!e)throw new TypeError("You must pass an event name.");if(t&&"function"!=typeof t)throw new TypeError("The callback must be a function.");k(this,"event:".concat(e),t)&&this.callMethod("removeEventListener",e).catch(function(e){})}},{key:"loadVideo",value:function(e){return this.callMethod("loadVideo",e)}},{key:"ready",value:function(){var e=S.get(this)||new y(function(e,t){t(new Error("Unknown player. Probably unloaded."))});return y.resolve(e)}},{key:"addCuePoint",value:function(e,t){var n=1<arguments.length&&void 0!==t?t:{};return this.callMethod("addCuePoint",{time:e,data:n})}},{key:"removeCuePoint",value:function(e){return this.callMethod("removeCuePoint",e)}},{key:"enableTextTrack",value:function(e,t){if(!e)throw new TypeError("You must pass a language.");return this.callMethod("enableTextTrack",{language:e,kind:t})}},{key:"disableTextTrack",value:function(){return this.callMethod("disableTextTrack")}},{key:"pause",value:function(){return this.callMethod("pause")}},{key:"play",value:function(){return this.callMethod("play")}},{key:"requestFullscreen",value:function(){return q.isEnabled?q.request(this.element):this.callMethod("requestFullscreen")}},{key:"exitFullscreen",value:function(){return q.isEnabled?q.exit():this.callMethod("exitFullscreen")}},{key:"getFullscreen",value:function(){return q.isEnabled?y.resolve(q.isFullscreen):this.get("fullscreen")}},{key:"requestPictureInPicture",value:function(){return this.callMethod("requestPictureInPicture")}},{key:"exitPictureInPicture",value:function(){return this.callMethod("exitPictureInPicture")}},{key:"getPictureInPicture",value:function(){return this.get("pictureInPicture")}},{key:"unload",value:function(){return this.callMethod("unload")}},{key:"destroy",value:function(){var n=this;return new y(function(e){var t;S.delete(n),A.delete(n.element),n._originalElement&&(A.delete(n._originalElement),n._originalElement.removeAttribute("data-vimeo-initialized")),n.element&&"IFRAME"===n.element.nodeName&&n.element.parentNode&&(n.element.parentNode.parentNode&&n._originalElement&&n._originalElement!==n.element.parentNode?n.element.parentNode.parentNode.removeChild(n.element.parentNode):n.element.parentNode.removeChild(n.element)),n.element&&"DIV"===n.element.nodeName&&n.element.parentNode&&(n.element.removeAttribute("data-vimeo-initialized"),(t=n.element.querySelector("iframe"))&&t.parentNode&&(t.parentNode.parentNode&&n._originalElement&&n._originalElement!==t.parentNode?t.parentNode.parentNode.removeChild(t.parentNode):t.parentNode.removeChild(t))),n._window.removeEventListener("message",n._onMessage),q.isEnabled&&q.off("fullscreenchange",n.fullscreenchangeHandler),e()})}},{key:"getAutopause",value:function(){return this.get("autopause")}},{key:"setAutopause",value:function(e){return this.set("autopause",e)}},{key:"getBuffered",value:function(){return this.get("buffered")}},{key:"getCameraProps",value:function(){return this.get("cameraProps")}},{key:"setCameraProps",value:function(e){return this.set("cameraProps",e)}},{key:"getChapters",value:function(){return this.get("chapters")}},{key:"getCurrentChapter",value:function(){return this.get("currentChapter")}},{key:"getColor",value:function(){return this.get("color")}},{key:"setColor",value:function(e){return this.set("color",e)}},{key:"getCuePoints",value:function(){return this.get("cuePoints")}},{key:"getCurrentTime",value:function(){return this.get("currentTime")}},{key:"setCurrentTime",value:function(e){return this.set("currentTime",e)}
23487},{key:"getDuration",value:function(){return this.get("duration")}},{key:"getEnded",value:function(){return this.get("ended")}},{key:"getLoop",value:function(){return this.get("loop")}},{key:"setLoop",value:function(e){return this.set("loop",e)}},{key:"setMuted",value:function(e){return this.set("muted",e)}},{key:"getMuted",value:function(){return this.get("muted")}},{key:"getPaused",value:function(){return this.get("paused")}},{key:"getPlaybackRate",value:function(){return this.get("playbackRate")}},{key:"setPlaybackRate",value:function(e){return this.set("playbackRate",e)}},{key:"getPlayed",value:function(){return this.get("played")}},{key:"getQualities",value:function(){return this.get("qualities")}},{key:"getQuality",value:function(){return this.get("quality")}},{key:"setQuality",value:function(e){return this.set("quality",e)}},{key:"getSeekable",value:function(){return this.get("seekable")}},{key:"getSeeking",value:function(){return this.get("seeking")}},{key:"getTextTracks",value:function(){return this.get("textTracks")}},{key:"getVideoEmbedCode",value:function(){return this.get("videoEmbedCode")}},{key:"getVideoId",value:function(){return this.get("videoId")}},{key:"getVideoTitle",value:function(){return this.get("videoTitle")}},{key:"getVideoWidth",value:function(){return this.get("videoWidth")}},{key:"getVideoHeight",value:function(){return this.get("videoHeight")}},{key:"getVideoUrl",value:function(){return this.get("videoUrl")}},{key:"getVolume",value:function(){return this.get("volume")}},{key:"setVolume",value:function(e){return this.set("volume",e)}}])&&r(e.prototype,t),n&&r(e,n),Player}();return e||(x=function(){for(var e,t=[["requestFullscreen","exitFullscreen","fullscreenElement","fullscreenEnabled","fullscreenchange","fullscreenerror"],["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen","msExitFullscreen","msFullscreenElement","msFullscreenEnabled","MSFullscreenChange","MSFullscreenError"]],n=0,r=t.length,o={};n<r;n++)if((e=t[n])&&e[1]in document){for(n=0;n<e.length;n++)o[t[0][n]]=e[n];return o}return!1}(),C={fullscreenchange:x.fullscreenchange,fullscreenerror:x.fullscreenerror},j={request:function(o){return new Promise(function(e,t){function n(){j.off("fullscreenchange",n),e()}j.on("fullscreenchange",n);var r=(o=o||document.documentElement)[x.requestFullscreen]();r instanceof Promise&&r.then(n).catch(t)})},exit:function(){return new Promise(function(t,e){var n,r;j.isFullscreen?(n=function e(){j.off("fullscreenchange",e),t()},j.on("fullscreenchange",n),(r=document[x.exitFullscreen]())instanceof Promise&&r.then(n).catch(e)):t()})},on:function(e,t){var n=C[e];n&&document.addEventListener(n,t)},off:function(e,t){var n=C[e];n&&document.removeEventListener(n,t)}},Object.defineProperties(j,{isFullscreen:{get:function(){return Boolean(document[x.fullscreenElement])}},element:{enumerable:!0,get:function(){return document[x.fullscreenElement]}},isEnabled:{enumerable:!0,get:function(){return Boolean(document[x.fullscreenEnabled])}}}),q=j,function(e){function n(e){"console"in window&&console.error&&console.error("There was an error creating an embed: ".concat(e))}var t=0<arguments.length&&void 0!==e?e:document;[].slice.call(t.querySelectorAll("[data-vimeo-id], [data-vimeo-url]")).forEach(function(t){try{if(null!==t.getAttribute("data-vimeo-defer"))return;var e=_(t);F(s(e),e,t).then(function(e){return N(e,t)}).catch(n)}catch(e){n(e)}})}(),function(e){var r=0<arguments.length&&void 0!==e?e:document;window.VimeoPlayerResizeEmbeds_||(window.VimeoPlayerResizeEmbeds_=!0,window.addEventListener("message",function(e){if(c(e.origin)&&e.data&&"spacechange"===e.data.event)for(var t=r.querySelectorAll("iframe"),n=0;n<t.length;n++)if(t[n].contentWindow===e.source){t[n].parentElement.style.paddingBottom="".concat(e.data.data[0].bottom,"px");break}}
vendor: 31,994 bytes, lines 23487-24694
23487))}(),function(e){var u=0<arguments.length&&void 0!==e?e:document;window.VimeoSeoMetadataAppended||(window.VimeoSeoMetadataAppended=!0,window.addEventListener("message",function(e){if(c(e.origin)){var t=E(e.data);if(t&&"ready"===t.event)for(var n,r=u.querySelectorAll("iframe"),o=0;o<r.length;o++){var i=r[o],a=i.contentWindow===e.source;n=i.src,/^https:\/\/player\.vimeo\.com\/video\/\d+/.test(n)&&a&&new Player(i).callMethod("appendVideoMetadata",window.location.href)}}}))}()),Player});
23488
23489/**
23490 * Owl carousel
23491 * @version 2.0.0-beta.3
23492 * @author Bartosz Wojciechowski
23493 * @license The MIT License (MIT)
23494 * @todo Lazy Load Icon
23495 * @todo prevent animationend bubling
23496 * @todo itemsScaleUp
23497 * @todo Test Zepto
23498 * @todo stagePadding calculate wrong active classes
23499 */
23500;(function($, window, document, undefined) {
23501
23502	/**
23503	 * Creates a carousel.
23504	 * @class The Owl Carousel.
23505	 * @public
23506	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
23507	 * @param {Object} [options] - The options
23508	 */
23509	function Owl(element, options) {
23510
23511		/**
23512		 * Current settings for the carousel.
23513		 * @public
23514		 */
23515		this.settings = null;
23516
23517		/**
23518		 * Current options set by the caller including defaults.
23519		 * @public
23520		 */
23521		this.options = $.extend({}, Owl.Defaults, options);
23522
23523		/**
23524		 * Plugin element.
23525		 * @public
23526		 */
23527		this.$element = $(element);
23528
23529		/**
23530		 * Proxied event handlers.
23531		 * @protected
23532		 */
23533		this._handlers = {};
23534
23535		/**
23536		 * References to the running plugins of this carousel.
23537		 * @protected
23538		 */
23539		this._plugins = {};
23540
23541		/**
23542		 * Currently suppressed events to prevent them from beeing retriggered.
23543		 * @protected
23544		 */
23545		this._supress = {};
23546
23547		/**
23548		 * Absolute current position.
23549		 * @protected
23550		 */
23551		this._current = null;
23552
23553		/**
23554		 * Animation speed in milliseconds.
23555		 * @protected
23556		 */
23557		this._speed = null;
23558
23559		/**
23560		 * Coordinates of all items in pixel.
23561		 * @todo The name of this member is missleading.
23562		 * @protected
23563		 */
23564		this._coordinates = [];
23565
23566		/**
23567		 * Current breakpoint.
23568		 * @todo Real media queries would be nice.
23569		 * @protected
23570		 */
23571		this._breakpoint = null;
23572
23573		/**
23574		 * Current width of the plugin element.
23575		 */
23576		this._width = null;
23577
23578		/**
23579		 * All real items.
23580		 * @protected
23581		 */
23582		this._items = [];
23583
23584		/**
23585		 * All cloned items.
23586		 * @protected
23587		 */
23588		this._clones = [];
23589
23590		/**
23591		 * Merge values of all items.
23592		 * @todo Maybe this could be part of a plugin.
23593		 * @protected
23594		 */
23595		this._mergers = [];
23596
23597		/**
23598		 * Widths of all items.
23599		 */
23600		this._widths = [];
23601
23602		/**
23603		 * Invalidated parts within the update process.
23604		 * @protected
23605		 */
23606		this._invalidated = {};
23607
23608		/**
23609		 * Ordered list of workers for the update process.
23610		 * @protected
23611		 */
23612		this._pipe = [];
23613
23614		/**
23615		 * Current state information for the drag operation.
23616		 * @todo #261
23617		 * @protected
23618		 */
23619		this._drag = {
23620			time: null,
23621			target: null,
23622			pointer: null,
23623			stage: {
23624				start: null,
23625				current: null
23626			},
23627			direction: null
23628		};
23629
23630		/**
23631		 * Current state information and their tags.
23632		 * @type {Object}
23633		 * @protected
23634		 */
23635		this._states = {
23636			current: {},
23637			tags: {
23638				'initializing': [ 'busy' ],
23639				'animating': [ 'busy' ],
23640				'dragging': [ 'interacting' ]
23641			}
23642		};
23643
23644		$.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
23645			this._handlers[handler] = $.proxy(this[handler], this);
23646		}, this));
23647
23648		$.each(Owl.Plugins, $.proxy(function(key, plugin) {
23649			this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
23650				= new plugin(this);
23651		}, this));
23652
23653		$.each(Owl.Workers, $.proxy(function(priority, worker) {
23654			this._pipe.push({
23655				'filter': worker.filter,
23656				'run': $.proxy(worker.run, this)
23657			});
23658		}, this));
23659
23660		this.setup();
23661		this.initialize();
23662	}
23663
23664	/**
23665	 * Default options for the carousel.
23666	 * @public
23667	 */
23668	Owl.Defaults = {
23669		items: 3,
23670		loop: false,
23671		center: false,
23672		rewind: false,
23673
23674		mouseDrag: true,
23675		touchDrag: true,
23676		pullDrag: true,
23677		freeDrag: false,
23678
23679		margin: 0,
23680		stagePadding: 0,
23681
23682		merge: false,
23683		mergeFit: true,
23684		autoWidth: false,
23685
23686		startPosition: 0,
23687		rtl: false,
23688
23689		smartSpeed: 250,
23690		fluidSpeed: false,
23691		dragEndSpeed: false,
23692
23693		responsive: {},
23694		responsiveRefreshRate: 200,
23695		responsiveBaseElement: window,
23696
23697		fallbackEasing: 'swing',
23698
23699		info: false,
23700
23701		nestedItemSelector: false,
23702		itemElement: 'div',
23703		stageElement: 'div',
23704
23705		refreshClass: 'owl-refresh',
23706		loadedClass: 'owl-loaded',
23707		loadingClass: 'owl-loading',
23708		rtlClass: 'owl-rtl',
23709		responsiveClass: 'owl-responsive',
23710		dragClass: 'owl-drag',
23711		itemClass: 'owl-item',
23712		stageClass: 'owl-stage',
23713		stageOuterClass: 'owl-stage-outer',
23714		grabClass: 'owl-grab'
23715	};
23716
23717	/**
23718	 * Enumeration for width.
23719	 * @public
23720	 * @readonly
23721	 * @enum {String}
23722	 */
23723	Owl.Width = {
23724		Default: 'default',
23725		Inner: 'inner',
23726		Outer: 'outer'
23727	};
23728
23729	/**
23730	 * Enumeration for types.
23731	 * @public
23732	 * @readonly
23733	 * @enum {String}
23734	 */
23735	Owl.Type = {
23736		Event: 'event',
23737		State: 'state'
23738	};
23739
23740	/**
23741	 * Contains all registered plugins.
23742	 * @public
23743	 */
23744	Owl.Plugins = {};
23745
23746	/**
23747	 * List of workers involved in the update process.
23748	 */
23749	Owl.Workers = [ {
23750		filter: [ 'width', 'settings' ],
23751		run: function() {
23752			this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width();
23753			//this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12);
23754		}
23755	}, {
23756		filter: [ 'width', 'items', 'settings' ],
23757		run: function(cache) {
23758			cache.current = this._items && this._items[this.relative(this._current)];
23759		}
23760	}, {
23761		filter: [ 'items', 'settings' ],
23762		run: function() {
23763			this.$stage.children('.cloned').remove();
23764		}
23765	}, {
23766		filter: [ 'width', 'items', 'settings' ],
23767		run: function(cache) {
23768			var margin = this.settings.margin || '',
23769				grid = !this.settings.autoWidth,
23770				rtl = this.settings.rtl,
23771				css = {
23772					'width': 'auto',
23773					'margin-left': rtl ? margin : '',
23774					'margin-right': rtl ? '' : margin
23775				};
23776
23777			!grid && this.$stage.children().css(css);
23778
23779			cache.css = css;
23780		}
23781	}, {
23782		filter: [ 'width', 'items', 'settings' ],
23783		run: function(cache) {
23784			//UNCODE edit to fix Chrome stage padding issue
23785			var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin),
23786				merge = null,
23787				iterator = this._items.length,
23788				grid = !this.settings.autoWidth,
23789				widths = [];
23790
23791			cache.items = {
23792				merge: false,
23793				width: width
23794			};
23795
23796			while (iterator--) {
23797				merge = this._mergers[iterator];
23798				merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
23799
23800				cache.items.merge = merge > 1 || cache.items.merge;
23801
23802				widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
23803			}
23804
23805			this._widths = widths;
23806		}
23807	}, {
23808		filter: [ 'items', 'settings' ],
23809		run: function() {
23810			var clones = [],
23811				items = this._items,
23812				settings = this.settings,
23813				view = Math.max(settings.items * 2, 4),
23814				size = Math.ceil(items.length / 2) * 2,
23815				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
23816				append = '',
23817				prepend = '';
23818
23819			repeat /= 2;
23820
23821			while (repeat--) {
23822				clones.push(this.normalize(clones.length / 2, true));
23823				append = append + items[clones[clones.length - 1]][0].outerHTML;
23824				clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
23825				prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
23826			}
23827
23828			this._clones = clones;
23829
23830			// var appendVideo = $(append).find('.uncode-video-container');
23831			// if (appendVideo.length) {
23832			// 	appendVideo.attr('data-id', Math.round(Math.random() * 100000));
23833			// }
23834			// var prependVideo = $(prepend).find('.uncode-video-container');
23835			// if (prependVideo.length) {
23836			// 	prependVideo.attr('data-id', Math.round(Math.random() * 100000));
23837			// }
23838			$(append).addClass('cloned').appendTo(this.$stage);
23839			$(prepend).addClass('cloned').prependTo(this.$stage);
23840		}
23841	}, {
23842		filter: [ 'width', 'items', 'settings' ],
23843		run: function() {
23844			var rtl = this.settings.rtl ? 1 : -1,
23845				size = this._clones.length + this._items.length,
23846				iterator = -1,
23847				previous = 0,
23848				current = 0,
23849				coordinates = [];
23850
23851			while (++iterator < size) {
23852				previous = coordinates[iterator - 1] || 0;
23853				current = this._widths[this.relative(iterator)] + this.settings.margin;
23854				coordinates.push(previous + current * rtl);
23855			}
23856
23857			this._coordinates = coordinates;
23858		}
23859	}, {
23860		filter: [ 'width', 'items', 'settings' ],
23861		run: function() {
23862			var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200,
23863				padding = stagePadding,
23864				coordinates = this._coordinates,
23865				css = {
23866					'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
23867					'padding-left': padding || '',
23868					'padding-right': padding || ''
23869				};
23870
23871			this.$stage.css(css);
23872		}
23873	}, {
23874		filter: [ 'width', 'items', 'settings' ],
23875		run: function(cache) {
23876			var iterator = this._coordinates.length,
23877				grid = !this.settings.autoWidth,
23878				items = this.$stage.children();
23879
23880			if (grid && cache.items.merge) {
23881				while (iterator--) {
23882					cache.css.width = this._widths[this.relative(iterator)];
23883					items.eq(iterator).css(cache.css);
23884				}
23885			} else if (grid) {
23886				cache.css.width = cache.items.width;
23887				items.css(cache.css);
23888			}
23889		}
23890	}, {
23891		filter: [ 'items' ],
23892		run: function() {
23893			this._coordinates.length < 1 && this.$stage.removeAttr('style');
23894		}
23895	}, {
23896		filter: [ 'width', 'items', 'settings' ],
23897		run: function(cache) {
23898			cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
23899			cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
23900			this.reset(cache.current);
23901		}
23902	}, {
23903		filter: [ 'position' ],
23904		run: function() {
23905			this.animate(this.coordinates(this._current));
23906		}
23907	}, {
23908		filter: [ 'width', 'position', 'items', 'settings' ],
23909		run: function() {
23910			var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200,
23911				rtl = this.settings.rtl ? 1 : -1,
23912				padding = this.settings.stagePadding * 2,
23913				begin = this.coordinates(this.current()) + padding,
23914				end = begin + this.width() * rtl,
23915				inner, outer, matches = [], i, n;
23916
23917			for (i = 0, n = this._coordinates.length; i < n; i++) {
23918				inner = this._coordinates[i - 1] || 0;
23919				outer = Math.abs(this._coordinates[i]) + padding * rtl;
23920
23921				if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
23922					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
23923					matches.push(i);
23924				}
23925			}
23926
23927			this.$stage.children('.active').removeClass('active');
23928			this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
23929
23930			if (this.settings.center) {
23931				this.$stage.children('.center').removeClass('center');
23932				this.$stage.children().eq(this.current()).addClass('center');
23933			}
23934		}
23935	} ];
23936
23937	/**
23938	 * Initializes the carousel.
23939	 * @protected
23940	 */
23941	Owl.prototype.initialize = function() {
23942		this.enter('initializing');
23943		this.trigger('initialize');
23944
23945		this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
23946
23947		if (this.settings.autoWidth && !this.is('pre-loading')) {
23948			var imgs, nestedSelector, width;
23949			imgs = this.$element.find('img');
23950			nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
23951			width = this.$element.children(nestedSelector).width();
23952
23953			if (imgs.length && width <= 0) {
23954				this.preloadAutoWidthImages(imgs);
23955			}
23956		}
23957
23958		this.$element.addClass(this.options.loadingClass);
23959
23960		// create stage
23961		this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')
23962			.wrap('<div class="' + this.settings.stageOuterClass + '"/>');
23963
23964		// append stage
23965		this.$element.append(this.$stage.parent());
23966
23967		// append content
23968		this.replace(this.$element.children().not(this.$stage.parent()));
23969
23970		// check visibility
23971		if (this.$element.is(':visible')) {
23972			// update view
23973			this.refresh();
23974		} else {
23975			// invalidate width
23976			this.invalidate('width');
23977		}
23978
23979		this.$element
23980			.removeClass(this.options.loadingClass)
23981			.addClass(this.options.loadedClass);
23982
23983		// register event handlers
23984		this.registerEventHandlers();
23985
23986		this.leave('initializing');
23987		this.trigger('initialized');
23988	};
23989
23990	/**
23991	 * Setups the current settings.
23992	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
23993	 * @todo Support for media queries by using `matchMedia` would be nice.
23994	 * @public
23995	 */
23996	Owl.prototype.setup = function() {
23997		var viewport = this.viewport(),
23998			overwrites = this.options.responsive,
23999			match = -1,
24000			settings = null;
24001
24002		if (!overwrites) {
24003			settings = $.extend({}, this.options);
24004		} else {
24005			$.each(overwrites, function(breakpoint) {
24006				if (breakpoint <= viewport && breakpoint > match) {
24007					match = Number(breakpoint);
24008				}
24009			});
24010
24011			settings = $.extend({}, this.options, overwrites[match]);
24012			delete settings.responsive;
24013
24014			// responsive class
24015			if (settings.responsiveClass) {
24016				this.$element.attr('class',
24017					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
24018				);
24019			}
24020		}
24021
24022		if (this.settings === null || this._breakpoint !== match) {
24023			this.trigger('change', { property: { name: 'settings', value: settings } });
24024			this._breakpoint = match;
24025			this.settings = settings;
24026			this.invalidate('settings');
24027			this.trigger('changed', { property: { name: 'settings', value: this.settings } });
24028		}
24029	};
24030
24031	/**
24032	 * Updates option logic if necessery.
24033	 * @protected
24034	 */
24035	Owl.prototype.optionsLogic = function() {
24036		if (this.settings.autoWidth) {
24037			this.settings.stagePadding = false;
24038			this.settings.merge = false;
24039		}
24040	};
24041
24042	/**
24043	 * Prepares an item before add.
24044	 * @todo Rename event parameter `content` to `item`.
24045	 * @protected
24046	 * @returns {jQuery|HTMLElement} - The item container.
24047	 */
24048	Owl.prototype.prepare = function(item, index) {
24049		var event = this.trigger('prepare', { content: item });
24050		if (!event.data) {
24051			event.data = $('<' + this.settings.itemElement + '/>')
24052				.addClass(this.options.itemClass).attr('data-index', index + 1).append(item)
24053		}
24054
24055		this.trigger('prepared', { content: event.data });
24056
24057		return event.data;
24058	};
24059
24060	/**
24061	 * Updates the view.
24062	 * @public
24063	 */
24064	Owl.prototype.update = function() {
24065		var i = 0,
24066			n = this._pipe.length,
24067			filter = $.proxy(function(p) { return this[p] }, this._invalidated),
24068			cache = {};
24069
24070		while (i < n) {
24071			if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
24072				this._pipe[i].run(cache);
24073			}
24074			i++;
24075		}
24076
24077		this._invalidated = {};
24078
24079		!this.is('valid') && this.enter('valid');
24080	};
24081
24082	/**
24083	 * Gets the width of the view.
24084	 * @public
24085	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
24086	 * @returns {Number} - The width of the view in pixel.
24087	 */
24088	Owl.prototype.width = function(dimension) {
24089		dimension = dimension || Owl.Width.Default;
24090		var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200;
24091		switch (dimension) {
24092			case Owl.Width.Inner:
24093			case Owl.Width.Outer:
24094				return this._width;
24095			default:
24096				return this._width - stagePadding * 2 + this.settings.margin;
24097		}
24098	};
24099
24100	/**
24101	 * Refreshes the carousel primarily for adaptive purposes.
24102	 * @public
24103	 */
24104	Owl.prototype.refresh = function() {
24105		this.enter('refreshing');
24106		this.trigger('refresh');
24107
24108		this.setup();
24109
24110		this.optionsLogic();
24111
24112		this.$element.addClass(this.options.refreshClass);
24113
24114		this.update();
24115
24116		this.$element.removeClass(this.options.refreshClass);
24117
24118		this.leave('refreshing');
24119		this.trigger('refreshed');
24120	};
24121
24122	/**
24123	 * Checks window `resize` event.
24124	 * @protected
24125	 */
24126	Owl.prototype.onThrottledResize = function() {
24127		window.clearTimeout(this.resizeTimer);
24128		this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
24129	};
24130
24131	/**
24132	 * Checks window `resize` event.
24133	 * @protected
24134	 */
24135	Owl.prototype.onResize = function() {
24136		if (!this._items.length) {
24137			return false;
24138		}
24139
24140		if (this._width === this.$element.width()) {
24141			return false;
24142		}
24143
24144		if (!this.$element.is(':visible')) {
24145			return false;
24146		}
24147
24148		this.enter('resizing');
24149
24150		if (this.trigger('resize').isDefaultPrevented()) {
24151			this.leave('resizing');
24152			return false;
24153		}
24154
24155		this.invalidate('width');
24156
24157		this.refresh();
24158
24159		this.leave('resizing');
24160		this.trigger('resized');
24161	};
24162
24163	/**
24164	 * Registers event handlers.
24165	 * @todo Check `msPointerEnabled`
24166	 * @todo #261
24167	 * @protected
24168	 */
24169	Owl.prototype.registerEventHandlers = function() {
24170		if ($.support.transition) {
24171			this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
24172		}
24173
24174		if (this.settings.responsive !== false) {
24175			this.on(window, 'resize', this._handlers.onThrottledResize);
24176		}
24177
24178		if (this.settings.mouseDrag) {
24179			this.$element.addClass(this.options.dragClass);
24180			this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
24181			this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
24182		}
24183
24184		if (this.settings.touchDrag){
24185			this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
24186			this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
24187		}
24188	};
24189
24190	/**
24191	 * Handles `touchstart` and `mousedown` events.
24192	 * @todo Horizontal swipe threshold as option
24193	 * @todo #261
24194	 * @protected
24195	 * @param {Event} event - The event arguments.
24196	 */
24197	Owl.prototype.onDragStart = function(event) {
24198		var stage = null;
24199
24200		if (event.which === 3) {
24201			return;
24202		}
24203
24204		if ($.support.transform) {
24205			stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
24206			stage = {
24207				x: stage[stage.length === 16 ? 12 : 4],
24208				y: stage[stage.length === 16 ? 13 : 5]
24209			};
24210		} else {
24211			stage = this.$stage.position();
24212			stage = {
24213				x: this.settings.rtl ?
24214					stage.left + this.$stage.width() - this.width() + this.settings.margin :
24215					stage.left,
24216				y: stage.top
24217			};
24218		}
24219
24220		if (this.is('animating')) {
24221			$.support.transform ? this.animate(stage.x) : this.$stage.stop()
24222			this.invalidate('position');
24223		}
24224
24225		this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
24226
24227		this.speed(0);
24228
24229		this._drag.time = new Date().getTime();
24230		this._drag.target = $(event.target);
24231		this._drag.stage.start = stage;
24232		this._drag.stage.current = stage;
24233		this._drag.pointer = this.pointer(event);
24234
24235		$(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
24236
24237		$(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
24238			var delta = this.difference(this._drag.pointer, this.pointer(event));
24239
24240			$(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
24241
24242			if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
24243				return;
24244			}
24245
24246			event.preventDefault();
24247
24248			this.enter('dragging');
24249			this.trigger('drag');
24250		}, this));
24251	};
24252
24253	/**
24254	 * Handles the `touchmove` and `mousemove` events.
24255	 * @todo #261
24256	 * @protected
24257	 * @param {Event} event - The event arguments.
24258	 */
24259	Owl.prototype.onDragMove = function(event) {
24260		var minimum = null,
24261			maximum = null,
24262			pull = null,
24263			delta = this.difference(this._drag.pointer, this.pointer(event)),
24264			stage = this.difference(this._drag.stage.start, delta);
24265
24266		if (!this.is('dragging')) {
24267			return;
24268		}
24269
24270		event.preventDefault();
24271
24272		if (this.settings.loop) {
24273			minimum = this.coordinates(this.minimum());
24274			maximum = this.coordinates(this.maximum() + 1) - minimum;
24275			stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
24276		} else {
24277			minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
24278			maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
24279			pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
24280			stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
24281		}
24282
24283		this._drag.stage.current = stage;
24284
24285		this.animate(stage.x);
24286	};
24287
24288	/**
24289	 * Handles the `touchend` and `mouseup` events.
24290	 * @todo #261
24291	 * @todo Threshold for click event
24292	 * @protected
24293	 * @param {Event} event - The event arguments.
24294	 */
24295	Owl.prototype.onDragEnd = function(event) {
24296		var delta = this.difference(this._drag.pointer, this.pointer(event)),
24297			stage = this._drag.stage.current,
24298			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
24299
24300		$(document).off('.owl.core');
24301
24302		this.$element.removeClass(this.options.grabClass);
24303
24304		if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
24305			this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
24306			this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
24307			this.invalidate('position');
24308			this.update();
24309
24310			this._drag.direction = direction;
24311
24312			if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
24313				this._drag.target.one('click.owl.core', function() { return false; });
24314			}
24315		}
24316
24317		if (!this.is('dragging')) {
24318			return;
24319		}
24320
24321		this.leave('dragging');
24322		this.trigger('dragged');
24323	};
24324
24325	/**
24326	 * Gets absolute position of the closest item for a coordinate.
24327	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
24328	 * @protected
24329	 * @param {Number} coordinate - The coordinate in pixel.
24330	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
24331	 * @return {Number} - The absolute position of the closest item.
24332	 */
24333	Owl.prototype.closest = function(coordinate, direction) {
24334		var position = -1,
24335			pull = 30,
24336			width = this.width(),
24337			coordinates = this.coordinates();
24338
24339		if (!this.settings.freeDrag) {
24340			// check closest item
24341			$.each(coordinates, $.proxy(function(index, value) {
24342				if (coordinate > value - pull && coordinate < value + pull) {
24343					position = index;
24344				} else if (this.op(coordinate, '<', value)
24345					&& this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
24346					position = direction === 'left' ? index + 1 : index;
24347				}
24348				return position === -1;
24349			}, this));
24350		}
24351
24352		if (!this.settings.loop) {
24353			// non loop boundries
24354			if (this.op(coordinate, '>', coordinates[this.minimum()])) {
24355				position = coordinate = this.minimum();
24356			} else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
24357				position = coordinate = this.maximum();
24358			}
24359		}
24360
24361		return position;
24362	};
24363
24364	/**
24365	 * Animates the stage.
24366	 * @todo #270
24367	 * @public
24368	 * @param {Number} coordinate - The coordinate in pixels.
24369	 */
24370	Owl.prototype.animate = function(coordinate) {
24371		var animate = this.speed() > 0;
24372
24373		this.is('animating') && this.onTransitionEnd();
24374
24375		if (animate) {
24376			this.enter('animating');
24377			this.trigger('translate');
24378		}
24379
24380		if ($.support.transform3d && $.support.transition) {
24381			this.$stage.css({
24382				transform: 'translate3d(' + coordinate + 'px,0px,0px)',
24383				transition: (this.speed() / 1000) + 's'
24384			});
24385		} else if (animate) {
24386			this.$stage.animate({
24387				left: coordinate + 'px'
24388			}, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
24389		} else {
24390			this.$stage.css({
24391				left: coordinate + 'px'
24392			});
24393		}
24394	};
24395
24396	/**
24397	 * Checks whether the carousel is in a specific state or not.
24398	 * @param {String} state - The state to check.
24399	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
24400	 */
24401	Owl.prototype.is = function(state) {
24402		return this._states.current[state] && this._states.current[state] > 0;
24403	};
24404
24405	/**
24406	 * Sets the absolute position of the current item.
24407	 * @public
24408	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
24409	 * @returns {Number} - The absolute position of the current item.
24410	 */
24411	Owl.prototype.current = function(position) {
24412		if (position === undefined) {
24413			return this._current;
24414		}
24415
24416		if (this._items.length === 0) {
24417			return undefined;
24418		}
24419
24420		position = this.normalize(position);
24421
24422		if (this._current !== position) {
24423			var event = this.trigger('change', { property: { name: 'position', value: position } });
24424
24425			if (event.data !== undefined) {
24426				position = this.normalize(event.data);
24427			}
24428
24429			this._current = position;
24430
24431			this.invalidate('position');
24432
24433			this.trigger('changed', { property: { name: 'position', value: this._current } });
24434		}
24435
24436		return this._current;
24437	};
24438
24439	/**
24440	 * Invalidates the given part of the update routine.
24441	 * @param {String} [part] - The part to invalidate.
24442	 * @returns {Array.<String>} - The invalidated parts.
24443	 */
24444	Owl.prototype.invalidate = function(part) {
24445		if ($.type(part) === 'string') {
24446			this._invalidated[part] = true;
24447			this.is('valid') && this.leave('valid');
24448		}
24449		return $.map(this._invalidated, function(v, i) { return i });
24450	};
24451
24452	/**
24453	 * Resets the absolute position of the current item.
24454	 * @public
24455	 * @param {Number} position - The absolute position of the new item.
24456	 */
24457	Owl.prototype.reset = function(position) {
24458		position = this.normalize(position);
24459
24460		if (position === undefined) {
24461			return;
24462		}
24463
24464		this._speed = 0;
24465		this._current = position;
24466
24467		this.suppress([ 'translate', 'translated' ]);
24468
24469		this.animate(this.coordinates(position));
24470
24471		this.release([ 'translate', 'translated' ]);
24472	};
24473
24474	/**
24475	 * Normalizes an absolute or a relative position of an item.
24476	 * @public
24477	 * @param {Number} position - The absolute or relative position to normalize.
24478	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
24479	 * @returns {Number} - The normalized position.
24480	 */
24481	Owl.prototype.normalize = function(position, relative) {
24482		var n = this._items.length,
24483			m = relative ? 0 : this._clones.length;
24484
24485		if (!$.isNumeric(position) || n < 1) {
24486			position = undefined;
24487		} else if (position < 0 || position >= n + m) {
24488			position = ((position - m / 2) % n + n) % n + m / 2;
24489		}
24490
24491		return position;
24492	};
24493
24494	/**
24495	 * Converts an absolute position of an item into a relative one.
24496	 * @public
24497	 * @param {Number} position - The absolute position to convert.
24498	 * @returns {Number} - The converted position.
24499	 */
24500	Owl.prototype.relative = function(position) {
24501		position -= this._clones.length / 2;
24502		return this.normalize(position, true);
24503	};
24504
24505	/**
24506	 * Gets the maximum position for the current item.
24507	 * @public
24508	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
24509	 * @returns {Number}
24510	 */
24511	Owl.prototype.maximum = function(relative) {
24512		var settings = this.settings,
24513			maximum = this._coordinates.length,
24514			boundary = Math.abs(this._coordinates[maximum - 1]) - this._width,
24515			i = -1, j;
24516
24517		if (settings.loop) {
24518			maximum = this._clones.length / 2 + this._items.length - 1;
24519		} else if (settings.autoWidth || settings.merge) {
24520			// binary search
24521			while (maximum - i > 1) {
24522				Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary
24523					? i = j : maximum = j;
24524			}
24525		} else if (settings.center) {
24526			maximum = this._items.length - 1;
24527		} else {
24528			maximum = this._items.length - settings.items;
24529		}
24530
24531		if (relative) {
24532			maximum -= this._clones.length / 2;
24533		}
24534
24535		return Math.max(maximum, 0);
24536	};
24537
24538	/**
24539	 * Gets the minimum position for the current item.
24540	 * @public
24541	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
24542	 * @returns {Number}
24543	 */
24544	Owl.prototype.minimum = function(relative) {
24545		return relative ? 0 : this._clones.length / 2;
24546	};
24547
24548	/**
24549	 * Gets an item at the specified relative position.
24550	 * @public
24551	 * @param {Number} [position] - The relative position of the item.
24552	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
24553	 */
24554	Owl.prototype.items = function(position) {
24555		if (position === undefined) {
24556			return this._items.slice();
24557		}
24558
24559		position = this.normalize(position, true);
24560		return this._items[position];
24561	};
24562
24563	/**
24564	 * Gets an item at the specified relative position.
24565	 * @public
24566	 * @param {Number} [position] - The relative position of the item.
24567	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
24568	 */
24569	Owl.prototype.mergers = function(position) {
24570		if (position === undefined) {
24571			return this._mergers.slice();
24572		}
24573
24574		position = this.normalize(position, true);
24575		return this._mergers[position];
24576	};
24577
24578	/**
24579	 * Gets the absolute positions of clones for an item.
24580	 * @public
24581	 * @param {Number} [position] - The relative position of the item.
24582	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
24583	 */
24584	Owl.prototype.clones = function(position) {
24585		var odd = this._clones.length / 2,
24586			even = odd + this._items.length,
24587			map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
24588
24589		if (position === undefined) {
24590			return $.map(this._clones, function(v, i) { return map(i) });
24591		}
24592
24593		return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
24594	};
24595
24596	/**
24597	 * Sets the current animation speed.
24598	 * @public
24599	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
24600	 * @returns {Number} - The current animation speed in milliseconds.
24601	 */
24602	Owl.prototype.speed = function(speed) {
24603		if (speed !== undefined) {
24604			this._speed = speed;
24605		}
24606
24607		return this._speed;
24608	};
24609
24610	/**
24611	 * Gets the coordinate of an item.
24612	 * @todo The name of this method is missleanding.
24613	 * @public
24614	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
24615	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
24616	 */
24617	Owl.prototype.coordinates = function(position) {
24618		var coordinate = null;
24619
24620		if (position === undefined) {
24621			return $.map(this._coordinates, $.proxy(function(coordinate, index) {
24622				return this.coordinates(index);
24623			}, this));
24624		}
24625
24626		if (this.settings.center) {
24627			coordinate = this._coordinates[position];
24628			coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1);
24629		} else {
24630			coordinate = this._coordinates[position - 1] || 0;
24631		}
24632
24633		return coordinate;
24634	};
24635
24636	/**
24637	 * Calculates the speed for a translation.
24638	 * @protected
24639	 * @param {Number} from - The absolute position of the start item.
24640	 * @param {Number} to - The absolute position of the target item.
24641	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
24642	 * @returns {Number} - The time in milliseconds for the translation.
24643	 */
24644	Owl.prototype.duration = function(from, to, factor) {
24645		return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
24646	};
24647
24648	/**
24649	 * Slides to the specified item.
24650	 * @public
24651	 * @param {Number} position - The position of the item.
24652	 * @param {Number} [speed] - The time in milliseconds for the transition.
24653	 */
24654	Owl.prototype.to = function(position, speed) {
24655		var current = this.current(),
24656			revert = null,
24657			distance = position - this.relative(current),
24658			direction = (distance > 0) - (distance < 0),
24659			items = this._items.length,
24660			minimum = this.minimum(),
24661			maximum = this.maximum();
24662
24663		if (this.settings.loop) {
24664			if (!this.settings.rewind && Math.abs(distance) > items / 2) {
24665				distance += direction * -1 * items;
24666			}
24667
24668			position = current + distance;
24669			revert = ((position - minimum) % items + items) % items + minimum;
24670
24671			if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
24672				current = revert - distance;
24673				position = revert;
24674				this.reset(current);
24675			}
24676		} else if (this.settings.rewind) {
24677			maximum += 1;
24678			position = (position % maximum + maximum) % maximum;
24679		} else {
24680			position = Math.max(minimum, Math.min(maximum, position));
24681		}
24682
24683		this.speed(this.duration(current, position, speed));
24684		this.current(position);
24685
24686		if (this.$element.is(':visible')) {
24687			this.update();
24688		}
24689	};
24690
24691	/**
24692	 * Slides to the next item.
24693	 * @public
24694	 * @param {Number}
vendor: 4,086 bytes, lines 24694-24830
24694 [speed] - The time in milliseconds for the transition.
24695	 */
24696	Owl.prototype.next = function(speed) {
24697		speed = speed || false;
24698		this.to(this.relative(this.current()) + 1, speed);
24699	};
24700
24701	/**
24702	 * Slides to the previous item.
24703	 * @public
24704	 * @param {Number} [speed] - The time in milliseconds for the transition.
24705	 */
24706	Owl.prototype.prev = function(speed) {
24707		speed = speed || false;
24708		this.to(this.relative(this.current()) - 1, speed);
24709	};
24710
24711	/**
24712	 * Handles the end of an animation.
24713	 * @protected
24714	 * @param {Event} event - The event arguments.
24715	 */
24716	Owl.prototype.onTransitionEnd = function(event) {
24717
24718		// if css2 animation then event object is undefined
24719		if (event !== undefined) {
24720			event.stopPropagation();
24721
24722			// Catch only owl-stage transitionEnd event
24723			if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
24724				return false;
24725			}
24726		}
24727
24728		this.leave('animating');
24729		this.trigger('translated');
24730	};
24731
24732	/**
24733	 * Gets viewport width.
24734	 * @protected
24735	 * @return {Number} - The width in pixel.
24736	 */
24737	Owl.prototype.viewport = function() {
24738		var width;
24739		if (this.options.responsiveBaseElement !== window) {
24740			width = $(this.options.responsiveBaseElement).width();
24741		} else if (window.innerWidth) {
24742			width = window.innerWidth;
24743		} else if (document.documentElement && document.documentElement.clientWidth) {
24744			width = document.documentElement.clientWidth;
24745		} else {
24746			throw 'Can not detect viewport width.';
24747		}
24748
24749		return width;
24750	};
24751
24752	/**
24753	 * Replaces the current content.
24754	 * @public
24755	 * @param {HTMLElement|jQuery|String} content - The new content.
24756	 */
24757	Owl.prototype.replace = function(content) {
24758		this.$stage.empty();
24759		this._items = [];
24760
24761		if (content) {
24762			content = (content instanceof jQuery) ? content : $(content);
24763		}
24764
24765		if (this.settings.nestedItemSelector) {
24766			content = content.find('.' + this.settings.nestedItemSelector);
24767		}
24768
24769		content.filter(function() {
24770			return this.nodeType === 1;
24771		}).each($.proxy(function(index, item) {
24772			item = this.prepare(item, index);
24773			this.$stage.append(item);
24774			this._items.push(item);
24775			this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
24776		}, this));
24777
24778		this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
24779
24780		this.invalidate('items');
24781	};
24782
24783	/**
24784	 * Adds an item.
24785	 * @todo Use `item` instead of `content` for the event arguments.
24786	 * @public
24787	 * @param {HTMLElement|jQuery|String} content - The item content to add.
24788	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
24789	 */
24790	Owl.prototype.add = function(content, position) {
24791		var current = this.relative(this._current);
24792
24793		position = position === undefined ? this._items.length : this.normalize(position, true);
24794		content = content instanceof jQuery ? content : $(content);
24795
24796		this.trigger('add', { content: content, position: position });
24797
24798		content = this.prepare(content, this._items[current].index());
24799
24800		if (this._items.length === 0 || position === this._items.length) {
24801			this._items.length === 0 && this.$stage.append(content);
24802			this._items.length !== 0 && this._items[position - 1].after(content);
24803			this._items.push(content);
24804			this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
24805		} else {
24806			this._items[position].before(content);
24807			this._items.splice(position, 0, content);
24808			this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
24809		}
24810
24811		this._items[current] && this.reset(this._items[current].index());
24812
24813		this.invalidate('items');
24814
24815		this.trigger('added', { content: content, position: position });
24816	};
24817
24818	/**
24819	 * Removes an item by its position.
24820	 * @todo Use `item` instead of `content` for the event arguments.
24821	 * @public
24822	 * @param {Number} position - The relative position of the item to remove.
24823	 */
24824	Owl.prototype.remove = function(position) {
24825		position = this.normalize(position, true);
24826
24827		if (position === undefined) {
24828			return;
24829		}
24830
vendor: 40,482 bytes, lines 24831-26397
24831		this.trigger('remove', { content: this._items[position], position: position });
24832
24833		this._items[position].remove();
24834		this._items.splice(position, 1);
24835		this._mergers.splice(position, 1);
24836
24837		this.invalidate('items');
24838
24839		this.trigger('removed', { content: null, position: position });
24840	};
24841
24842	/**
24843	 * Preloads images with auto width.
24844	 * @todo Replace by a more generic approach
24845	 * @protected
24846	 */
24847	Owl.prototype.preloadAutoWidthImages = function(images) {
24848		images.each($.proxy(function(i, element) {
24849			this.enter('pre-loading');
24850			element = $(element);
24851			$(new Image()).one('load', $.proxy(function(e) {
24852				element.attr('src', e.target.src);
24853				element.css('opacity', 1);
24854				this.leave('pre-loading');
24855				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
24856			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
24857		}, this));
24858	};
24859
24860	/**
24861	 * Destroys the carousel.
24862	 * @public
24863	 */
24864	Owl.prototype.destroy = function() {
24865
24866		this.$element.off('.owl.core');
24867		this.$stage.off('.owl.core');
24868		$(document).off('.owl.core');
24869
24870		if (this.settings.responsive !== false) {
24871			window.clearTimeout(this.resizeTimer);
24872			this.off(window, 'resize', this._handlers.onThrottledResize);
24873		}
24874
24875		for (var i in this._plugins) {
24876			this._plugins[i].destroy();
24877		}
24878
24879		this.$stage.children('.cloned').remove();
24880
24881		this.$stage.unwrap();
24882		this.$stage.children().contents().unwrap();
24883		this.$stage.children().unwrap();
24884
24885		this.$element
24886			.removeClass(this.options.refreshClass)
24887			.removeClass(this.options.loadingClass)
24888			.removeClass(this.options.loadedClass)
24889			.removeClass(this.options.rtlClass)
24890			.removeClass(this.options.dragClass)
24891			.removeClass(this.options.grabClass)
24892			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
24893			.removeData('owl.carousel');
24894	};
24895
24896	/**
24897	 * Operators to calculate right-to-left and left-to-right.
24898	 * @protected
24899	 * @param {Number} [a] - The left side operand.
24900	 * @param {String} [o] - The operator.
24901	 * @param {Number} [b] - The right side operand.
24902	 */
24903	Owl.prototype.op = function(a, o, b) {
24904		var rtl = this.settings.rtl;
24905		switch (o) {
24906			case '<':
24907				return rtl ? a > b : a < b;
24908			case '>':
24909				return rtl ? a < b : a > b;
24910			case '>=':
24911				return rtl ? a <= b : a >= b;
24912			case '<=':
24913				return rtl ? a >= b : a <= b;
24914			default:
24915				break;
24916		}
24917	};
24918
24919	/**
24920	 * Attaches to an internal event.
24921	 * @protected
24922	 * @param {HTMLElement} element - The event source.
24923	 * @param {String} event - The event name.
24924	 * @param {Function} listener - The event handler to attach.
24925	 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
24926	 */
24927	Owl.prototype.on = function(element, event, listener, capture) {
24928		if (element.addEventListener) {
24929			element.addEventListener(event, listener, capture);
24930		} else if (element.attachEvent) {
24931			element.attachEvent('on' + event, listener);
24932		}
24933	};
24934
24935	/**
24936	 * Detaches from an internal event.
24937	 * @protected
24938	 * @param {HTMLElement} element - The event source.
24939	 * @param {String} event - The event name.
24940	 * @param {Function} listener - The attached event handler to detach.
24941	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
24942	 */
24943	Owl.prototype.off = function(element, event, listener, capture) {
24944		if (element.removeEventListener) {
24945			element.removeEventListener(event, listener, capture);
24946		} else if (element.detachEvent) {
24947			element.detachEvent('on' + event, listener);
24948		}
24949	};
24950
24951	/**
24952	 * Triggers a public event.
24953	 * @todo Remove `status`, `relatedTarget` should be used instead.
24954	 * @protected
24955	 * @param {String} name - The event name.
24956	 * @param {*} [data=null] - The event data.
24957	 * @param {String} [namespace=carousel] - The event namespace.
24958	 * @param {String} [state] - The state which is associated with the event.
24959	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
24960	 * @returns {Event} - The event arguments.
24961	 */
24962	Owl.prototype.trigger = function(name, data, namespace, state, enter) {
24963		var status = {
24964			item: { count: this._items.length, index: this.current() }
24965		}, handler = $.camelCase(
24966			$.grep([ 'on', name, namespace ], function(v) { return v })
24967				.join('-').toLowerCase()
24968		), event = $.Event(
24969			[ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
24970			$.extend({ relatedTarget: this }, status, data)
24971		);
24972
24973		if (!this._supress[name]) {
24974			$.each(this._plugins, function(name, plugin) {
24975				if (plugin.onTrigger) {
24976					plugin.onTrigger(event);
24977				}
24978			});
24979
24980			this.register({ type: Owl.Type.Event, name: name });
24981			this.$element.trigger(event);
24982
24983			if (this.settings && typeof this.settings[handler] === 'function') {
24984				this.settings[handler].call(this, event);
24985			}
24986		}
24987
24988		return event;
24989	};
24990
24991	/**
24992	 * Enters a state.
24993	 * @param name - The state name.
24994	 */
24995	Owl.prototype.enter = function(name) {
24996		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
24997			if (this._states.current[name] === undefined) {
24998				this._states.current[name] = 0;
24999			}
25000
25001			this._states.current[name]++;
25002		}, this));
25003	};
25004
25005	/**
25006	 * Leaves a state.
25007	 * @param name - The state name.
25008	 */
25009	Owl.prototype.leave = function(name) {
25010		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
25011			this._states.current[name]--;
25012		}, this));
25013	};
25014
25015	/**
25016	 * Registers an event or state.
25017	 * @public
25018	 * @param {Object} object - The event or state to register.
25019	 */
25020	Owl.prototype.register = function(object) {
25021		if (object.type === Owl.Type.Event) {
25022			if (!$.event.special[object.name]) {
25023				$.event.special[object.name] = {};
25024			}
25025
25026			if (!$.event.special[object.name].owl) {
25027				var _default = $.event.special[object.name]._default;
25028				$.event.special[object.name]._default = function(e) {
25029					if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
25030						return _default.apply(this, arguments);
25031					}
25032					return e.namespace && e.namespace.indexOf('owl') > -1;
25033				};
25034				$.event.special[object.name].owl = true;
25035			}
25036		} else if (object.type === Owl.Type.State) {
25037			if (!this._states.tags[object.name]) {
25038				this._states.tags[object.name] = object.tags;
25039			} else {
25040				this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
25041			}
25042
25043			this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
25044				return $.inArray(tag, this._states.tags[object.name]) === i;
25045			}, this));
25046		}
25047	};
25048
25049	/**
25050	 * Suppresses events.
25051	 * @protected
25052	 * @param {Array.<String>} events - The events to suppress.
25053	 */
25054	Owl.prototype.suppress = function(events) {
25055		$.each(events, $.proxy(function(index, event) {
25056			this._supress[event] = true;
25057		}, this));
25058	};
25059
25060	/**
25061	 * Releases suppressed events.
25062	 * @protected
25063	 * @param {Array.<String>} events - The events to release.
25064	 */
25065	Owl.prototype.release = function(events) {
25066		$.each(events, $.proxy(function(index, event) {
25067			delete this._supress[event];
25068		}, this));
25069	};
25070
25071	/**
25072	 * Gets unified pointer coordinates from event.
25073	 * @todo #261
25074	 * @protected
25075	 * @param {Event} - The `mousedown` or `touchstart` event.
25076	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
25077	 */
25078	Owl.prototype.pointer = function(event) {
25079		var result = { x: null, y: null };
25080
25081		event = event.originalEvent || event || window.event;
25082
25083		event = event.touches && event.touches.length ?
25084			event.touches[0] : event.changedTouches && event.changedTouches.length ?
25085				event.changedTouches[0] : event;
25086
25087		if (event.pageX) {
25088			result.x = event.pageX;
25089			result.y = event.pageY;
25090		} else {
25091			result.x = event.clientX;
25092			result.y = event.clientY;
25093		}
25094
25095		return result;
25096	};
25097
25098	/**
25099	 * Gets the difference of two vectors.
25100	 * @todo #261
25101	 * @protected
25102	 * @param {Object} - The first vector.
25103	 * @param {Object} - The second vector.
25104	 * @returns {Object} - The difference.
25105	 */
25106	Owl.prototype.difference = function(first, second) {
25107		return {
25108			x: first.x - second.x,
25109			y: first.y - second.y
25110		};
25111	};
25112
25113	/**
25114	 * The jQuery Plugin for the Owl Carousel
25115	 * @todo Navigation plugin `next` and `prev`
25116	 * @public
25117	 */
25118	$.fn.owlCarousel = function(option) {
25119		var args = Array.prototype.slice.call(arguments, 1);
25120
25121		return this.each(function() {
25122			var $this = $(this),
25123				data = $this.data('owl.carousel');
25124
25125			if (!data) {
25126				data = new Owl(this, typeof option == 'object' && option);
25127				$this.data('owl.carousel', data);
25128
25129				$.each([
25130					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
25131				], function(i, event) {
25132					data.register({ type: Owl.Type.Event, name: event });
25133					data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
25134						if (e.namespace && e.relatedTarget !== this) {
25135							this.suppress([ event ]);
25136							data[event].apply(this, [].slice.call(arguments, 1));
25137							this.release([ event ]);
25138						}
25139					}, data));
25140				});
25141			}
25142
25143			if (typeof option == 'string' && option.charAt(0) !== '_') {
25144				data[option].apply(data, args);
25145			}
25146		});
25147	};
25148
25149	/**
25150	 * The constructor for the jQuery Plugin
25151	 * @public
25152	 */
25153	$.fn.owlCarousel.Constructor = Owl;
25154
25155})(window.Zepto || window.jQuery, window, document);
25156
25157/**
25158 * AutoRefresh Plugin
25159 * @version 2.0.0-beta.3
25160 * @author Artus Kolanowski
25161 * @license The MIT License (MIT)
25162 */
25163;(function($, window, document, undefined) {
25164
25165	/**
25166	 * Creates the auto refresh plugin.
25167	 * @class The Auto Refresh Plugin
25168	 * @param {Owl} carousel - The Owl Carousel
25169	 */
25170	var AutoRefresh = function(carousel) {
25171		/**
25172		 * Reference to the core.
25173		 * @protected
25174		 * @type {Owl}
25175		 */
25176		this._core = carousel;
25177
25178		/**
25179		 * Refresh interval.
25180		 * @protected
25181		 * @type {number}
25182		 */
25183		this._interval = null;
25184
25185		/**
25186		 * Whether the element is currently visible or not.
25187		 * @protected
25188		 * @type {Boolean}
25189		 */
25190		this._visible = null;
25191
25192		/**
25193		 * All event handlers.
25194		 * @protected
25195		 * @type {Object}
25196		 */
25197		this._handlers = {
25198			'initialized.owl.carousel': $.proxy(function(e) {
25199				if (e.namespace && this._core.settings.autoRefresh) {
25200					this.watch();
25201				}
25202			}, this)
25203		};
25204
25205		// set default options
25206		this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
25207
25208		// register event handlers
25209		this._core.$element.on(this._handlers);
25210	};
25211
25212	/**
25213	 * Default options.
25214	 * @public
25215	 */
25216	AutoRefresh.Defaults = {
25217		autoRefresh: true,
25218		autoRefreshInterval: 500
25219	};
25220
25221	/**
25222	 * Watches the element.
25223	 */
25224	AutoRefresh.prototype.watch = function() {
25225		if (this._interval) {
25226			return;
25227		}
25228
25229		this._visible = this._core.$element.is(':visible');
25230		this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
25231	};
25232
25233	/**
25234	 * Refreshes the element.
25235	 */
25236	AutoRefresh.prototype.refresh = function() {
25237		if (this._core.$element.is(':visible') === this._visible) {
25238			return;
25239		}
25240
25241		this._visible = !this._visible;
25242
25243		this._core.$element.toggleClass('owl-hidden', !this._visible);
25244
25245		this._visible && (this._core.invalidate('width') && this._core.refresh());
25246	};
25247
25248	/**
25249	 * Destroys the plugin.
25250	 */
25251	AutoRefresh.prototype.destroy = function() {
25252		var handler, property;
25253
25254		window.clearInterval(this._interval);
25255
25256		for (handler in this._handlers) {
25257			this._core.$element.off(handler, this._handlers[handler]);
25258		}
25259		for (property in Object.getOwnPropertyNames(this)) {
25260			typeof this[property] != 'function' && (this[property] = null);
25261		}
25262	};
25263
25264	$.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
25265
25266})(window.Zepto || window.jQuery, window, document);
25267
25268/**
25269 * Lazy Plugin
25270 * @version 2.0.0-beta.3
25271 * @author Bartosz Wojciechowski
25272 * @license The MIT License (MIT)
25273 */
25274;(function($, window, document, undefined) {
25275
25276	/**
25277	 * Creates the lazy plugin.
25278	 * @class The Lazy Plugin
25279	 * @param {Owl} carousel - The Owl Carousel
25280	 */
25281	var Lazy = function(carousel) {
25282
25283		/**
25284		 * Reference to the core.
25285		 * @protected
25286		 * @type {Owl}
25287		 */
25288		this._core = carousel;
25289
25290		/**
25291		 * Already loaded items.
25292		 * @protected
25293		 * @type {Array.<jQuery>}
25294		 */
25295		this._loaded = [];
25296
25297		/**
25298		 * Event handlers.
25299		 * @protected
25300		 * @type {Object}
25301		 */
25302		this._handlers = {
25303			'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) {
25304				if (!e.namespace) {
25305					return;
25306				}
25307
25308				if (!this._core.settings || !this._core.settings.lazyLoad) {
25309					return;
25310				}
25311
25312				if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
25313					var settings = this._core.settings,
25314						n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
25315						i = ((settings.center && n * -1) || 0),
25316						position = ((e.property && e.property.value) || this._core.current()) + i,
25317						clones = this._core.clones().length,
25318						load = $.proxy(function(i, v) { this.load(v) }, this);
25319
25320					while (i++ < n) {
25321						this.load(clones / 2 + this._core.relative(position));
25322						clones && $.each(this._core.clones(this._core.relative(position)), load);
25323						position++;
25324					}
25325				}
25326			}, this)
25327		};
25328
25329		// set the default options
25330		this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
25331
25332		// register event handler
25333		this._core.$element.on(this._handlers);
25334	}
25335
25336	/**
25337	 * Default options.
25338	 * @public
25339	 */
25340	Lazy.Defaults = {
25341		lazyLoad: false
25342	}
25343
25344	/**
25345	 * Loads all resources of an item at the specified position.
25346	 * @param {Number} position - The absolute position of the item.
25347	 * @protected
25348	 */
25349	Lazy.prototype.load = function(position) {
25350		var $item = this._core.$stage.children().eq(position),
25351			$elements = $item && $item.find('.owl-lazy');
25352
25353		if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
25354			return;
25355		}
25356
25357		$elements.each($.proxy(function(index, element) {
25358			var $element = $(element), image,
25359				url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');
25360
25361			this._core.trigger('load', { element: $element, url: url }, 'lazy');
25362
25363			if ($element.is('img')) {
25364				$element.one('load.owl.lazy', $.proxy(function() {
25365					$element.css('opacity', 1);
25366					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
25367				}, this)).attr('src', url);
25368			} else {
25369				image = new Image();
25370				image.onload = $.proxy(function() {
25371					$element.css({
25372						'background-image': 'url(' + url + ')',
25373						'opacity': '1'
25374					});
25375					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
25376				}, this);
25377				image.src = url;
25378			}
25379		}, this));
25380
25381		this._loaded.push($item.get(0));
25382	}
25383
25384	/**
25385	 * Destroys the plugin.
25386	 * @public
25387	 */
25388	Lazy.prototype.destroy = function() {
25389		var handler, property;
25390
25391		for (handler in this.handlers) {
25392			this._core.$element.off(handler, this.handlers[handler]);
25393		}
25394		for (property in Object.getOwnPropertyNames(this)) {
25395			typeof this[property] != 'function' && (this[property] = null);
25396		}
25397	};
25398
25399	$.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
25400
25401})(window.Zepto || window.jQuery, window, document);
25402
25403/**
25404 * AutoHeight Plugin
25405 * @version 2.0.0-beta.3
25406 * @author Bartosz Wojciechowski
25407 * @license The MIT License (MIT)
25408 */
25409;(function($, window, document, undefined) {
25410
25411	/**
25412	 * Creates the auto height plugin.
25413	 * @class The Auto Height Plugin
25414	 * @param {Owl} carousel - The Owl Carousel
25415	 */
25416	var AutoHeight = function(carousel) {
25417		/**
25418		 * Reference to the core.
25419		 * @protected
25420		 * @type {Owl}
25421		 */
25422		this._core = carousel;
25423
25424		/**
25425		 * All event handlers.
25426		 * @protected
25427		 * @type {Object}
25428		 */
25429		this._handlers = {
25430			'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {
25431				if (e.namespace && this._core.settings.autoHeight) {
25432					this.update();
25433				}
25434			}, this),
25435			'changed.owl.carousel': $.proxy(function(e) {
25436				if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){
25437					this.update();
25438				}
25439			}, this),
25440			'loaded.owl.lazy': $.proxy(function(e) {
25441				if (e.namespace && this._core.settings.autoHeight
25442					&& e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
25443					this.update();
25444				}
25445			}, this)
25446		};
25447
25448		// set default options
25449		this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
25450
25451		// register event handlers
25452		this._core.$element.on(this._handlers);
25453	};
25454
25455	/**
25456	 * Default options.
25457	 * @public
25458	 */
25459	AutoHeight.Defaults = {
25460		autoHeight: false,
25461		autoHeightClass: 'owl-height'
25462	};
25463
25464	/**
25465	 * Updates the view.
25466	 */
25467	AutoHeight.prototype.update = function() {
25468		var start = this._core._current,
25469			end = start + this._core.settings.items,
25470			visible = this._core.$stage.children().toArray().slice(start, end);
25471			heights = [],
25472			maxheight = 0;
25473
25474		$.each(visible, function(index, item) {
25475			heights.push($(item).height());
25476		});
25477
25478		maxheight = Math.max.apply(null, heights);
25479
25480		this._core.$stage.parent()
25481			.height(maxheight)
25482			.addClass(this._core.settings.autoHeightClass);
25483	};
25484
25485	AutoHeight.prototype.destroy = function() {
25486		var handler, property;
25487
25488		for (handler in this._handlers) {
25489			this._core.$element.off(handler, this._handlers[handler]);
25490		}
25491		for (property in Object.getOwnPropertyNames(this)) {
25492			typeof this[property] != 'function' && (this[property] = null);
25493		}
25494	};
25495
25496	$.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
25497
25498})(window.Zepto || window.jQuery, window, document);
25499
25500/**
25501 * Video Plugin
25502 * @version 2.0.0-beta.3
25503 * @author Bartosz Wojciechowski
25504 * @license The MIT License (MIT)
25505 */
25506;(function($, window, document, undefined) {
25507
25508	/**
25509	 * Creates the video plugin.
25510	 * @class The Video Plugin
25511	 * @param {Owl} carousel - The Owl Carousel
25512	 */
25513	var Video = function(carousel) {
25514		/**
25515		 * Reference to the core.
25516		 * @protected
25517		 * @type {Owl}
25518		 */
25519		this._core = carousel;
25520
25521		/**
25522		 * Cache all video URLs.
25523		 * @protected
25524		 * @type {Object}
25525		 */
25526		this._videos = {};
25527
25528		/**
25529		 * Current playing item.
25530		 * @protected
25531		 * @type {jQuery}
25532		 */
25533		this._playing = null;
25534
25535		/**
25536		 * All event handlers.
25537		 * @todo The cloned content removale is too late
25538		 * @protected
25539		 * @type {Object}
25540		 */
25541		this._handlers = {
25542			'initialized.owl.carousel': $.proxy(function(e) {
25543				if (e.namespace) {
25544					this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });
25545				}
25546			}, this),
25547			'resize.owl.carousel': $.proxy(function(e) {
25548				if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
25549					e.preventDefault();
25550				}
25551			}, this),
25552			'refreshed.owl.carousel': $.proxy(function(e) {
25553				if (e.namespace && this._core.is('resizing')) {
25554					this._core.$stage.find('.cloned .owl-video-frame').remove();
25555				}
25556			}, this),
25557			'changed.owl.carousel': $.proxy(function(e) {
25558				if (e.namespace && e.property.name === 'position' && this._playing) {
25559					this.stop();
25560				}
25561			}, this),
25562			'prepared.owl.carousel': $.proxy(function(e) {
25563				if (!e.namespace) {
25564					return;
25565				}
25566
25567				var $element = $(e.content).find('.owl-video');
25568
25569				if ($element.length) {
25570					$element.css('display', 'none');
25571					this.fetch($element, $(e.content));
25572				}
25573			}, this)
25574		};
25575
25576		// set default options
25577		this._core.options = $.extend({}, Video.Defaults, this._core.options);
25578
25579		// register event handlers
25580		this._core.$element.on(this._handlers);
25581
25582		this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
25583			this.play(e);
25584		}, this));
25585	};
25586
25587	/**
25588	 * Default options.
25589	 * @public
25590	 */
25591	Video.Defaults = {
25592		video: false,
25593		videoHeight: false,
25594		videoWidth: false
25595	};
25596
25597	/**
25598	 * Gets the video ID and the type (YouTube/Vimeo only).
25599	 * @protected
25600	 * @param {jQuery} target - The target containing the video data.
25601	 * @param {jQuery} item - The item containing the video.
25602	 */
25603	Video.prototype.fetch = function(target, item) {
25604		var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube',
25605			id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'),
25606			width = target.attr('data-width') || this._core.settings.videoWidth,
25607			height = target.attr('data-height') || this._core.settings.videoHeight,
25608			url = target.attr('href');
25609
25610		if (url) {
25611			id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
25612
25613			if (id[3].indexOf('youtu') > -1) {
25614				type = 'youtube';
25615			} else if (id[3].indexOf('vimeo') > -1) {
25616				type = 'vimeo';
25617			} else {
25618				throw new Error('Video URL not supported.');
25619			}
25620			id = id[6];
25621		} else {
25622			throw new Error('Missing video URL.');
25623		}
25624
25625		this._videos[url] = {
25626			type: type,
25627			id: id,
25628			width: width,
25629			height: height
25630		};
25631
25632		item.attr('data-video', url);
25633
25634		this.thumbnail(target, this._videos[url]);
25635	};
25636
25637	/**
25638	 * Creates video thumbnail.
25639	 * @protected
25640	 * @param {jQuery} target - The target containing the video data.
25641	 * @param {Object} info - The video info object.
25642	 * @see `fetch`
25643	 */
25644	Video.prototype.thumbnail = function(target, video) {
25645		var tnLink,
25646			icon,
25647			path,
25648			dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
25649			customTn = target.find('img'),
25650			srcType = 'src',
25651			lazyClass = '',
25652			settings = this._core.settings,
25653			create = function(path) {
25654				icon = '<div class="owl-video-play-icon"></div>';
25655
25656				if (settings.lazyLoad) {
25657					tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';
25658				} else {
25659					tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';
25660				}
25661				target.after(tnLink);
25662				target.after(icon);
25663			};
25664
25665		// wrap video content into owl-video-wrapper div
25666		target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');
25667
25668		if (this._core.settings.lazyLoad) {
25669			srcType = 'data-src';
25670			lazyClass = 'owl-lazy';
25671		}
25672
25673		// custom thumbnail
25674		if (customTn.length) {
25675			create(customTn.attr(srcType));
25676			customTn.remove();
25677			return false;
25678		}
25679
25680		if (video.type === 'youtube') {
25681			path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
25682			create(path);
25683		} else if (video.type === 'vimeo') {
25684			$.ajax({
25685				type: 'GET',
25686				url: '//vimeo.com/api/v2/video/' + video.id + '.json',
25687				jsonp: 'callback',
25688				dataType: 'jsonp',
25689				success: function(data) {
25690					path = data[0].thumbnail_large;
25691					create(path);
25692				}
25693			});
25694		}
25695	};
25696
25697	/**
25698	 * Stops the current video.
25699	 * @public
25700	 */
25701	Video.prototype.stop = function() {
25702		this._core.trigger('stop', null, 'video');
25703		this._playing.find('.owl-video-frame').remove();
25704		this._playing.removeClass('owl-video-playing');
25705		this._playing = null;
25706		this._core.leave('playing');
25707		this._core.trigger('stopped', null, 'video');
25708	};
25709
25710	/**
25711	 * Starts the current video.
25712	 * @public
25713	 * @param {Event} event - The event arguments.
25714	 */
25715	Video.prototype.play = function(event) {
25716		var target = $(event.target),
25717			item = target.closest('.' + this._core.settings.itemClass),
25718			video = this._videos[item.attr('data-video')],
25719			width = video.width || '100%',
25720			height = video.height || this._core.$stage.height(),
25721			html;
25722
25723		if (this._playing) {
25724			return;
25725		}
25726
25727		this._core.enter('playing');
25728		this._core.trigger('play', null, 'video');
25729
25730		item = this._core.items(this._core.relative(item.index()));
25731
25732		this._core.reset(item.index());
25733
25734		if (video.type === 'youtube') {
25735			html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' +
25736				video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';
25737		} else if (video.type === 'vimeo') {
25738			html = '<iframe src="//player.vimeo.com/video/' + video.id +
25739				'?autoplay=1" width="' + width + '" height="' + height +
25740				'" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
25741		}
25742
25743		$('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video'));
25744
25745		this._playing = item.addClass('owl-video-playing');
25746	};
25747
25748	/**
25749	 * Checks whether an video is currently in full screen mode or not.
25750	 * @todo Bad style because looks like a readonly method but changes members.
25751	 * @protected
25752	 * @returns {Boolean}
25753	 */
25754	Video.prototype.isInFullScreen = function() {
25755		var element = document.fullscreenElement || document.mozFullScreenElement ||
25756				document.webkitFullscreenElement;
25757
25758		return element && $(element).parent().hasClass('owl-video-frame');
25759	};
25760
25761	/**
25762	 * Destroys the plugin.
25763	 */
25764	Video.prototype.destroy = function() {
25765		var handler, property;
25766
25767		this._core.$element.off('click.owl.video');
25768
25769		for (handler in this._handlers) {
25770			this._core.$element.off(handler, this._handlers[handler]);
25771		}
25772		for (property in Object.getOwnPropertyNames(this)) {
25773			typeof this[property] != 'function' && (this[property] = null);
25774		}
25775	};
25776
25777	$.fn.owlCarousel.Constructor.Plugins.Video = Video;
25778
25779})(window.Zepto || window.jQuery, window, document);
25780
25781/**
25782 * Animate Plugin
25783 * @version 2.0.0-beta.3
25784 * @author Bartosz Wojciechowski
25785 * @license The MIT License (MIT)
25786 */
25787;(function($, window, document, undefined) {
25788
25789	/**
25790	 * Creates the animate plugin.
25791	 * @class The Navigation Plugin
25792	 * @param {Owl} scope - The Owl Carousel
25793	 */
25794	var Animate = function(scope) {
25795		this.core = scope;
25796		this.core.options = $.extend({}, Animate.Defaults, this.core.options);
25797		this.swapping = true;
25798		this.previous = undefined;
25799		this.next = undefined;
25800
25801		this.handlers = {
25802			'change.owl.carousel': $.proxy(function(e) {
25803				if (e.namespace && e.property.name == 'position') {
25804					this.previous = this.core.current();
25805					this.next = e.property.value;
25806				}
25807			}, this),
25808			'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
25809				if (e.namespace) {
25810					this.swapping = e.type == 'translated';
25811				}
25812			}, this),
25813			'translate.owl.carousel': $.proxy(function(e) {
25814				if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
25815					this.swap();
25816				}
25817			}, this)
25818		};
25819
25820		this.core.$element.on(this.handlers);
25821	};
25822
25823	/**
25824	 * Default options.
25825	 * @public
25826	 */
25827	Animate.Defaults = {
25828		animateOut: false,
25829		animateIn: false
25830	};
25831
25832	/**
25833	 * Toggles the animation classes whenever an translations starts.
25834	 * @protected
25835	 * @returns {Boolean|undefined}
25836	 */
25837	Animate.prototype.swap = function() {
25838
25839		if (this.core.settings.items !== 1) {
25840			return;
25841		}
25842
25843		if (!$.support.animation || !$.support.transition) {
25844			return;
25845		}
25846
25847		this.core.speed(0);
25848
25849		var left,
25850			clear = $.proxy(this.clear, this),
25851			previous = this.core.$stage.children().eq(this.previous),
25852			next = this.core.$stage.children().eq(this.next),
25853			incoming = this.core.settings.animateIn,
25854			outgoing = this.core.settings.animateOut;
25855
25856		if (this.core.current() === this.previous) {
25857			return;
25858		}
25859
25860		if (outgoing) {
25861			left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
25862			previous.css( { 'left': left + 'px' } )
25863				.addClass('animated owl-animated-out')
25864				.addClass(outgoing)
25865				.on($.support.animation.end, clear);
25866		}
25867
25868		if (incoming) {
25869			next.addClass('animated owl-animated-in')
25870				.addClass(incoming)
25871				.on($.support.animation.end, clear);
25872		}
25873	};
25874
25875	Animate.prototype.clear = function(e) {
25876		if ($(e.target).hasClass('animated')) {
25877			$(e.target).css( { 'left': '' } )
25878				.removeClass('animated owl-animated-out owl-animated-in')
25879				.removeClass(this.core.settings.animateIn)
25880				.removeClass(this.core.settings.animateOut);
25881			this.core.onTransitionEnd();
25882		}
25883	};
25884
25885	/**
25886	 * Destroys the plugin.
25887	 * @public
25888	 */
25889	Animate.prototype.destroy = function() {
25890		var handler, property;
25891
25892		for (handler in this.handlers) {
25893			this.core.$element.off(handler, this.handlers[handler]);
25894		}
25895		for (property in Object.getOwnPropertyNames(this)) {
25896			typeof this[property] != 'function' && (this[property] = null);
25897		}
25898	};
25899
25900	$.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
25901
25902})(window.Zepto || window.jQuery, window, document);
25903
25904/**
25905 * Autoplay Plugin
25906 * @version 2.0.0-beta.3
25907 * @author Bartosz Wojciechowski
25908 * @author Artus Kolanowski
25909 * @license The MIT License (MIT)
25910 */
25911;(function($, window, document, undefined) {
25912
25913	/**
25914	 * Creates the autoplay plugin.
25915	 * @class The Autoplay Plugin
25916	 * @param {Owl} scope - The Owl Carousel
25917	 */
25918	var Autoplay = function(carousel) {
25919		/**
25920		 * Reference to the core.
25921		 * @protected
25922		 * @type {Owl}
25923		 */
25924		this._core = carousel;
25925
25926		/**
25927		 * The autoplay interval.
25928		 * @type {Number}
25929		 */
25930		this._interval = null;
25931
25932		/**
25933		 * Indicates whenever the autoplay is paused.
25934		 * @type {Boolean}
25935		 */
25936		this._paused = false;
25937
25938		/**
25939		 * All event handlers.
25940		 * @protected
25941		 * @type {Object}
25942		 */
25943		this._handlers = {
25944			'changed.owl.carousel': $.proxy(function(e) {
25945				if (e.namespace && e.property.name === 'settings') {
25946					if (this._core.settings.autoplay) {
25947						this.play();
25948					} else {
25949						this.stop();
25950					}
25951				}
25952			}, this),
25953			'initialized.owl.carousel': $.proxy(function(e) {
25954				if (e.namespace && this._core.settings.autoplay) {
25955					this.play();
25956				}
25957			}, this),
25958			'play.owl.autoplay': $.proxy(function(e, t, s) {
25959				if (e.namespace) {
25960					this.play(t, s);
25961				}
25962			}, this),
25963			'stop.owl.autoplay': $.proxy(function(e) {
25964				if (e.namespace) {
25965					this.stop();
25966				}
25967			}, this),
25968			'mouseover.owl.autoplay': $.proxy(function() {
25969				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
25970					this.pause();
25971				}
25972			}, this),
25973			'mouseleave.owl.autoplay': $.proxy(function() {
25974				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
25975					this.play();
25976				}
25977			}, this)
25978		};
25979
25980		// register event handlers
25981		this._core.$element.on(this._handlers);
25982
25983		// set default options
25984		this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
25985	};
25986
25987	/**
25988	 * Default options.
25989	 * @public
25990	 */
25991	Autoplay.Defaults = {
25992		autoplay: false,
25993		autoplayTimeout: 5000,
25994		autoplayHoverPause: false,
25995		autoplaySpeed: false
25996	};
25997
25998	/**
25999	 * Starts the autoplay.
26000	 * @public
26001	 * @param {Number} [timeout] - The interval before the next animation starts.
26002	 * @param {Number} [speed] - The animation speed for the animations.
26003	 */
26004	Autoplay.prototype.play = function(timeout, speed) {
26005		this._paused = false;
26006
26007		if (this._core.is('rotating')) {
26008			return;
26009		}
26010
26011		this._core.enter('rotating');
26012
26013		this._interval = window.setInterval($.proxy(function() {
26014			if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) {
26015				return;
26016			}
26017			this._core.next(speed || this._core.settings.autoplaySpeed);
26018		}, this), timeout || this._core.settings.autoplayTimeout);
26019	};
26020
26021	/**
26022	 * Stops the autoplay.
26023	 * @public
26024	 */
26025	Autoplay.prototype.stop = function() {
26026		if (!this._core.is('rotating')) {
26027			return;
26028		}
26029
26030		window.clearInterval(this._interval);
26031		this._core.leave('rotating');
26032	};
26033
26034	/**
26035	 * Stops the autoplay.
26036	 * @public
26037	 */
26038	Autoplay.prototype.pause = function() {
26039		if (!this._core.is('rotating')) {
26040			return;
26041		}
26042
26043		this._paused = true;
26044	};
26045
26046	/**
26047	 * Destroys the plugin.
26048	 */
26049	Autoplay.prototype.destroy = function() {
26050		var handler, property;
26051
26052		this.stop();
26053
26054		for (handler in this._handlers) {
26055			this._core.$element.off(handler, this._handlers[handler]);
26056		}
26057		for (property in Object.getOwnPropertyNames(this)) {
26058			typeof this[property] != 'function' && (this[property] = null);
26059		}
26060	};
26061
26062	$.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
26063
26064})(window.Zepto || window.jQuery, window, document);
26065
26066/**
26067 * Navigation Plugin
26068 * @version 2.0.0-beta.3
26069 * @author Artus Kolanowski
26070 * @license The MIT License (MIT)
26071 */
26072;(function($, window, document, undefined) {
26073	'use strict';
26074
26075	/**
26076	 * Creates the navigation plugin.
26077	 * @class The Navigation Plugin
26078	 * @param {Owl} carousel - The Owl Carousel.
26079	 */
26080	var Navigation = function(carousel) {
26081		/**
26082		 * Reference to the core.
26083		 * @protected
26084		 * @type {Owl}
26085		 */
26086		this._core = carousel;
26087
26088		/**
26089		 * Indicates whether the plugin is initialized or not.
26090		 * @protected
26091		 * @type {Boolean}
26092		 */
26093		this._initialized = false;
26094
26095		/**
26096		 * The current paging indexes.
26097		 * @protected
26098		 * @type {Array}
26099		 */
26100		this._pages = [];
26101
26102		/**
26103		 * All DOM elements of the user interface.
26104		 * @protected
26105		 * @type {Object}
26106		 */
26107		this._controls = {};
26108
26109		/**
26110		 * Markup for an indicator.
26111		 * @protected
26112		 * @type {Array.<String>}
26113		 */
26114		this._templates = [];
26115
26116		/**
26117		 * The carousel element.
26118		 * @type {jQuery}
26119		 */
26120		this.$element = this._core.$element;
26121
26122		/**
26123		 * Overridden methods of the carousel.
26124		 * @protected
26125		 * @type {Object}
26126		 */
26127		this._overrides = {
26128			next: this._core.next,
26129			prev: this._core.prev,
26130			to: this._core.to
26131		};
26132
26133		/**
26134		 * All event handlers.
26135		 * @protected
26136		 * @type {Object}
26137		 */
26138		this._handlers = {
26139			'prepared.owl.carousel': $.proxy(function(e) {
26140				if (e.namespace && this._core.settings.dotsData) {
26141					this._templates.push('<div class="' + this._core.settings.dotClass + '">' +
26142						$(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>');
26143				}
26144			}, this),
26145			'added.owl.carousel': $.proxy(function(e) {
26146				if (e.namespace && this._core.settings.dotsData) {
26147					this._templates.splice(e.position, 0, this._templates.pop());
26148				}
26149			}, this),
26150			'remove.owl.carousel': $.proxy(function(e) {
26151				if (e.namespace && this._core.settings.dotsData) {
26152					this._templates.splice(e.position, 1);
26153				}
26154			}, this),
26155			'changed.owl.carousel': $.proxy(function(e) {
26156				if (e.namespace && e.property.name == 'position') {
26157					this.draw();
26158				}
26159			}, this),
26160			'initialized.owl.carousel': $.proxy(function(e) {
26161				if (e.namespace && !this._initialized) {
26162					this._core.trigger('initialize', null, 'navigation');
26163					this.initialize();
26164					this.update();
26165					this.draw();
26166					this._initialized = true;
26167					this._core.trigger('initialized', null, 'navigation');
26168				}
26169			}, this),
26170			'refreshed.owl.carousel': $.proxy(function(e) {
26171				if (e.namespace && this._initialized) {
26172					this._core.trigger('refresh', null, 'navigation');
26173					this.update();
26174					this.draw();
26175					this._core.trigger('refreshed', null, 'navigation');
26176				}
26177			}, this)
26178		};
26179
26180		// set default options
26181		this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
26182
26183		// register event handlers
26184		this.$element.on(this._handlers);
26185	};
26186
26187	/**
26188	 * Default options.
26189	 * @public
26190	 * @todo Rename `slideBy` to `navBy`
26191	 */
26192	Navigation.Defaults = {
26193		nav: false,
26194		navText: [ 'prev', 'next' ],
26195		navSpeed: false,
26196		navElement: 'button type="button" role="presentation"',
26197		navContainer: false,
26198		navContainerClass: 'owl-nav',
26199		navClass: [ 'owl-prev', 'owl-next' ],
26200		slideBy: 1,
26201		dotClass: 'owl-dot',
26202		dotsClass: 'owl-dots',
26203		dots: true,
26204		dotsEach: false,
26205		dotsData: false,
26206		dotsSpeed: false,
26207		dotsContainer: false
26208	};
26209
26210	/**
26211	 * Initializes the layout of the plugin and extends the carousel.
26212	 * @protected
26213	 */
26214	Navigation.prototype.initialize = function() {
26215		var override,
26216			settings = this._core.settings;
26217
26218		// create DOM structure for relative navigation
26219		this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
26220			: $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');
26221
26222		this._controls.$previous = $('<' + settings.navElement[0] + '>')
26223			.addClass(settings.navClass[0])
26224			.html(settings.navText[0])
26225			.prependTo(this._controls.$relative)
26226			.on('click', $.proxy(function(e) {
26227				this.prev(settings.navSpeed);
26228			}, this));
26229		this._controls.$next = $('<' + settings.navElement[1] + '>')
26230			.addClass(settings.navClass[1])
26231			.html(settings.navText[1])
26232			.appendTo(this._controls.$relative)
26233			.on('click', $.proxy(function(e) {
26234				this.next(settings.navSpeed);
26235			}, this));
26236
26237		// create DOM structure for absolute navigation
26238		if (!settings.dotsData) {
26239			this._templates = [ $('<button role="button">')
26240				.addClass(settings.dotClass)
26241				.append($('<span>'))
26242				.prop('outerHTML') ];
26243		}
26244
26245		this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
26246			: $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');
26247
26248		this._controls.$absolute.on('click', 'div, button', $.proxy(function(e) {
26249			var index = $(e.target).parent().is(this._controls.$absolute)
26250				? $(e.target).index() : $(e.target).parent().index();
26251
26252			e.preventDefault();
26253
26254			this.to(index, settings.dotsSpeed);
26255		}, this));
26256
26257		// override public methods of the carousel
26258		for (override in this._overrides) {
26259			this._core[override] = $.proxy(this[override], this);
26260		}
26261	};
26262
26263	/**
26264	 * Destroys the plugin.
26265	 * @protected
26266	 */
26267	Navigation.prototype.destroy = function() {
26268		var handler, control, property, override;
26269
26270		for (handler in this._handlers) {
26271			this.$element.off(handler, this._handlers[handler]);
26272		}
26273		for (control in this._controls) {
26274			this._controls[control].remove();
26275		}
26276		for (override in this.overides) {
26277			this._core[override] = this._overrides[override];
26278		}
26279		for (property in Object.getOwnPropertyNames(this)) {
26280			typeof this[property] != 'function' && (this[property] = null);
26281		}
26282	};
26283
26284	/**
26285	 * Updates the internal state.
26286	 * @protected
26287	 */
26288	Navigation.prototype.update = function() {
26289		var i, j, k,
26290			lower = this._core.clones().length / 2,
26291			upper = lower + this._core.items().length,
26292			maximum = this._core.maximum(true),
26293			settings = this._core.settings,
26294			size = settings.center || settings.autoWidth || settings.dotsData
26295				? 1 : settings.dotsEach || settings.items;
26296
26297		if (settings.slideBy !== 'page') {
26298			settings.slideBy = Math.min(settings.slideBy, settings.items);
26299		}
26300
26301		if (settings.dots || settings.slideBy == 'page') {
26302			this._pages = [];
26303
26304			for (i = lower, j = 0, k = 0; i < upper; i++) {
26305				if (j >= size || j === 0) {
26306					this._pages.push({
26307						start: Math.min(maximum, i - lower),
26308						end: i - lower + size - 1
26309					});
26310					if (Math.min(maximum, i - lower) === maximum) {
26311						break;
26312					}
26313					j = 0, ++k;
26314				}
26315				j += this._core.mergers(this._core.relative(i));
26316			}
26317		}
26318	};
26319
26320	/**
26321	 * Draws the user interface.
26322	 * @todo The option `dotsData` wont work.
26323	 * @protected
26324	 */
26325	Navigation.prototype.draw = function() {
26326		var difference,
26327			settings = this._core.settings,
26328			disabled = this._core.items().length <= settings.items,
26329			index = this._core.relative(this._core.current()),
26330			loop = settings.loop || settings.rewind;
26331
26332		this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);
26333
26334		if (settings.nav) {
26335			this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
26336			this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
26337		}
26338
26339		this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);
26340
26341		if (settings.dots) {
26342			difference = this._pages.length - this._controls.$absolute.children().length;
26343
26344			if (settings.dotsData && difference !== 0) {
26345				this._controls.$absolute.html(this._templates.join(''));
26346			} else if (difference > 0) {
26347				this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
26348			} else if (difference < 0) {
26349				this._controls.$absolute.children().slice(difference).remove();
26350			}
26351
26352			this._controls.$absolute.find('.active').removeClass('active');
26353			this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
26354		}
26355	};
26356
26357	/**
26358	 * Extends event data.
26359	 * @protected
26360	 * @param {Event} event - The event object which gets thrown.
26361	 */
26362	Navigation.prototype.onTrigger = function(event) {
26363		var settings = this._core.settings;
26364
26365		event.page = {
26366			index: $.inArray(this.current(), this._pages),
26367			count: this._pages.length,
26368			size: settings && (settings.center || settings.autoWidth || settings.dotsData
26369				? 1 : settings.dotsEach || settings.items)
26370		};
26371	};
26372
26373	/**
26374	 * Gets the current page position of the carousel.
26375	 * @protected
26376	 * @returns {Number}
26377	 */
26378	Navigation.prototype.current = function() {
26379		var current = this._core.relative(this._core.current());
26380		return $.grep(this._pages, $.proxy(function(page, index) {
26381			return page.start <= current && page.end >= current;
26382		}, this)).pop();
26383	};
26384
26385	/**
26386	 * Gets the current succesor/predecessor position.
26387	 * @protected
26388	 * @returns {Number}
26389	 */
26390	Navigation.prototype.getPosition = function(successor) {
26391		var position, length,
26392			settings = this._core.settings;
26393
26394		if (settings.slideBy == 'page') {
26395			position = $.inArray(this.current(), this._pages);
26396			length = this._pages.length;
26397			successor ? ++position : --position;
vendor: 5,674 bytes, lines 26398-26622
26398			position = this._pages[((position % length) + length) % length].start;
26399		} else {
26400			position = this._core.relative(this._core.current());
26401			length = this._core.items().length;
26402			successor ? position += settings.slideBy : position -= settings.slideBy;
26403		}
26404
26405		return position;
26406	};
26407
26408	/**
26409	 * Slides to the next item or page.
26410	 * @public
26411	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
26412	 */
26413	Navigation.prototype.next = function(speed) {
26414		$.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
26415	};
26416
26417	/**
26418	 * Slides to the previous item or page.
26419	 * @public
26420	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
26421	 */
26422	Navigation.prototype.prev = function(speed) {
26423		$.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
26424	};
26425
26426	/**
26427	 * Slides to the specified item or page.
26428	 * @public
26429	 * @param {Number} position - The position of the item or page.
26430	 * @param {Number} [speed] - The time in milliseconds for the transition.
26431	 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
26432	 */
26433	Navigation.prototype.to = function(position, speed, standard) {
26434		var length;
26435
26436		if (!standard) {
26437			length = this._pages.length;
26438			$.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
26439		} else {
26440			$.proxy(this._overrides.to, this._core)(position, speed);
26441		}
26442	};
26443
26444	$.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
26445
26446})(window.Zepto || window.jQuery, window, document);
26447
26448/**
26449 * Hash Plugin
26450 * @version 2.0.0-beta.3
26451 * @author Artus Kolanowski
26452 * @license The MIT License (MIT)
26453 */
26454;(function($, window, document, undefined) {
26455	'use strict';
26456
26457	/**
26458	 * Creates the hash plugin.
26459	 * @class The Hash Plugin
26460	 * @param {Owl} carousel - The Owl Carousel
26461	 */
26462	var Hash = function(carousel) {
26463		/**
26464		 * Reference to the core.
26465		 * @protected
26466		 * @type {Owl}
26467		 */
26468		this._core = carousel;
26469
26470		/**
26471		 * Hash index for the items.
26472		 * @protected
26473		 * @type {Object}
26474		 */
26475		this._hashes = {};
26476
26477		/**
26478		 * The carousel element.
26479		 * @type {jQuery}
26480		 */
26481		this.$element = this._core.$element;
26482
26483		/**
26484		 * All event handlers.
26485		 * @protected
26486		 * @type {Object}
26487		 */
26488		this._handlers = {
26489			'initialized.owl.carousel': $.proxy(function(e) {
26490				if (e.namespace && this._core.settings.startPosition === 'URLHash') {
26491					$(window).trigger('hashchange.owl.navigation');
26492				}
26493			}, this),
26494			'prepared.owl.carousel': $.proxy(function(e) {
26495				if (e.namespace) {
26496					var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');
26497
26498					if (!hash) {
26499						return;
26500					}
26501
26502					this._hashes[hash] = e.content;
26503				}
26504			}, this),
26505			'changed.owl.carousel': $.proxy(function(e) {
26506				if (e.namespace && e.property.name === 'position') {
26507					var current = this._core.items(this._core.relative(this._core.current())),
26508						hash = $.map(this._hashes, function(item, hash) {
26509							return item === current ? hash : null;
26510						}).join();
26511
26512					if (!hash || window.location.hash.slice(1) === hash) {
26513						return;
26514					}
26515
26516					window.location.hash = hash;
26517				}
26518			}, this)
26519		};
26520
26521		// set default options
26522		this._core.options = $.extend({}, Hash.Defaults, this._core.options);
26523
26524		// register the event handlers
26525		this.$element.on(this._handlers);
26526
26527		// register event listener for hash navigation
26528		/*$(window).on('hashchange.owl.navigation', $.proxy(function(e) {
26529			var hash = window.location.hash.substring(1),
26530				items = this._core.$stage.children(),
26531				position = this._hashes[hash] && items.index(this._hashes[hash]);
26532
26533			if (position === undefined || position === this._core.current()) {
26534				return;
26535			}
26536
26537			this._core.to(this._core.relative(position), false, true);
26538		}, this));*/
26539	};
26540
26541	/**
26542	 * Default options.
26543	 * @public
26544	 */
26545	Hash.Defaults = {
26546		URLhashListener: false
26547	};
26548
26549	/**
26550	 * Destroys the plugin.
26551	 * @public
26552	 */
26553	Hash.prototype.destroy = function() {
26554		var handler, property;
26555
26556		$(window).off('hashchange.owl.navigation');
26557
26558		for (handler in this._handlers) {
26559			this._core.$element.off(handler, this._handlers[handler]);
26560		}
26561		for (property in Object.getOwnPropertyNames(this)) {
26562			typeof this[property] != 'function' && (this[property] = null);
26563		}
26564	};
26565
26566	$.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
26567
26568})(window.Zepto || window.jQuery, window, document);
26569
26570/**
26571 * Support Plugin
26572 *
26573 * @version 2.0.0-beta.3
26574 * @author Vivid Planet Software GmbH
26575 * @author Artus Kolanowski
26576 * @license The MIT License (MIT)
26577 */
26578;(function($, window, document, undefined) {
26579
26580	var style = $('<support>').get(0).style,
26581		prefixes = 'Webkit Moz O ms'.split(' '),
26582		events = {
26583			transition: {
26584				end: {
26585					WebkitTransition: 'webkitTransitionEnd',
26586					MozTransition: 'transitionend',
26587					OTransition: 'oTransitionEnd',
26588					transition: 'transitionend'
26589				}
26590			},
26591			animation: {
26592				end: {
26593					WebkitAnimation: 'webkitAnimationEnd',
26594					MozAnimation: 'animationend',
26595					OAnimation: 'oAnimationEnd',
26596					animation: 'animationend'
26597				}
26598			}
26599		},
26600		tests = {
26601			csstransforms: function() {
26602				return !!test('transform');
26603			},
26604			csstransforms3d: function() {
26605				return !!test('perspective');
26606			},
26607			csstransitions: function() {
26608				return !!test('transition');
26609			},
26610			cssanimations: function() {
26611				return !!test('animation');
26612			}
26613		};
26614
26615	function test(property, prefixed) {
26616		var result = false,
26617			upper = property.charAt(0).toUpperCase() + property.slice(1);
26618
26619		$.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {
26620			if (style[property] !== undefined) {
26621				result = prefixed ? property : true;
26622				return false;
26623			}
26624		});
26625
26626		return result;
26627	}
26628
26629	function prefixed(property) {
26630		return test(property, true);
26631	}
26632
26633	if (tests.csstransitions()) {
26634		/* jshint -W053 */
26635		$.support.transition = new String(prefixed('transition'))
26636		$.support.transition.end = events.transition.end[ $.support.transition ];
26637	}
26638
26639	if (tests.cssanimations()) {
26640		/* jshint -W053 */
26641		$.support.animation = new String(prefixed('animation'))
26642		$.support.animation.end = events.animation.end[ $.support.animation ];
26643	}
26644
26645	if (tests.csstransforms()) {
26646		/* jshint -W053 */
26647		$.support.transform = new String(prefixed('transform'));
26648		$.support.transform3d = tests.csstransforms3d();
26649	}
26650
26651})(window.Zepto || window.jQuery, window, document);
26652
26653(function(window, document, undefined) {
26654
26655	/**
26656	 * Find the absolute position of an element
26657	 */
26658	var absPos = function(element) {
26659		var offsetLeft, offsetTop;
26660		offsetLeft = offsetTop = 0;
26661		if (element.offsetParent) {
26662			do {
26663				offsetLeft += element.offsetLeft;
26664				offsetTop += element.offsetTop;
26665			} while (element = element.offsetParent);
26666		}
26667		return [offsetLeft, offsetTop];
26668	};
26669
26670	/**
26671	 * @constructor Progress Circle class
26672	 * @param params.canvas Canvas on which the circles will be drawn.
26673	 * @param params.minRadius Inner radius of the innermost circle, in px.
26674	 * @param params.arcWidth Width of each circle(to be more accurate, ring).
26675	 * @param params.gapWidth Space between each circle.
26676	 * @param params.centerX X coordinate of the center of circles.
26677	 * @param params.centerY Y coordinate of the center of circles.
26678	 * @param params.infoLineBaseAngle Base angle of the info line.
26679	 * @param params.infoLineAngleInterval Angles between the info lines.
26680	 */
26681	var ProgressCircle = function(params) {
26682		this.canvas = params.canvas;
26683		this.minRadius = params.minRadius || 15;
26684		this.arcWidth = params.arcWidth || 5;
26685		this.gapWidth = params.gapWidth || 3;
26686		this.centerX = params.centerX || this.canvas.width / 2;
26687		this.centerY = params.centerY || this.canvas.height / 2;
26688		this.infoLineLength = params.infoLineLength || 60;
26689		this.horizLineLength = params.horizLineLength || 10;
26690		this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8;
26691		this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6;
26692
26693		this.context = this.canvas.getContext('2d');
26694
26695		this.width = this.canvas.width;
26696		this.height = this.canvas.height;
26697
26698		this.circles = [];
26699		this.runningCount = 0;
26700	};
26701
26702	ProgressCircle.prototype = {
26703		constructor: ProgressCircle,
26704
26705		/**
26706		 * @method Adds an progress monitor entry.
26707		 * @param params.fillColor Color to fill in the circle.
26708		 * @param params.outlineColor Color to outline the circle.
26709		 * @param params.progressListener Callback function to fetch the progress.
26710		 * @param params.infoListener Callback function to fetch the info.
26711		 * @returns this
26712		 */
26713		addEntry: function(params) {
26714			this.circles.push(new Circle({
26715				canvas: this.canvas,
26716				context: this.context,
26717				centerX: this.centerX,
26718				centerY: this.centerY,
26719				innerRadius: this.minRadius + this.circles.length *
26720					(this.gapWidth + this.arcWidth),
26721				arcWidth: this.arcWidth,
26722				infoLineLength: this.infoLineLength,
26723				horizLineLength: this.horizLineLength,
26724
26725				id: this.circles.length,
26726				fillColor: params.fillColor,
26727				outlineColor: params.outlineColor,
26728				progressListener: params.progressListener,
26729				infoListener: params.infoListener,
26730				infoLineAngle: this.infoLineBaseAngle +
26731					this.circles.length * this.infoLineAngleInterval,
26732			}));
26733
26734			return this;
26735		},
26736
26737		/**
26738		 * @method Starts the monitor and updates with the given interval.
26739		 * @param interval Interval between updates, in millisecond.
26740		 * @returns this
26741		 */
26742		start: function(interval) {
26743			var self = this;
26744			this.timer = setInterval(function() {
26745				self._update();
26746			}, interval || 33);
26747
26748			return this;
26749		},
26750
26751		/**
26752		 * @method Stop the animation.
26753		 */
26754		stop: function() {
26755			clearTimeout(this.timer);
26756		},
26757
26758		/**
26759		 * @private
26760		 * @method Call update on each circle and redraw them.
26761		 * @returns this
26762		 */
26763		_update: function() {
26764			this._clear();
26765			this.circles.forEach(function(circle, idx, array) {
26766				circle.update();
26767			});
26768
26769			return this;
26770		},
26771
26772		/**
26773		 * @private
26774		 * @method Clear the canvas.
26775		 * @returns this
26776		 */
26777		_clear: function() {
26778			this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
26779
26780			return this;
26781		},
26782
26783	};
26784
26785	/**
26786	 * @private
26787	 * @class Individual progress circle.
26788	 * @param params.canvas Canvas on which the circle will be drawn.
26789	 * @param params.context Context of the canvas.
26790	 * @param params.innerRadius Inner radius of the circle, in px.
26791	 * @param params.arcWidth Width of each arc(circle).
26792	 * @param params.gapWidth Distance between each arc.
26793	 * @param params.centerX X coordinate of the center of circles.
26794	 * @param params.centerY Y coordinate of the center of circles.
26795	 * @param params.fillColor Color to fill in the circle.
26796	 * @param params.outlineColor Color to outline the circle.
26797	 * @param params.progressListener Callback function to fetch the progress.
26798	 * @param params.infoListener Callback function to fetch the info.
26799	 * @param params.infoLineAngle Angle of info line.
26800	 */
26801	var Circle = function(params) {
26802		this.id = params.id;
26803		this.canvas = params.canvas;
26804		this.context = params.context;
26805		this.centerX = params.centerX;
26806		this.centerY = params.centerY;
26807		this.arcWidth = params.arcWidth;
26808		this.innerRadius = params.innerRadius || 0;
26809		this.fillColor = params.fillColor || '#fff';
26810		this.outlineColor = params.outlineColor || this.fillColor;
26811		this.progressListener = params.progressListener;
26812		this.infoLineLength = params.infoLineLength || 250;
26813		this.horizLineLength = params.horizLineLength || 50;
26814		this.infoListener = params.infoListener;
26815		this.infoLineAngle = params.infoLineAngle;
26816
26817		this.outerRadius = this.innerRadius + this.arcWidth;
26818
26819		// If the info listener is not registered, then don't calculate
26820		// the related coordinates
26821		if (!this.infoListener) return;
26822
26823		// calculate the info-line turning points
26824		var angle = this.infoLineAngle,
26825			arcDistance = (this.innerRadius + this.outerRadius) / 2,
26826
26827			sinA = Math.sin(angle),
26828			cosA = Math.cos(angle);
26829
26830		this.infoLineStartX = this.centerX + sinA * arcDistance;
26831		this.infoLineStartY = this.centerY - cosA * arcDistance;
26832
26833		this.infoLineMidX = this.centerX + sinA * this.infoLineLength;
26834		this.infoLineMidY = this.centerY - cosA * this.infoLineLength;
26835
26836		this.infoLineEndX = this.infoLineMidX +
26837			 (sinA < 0 ? -this.horizLineLength : this.horizLineLength);
26838		this.infoLineEndY = this.infoLineMidY;
26839
26840		var infoText = document.createElement('div'),
26841			style = infoText.style;
26842
26843		style.color = this.fillColor;
26844		style.position = 'absolute';
26845		style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px';
26846		// style.top will be calculated in the `drawInfo` method. Since
26847		// user may want to change the size of the font, so the top offset
26848		// must be updated in each loop.
26849		infoText.className = 'ProgressCircleInfo'; // For css styling
26850		infoText.id = 'progress_circle_info_' + this.id;
26851		document.body.appendChild(infoText);
26852		this.infoText = infoText;
26853	};
26854
26855	Circle.prototype = {
26856		constructor: Circle,
26857
26858		update: function() {
26859			this.progress = this.progressListener();
26860			this._draw();
26861
26862			if (this.infoListener) {
26863				this.info = this.infoListener();
26864				this._drawInfo();
26865			}
26866		},
26867
26868		/**
26869		 * @private
26870		 * @method Draw the circle on the canvas.
26871		 * @returns this
26872		 */
26873		_draw: function() {
26874			var ctx = this.context,
26875
26876				ANGLE_OFFSET = -Math.PI / 2,
26877
26878				startAngle = 0 + ANGLE_OFFSET,
26879				endAngle= startAngle + this.progress * Math.PI * 2,
26880
26881				x = this.centerX,
26882				y = this.centerY,
26883
26884				innerRadius = this.innerRadius - this.arcWidth - 1,
26885				outerRadius = this.outerRadius - this.arcWidth - 1;
26886
26887			if ( innerRadius < 0 )
26888				return;
26889
26890			ctx.fillStyle = this.fillColor;
26891			ctx.strokeStyle = this.outlineColor;
26892
26893			ctx.beginPath();
26894			ctx.arc(x, y, innerRadius, startAngle, endAngle, false);
26895			ctx.arc(x, y, outerRadius, endAngle, startAngle, true);
26896			ctx.closePath();
26897			ctx.stroke();
26898			ctx.fill();
26899
26900			return this;
26901		},
26902
26903		/**
26904		 * @private
26905		 * @method Draw the info lines and info text.
26906		 * @returns this
26907		 */
26908		_drawInfo: function() {
26909
26910			var pointList, lineHeight;
26911
26912			pointList = [
26913				[this.infoLineStartX, this.infoLineStartY],
26914				[this.infoLineMidX, this.infoLineMidY],
26915				[this.infoLineEndX, this.infoLineEndY],
26916			];
26917			this._drawSegments(pointList, false);
26918
26919			this.infoText.innerHTML = this.info;
26920
26921			lineHeight = this.infoText.offsetHeight;
26922			this.infoText.style.top = this.infoLineEndY +
26923				absPos(this.canvas)[1] - lineHeight / 2 + 'px';
26924
26925			return this;
26926		},
26927
26928		/**
26929		 * @private
26930		 * @method Helper function to draw the segments
26931		 * @param pointList An array of points in the form of [x, y].
26932		 * @param close Whether to connect the first and last point.
26933		 */
26934		_drawSegments: function(pointList, close) {
26935			var ctx = this.context;
26936
26937			ctx.beginPath();
26938			ctx.moveTo(pointList[0][0], pointList[0][1]);
26939			for (var i = 1; i < pointList.length; ++i) {
26940				ctx.lineTo(pointList[i][0], pointList[i][1]);
26941			}
26942
26943			if (close) {
26944				ctx.closePath();
26945			}
26946			ctx.stroke();
26947		},
26948	};
26949
26950	window.ProgressCircle = ProgressCircle;
26951
26952})(window, document);
26953
26954
26955
26956
26957/* =========================================================
26958 * jquery.vc_chart.js v1.0
26959 * =========================================================
26960 * Copyright 2013 Wpbakery
26961 *
26962 * Jquery chart plugin for the Visual Composer.
26963 * ========================================================= */
26964(function($){
26965	/**
26966	 * Pie chart animated.
26967	 * @param element - DOM element
26968	 * @param options - settings object.
26969	 * @constructor
26970	 */
26971	var VcChart = function(element, options) {
26972		this.el = element;
26973		this.$el = $(this.el);
26974		var $this = this;
26975		$this.options = $.extend({
26976			color: 'wpb_button',
26977			units: '',
26978			width: '',
26979			label_selector: '.vc_pie_chart_value',
26980			back_selector: '.vc_pie_chart_back',
26981			responsive: true
26982		}, options);
26983		$this.init();
26984	};
26985	VcChart.prototype = {
26986		constructor: VcChart,
26987		_progress_v: 0,
26988		animated: false,
26989		colors: {
26990			'wpb_button': 'rgba(247, 247, 247, 1)',
26991			'btn-primary': 'rgba(0, 136, 204, 1)',
26992			'btn-info': 'rgba(88, 185, 218, 1)',
26993			'btn-success': 'rgba(106, 177, 101, 1)',
26994			'btn-warning': 'rgba(255, 153, 0, 1)',
26995			'btn-danger': 'rgba(255, 103, 91, 1)',
26996			'btn-inverse': 'rgba(85, 85, 85, 1)'
26997		},
26998		init: function() {
26999			this.setupColor();
27000			this.value = this.$el.data('pie-value')/100;
27001			this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value');
27002			this.$wrapper = $('.vc_pie_wrapper', this.$el);
27003			this.$label = $(this.options.label_selector, this.$el);
27004			this.$back = $(this.options.back_selector, this.$el);
27005			this.$canvas = this.$el.find('canvas');
27006			this.arcWidth = this.$el.data('pie-width') * 2;
27007			this.draw();
27008			this.setWayPoint();
27009			if(this.options.responsive === true) this.setResponsive();
27010			if (UNCODE.isMobile) this._progress_v = this.value;
27011		},
27012		setupColor: function() {
27013			// if(typeof this.colors[this.options.color] !== 'undefined') {
27014			//     this.color = this.colors[this.options.color];
27015			// } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) {
27016			//     this.color = this.options.color;
27017			// } else {
27018			//     this.color = 'rgba(247, 247, 247, 0.2)';
27019			// }
27020			if(typeof this.options.color !== 'undefined') {
27021				this.color = this.options.color;
27022			} else this.color = 'rgba(247, 247, 247, 0.2)';
27023
27024		},
27025		setResponsive: function() {
27026			var that = this;
27027			if (!UNCODE.isMobile) {
27028				$(window).resize(function(){
27029					if(that.animated === true) that.circle.stop();
27030					that.draw(true);
27031				});
27032			}
27033		},
27034		draw: function(redraw) {
27035			var w = this.$el.addClass('vc_ready').width() * 2,
27036				border_w = this.arcWidth,
27037				radius;
27038			if(!w) w = this.$el.parents(':visible').first().width()-2;
27039			//w = Math.round(w/100*80);
27040			//if (w < 250) w = 250;
27041			radius = w/2;
27042			this.$wrapper.css({"width" : (w / 2) + "px"});
27043			this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"});
27044			this.$back.css({"width" : (w / 2), "height" : (w / 2)});
27045			this.$canvas.attr({"width" : w + "px", "height" : w + "px"});
27046			this.$el.addClass('vc_ready');
27047			this.circle = new ProgressCircle({
27048				canvas: this.$canvas.get(0),
27049				minRadius: radius,
27050				arcWidth: border_w
27051			});
27052			if(redraw === true && this.animated === true) {
27053				this._progress_v = this.value;
27054				this.circle.addEntry({
27055					fillColor: this.color,
27056					progressListener: $.proxy(this.setProgress, this)
27057				}).start();
27058			}
27059		},
27060		setProgress: function() {
27061			if (this._progress_v >= this.value) {
27062				this.circle.stop();
27063				this.animated = true;
27064				this.$label.html(this.label_value + this.options.units);
27065				return this._progress_v;
27066			}
27067			this._progress_v += 0.01;
27068			if (!isNaN(this.label_value)) {
27069				var label_value = this._progress_v/this.value*this.label_value;
27070				var val = Math.round(label_value) + this.options.units;
27071				this.$label.html(val);
27072			} else this.$label.html(this.label_value + this.options.units);
27073			return this._progress_v;
27074		},
27075		animate: function() {
27076			if(this.animated !== true) {
27077				this.circle.addEntry({
27078					fillColor: this.color,
27079					progressListener: $.proxy(this.setProgress, this)
27080				}).start(10);
27081			}
27082		},
27083		setWayPoint: function() {
27084			if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) {
27085				this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' });
27086			} else {
27087				this.animate();
27088			}
27089		}
27090	};
27091	/**
27092	 * jQuery plugin
27093	 * @param option - object with settings
27094	 * @return {*}
27095	 */
27096	$.fn.vcChat = function(option, value) {
27097		return this.each(function () {
27098			var $this = $(this),
27099				data = $this.data('vc_chart'),
27100				options = typeof option === 'object' ? option : {
27101					color: $this.data('pie-color'),
27102					units: $this.data('pie-units')
27103				};
27104			if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options)));
27105			if (typeof option == 'string') data[option](value);
27106		});
27107	};
27108	/**
27109	 * Allows users to rewrite function inside theme.
27110	 */
27111	if ( typeof window['vc_pieChart'] !== 'function' ) {
27112		window.vc_pieChart = function() {
27113			$('.vc_pie_chart:visible:not(.vc_ready)').vcChat();
27114		}
27115	}
27116	$(document).ready(function(){
27117		!window.vc_iframe && vc_pieChart();
27118
27119		/**
27120		* Tab and collapse integration.
27121		*/
27122		$('.nav-tabs a').on('shown.bs.tab', function(e){
27123			var $cont = $(e.target).closest('.tab-container'),
27124				$active = $('.tab-pane.active', $cont);
27125			$('.vc_pie_chart:not(.vc_ready)', $active).vcChat();
27126		});
27127
27128		$('.panel-collapse').on('shown.bs.collapse', function (e) {
27129			$('.vc_pie_chart:not(.vc_ready)', e.target).vcChat();
27130		})
27131	});
27132
27133})(window.jQuery);
27134
27135/* Progress bar
27136 ---------------------------------------------------------- */
27137function uncode_progress_bar() {
27138	jQuery.each(jQuery('.vc_progress_bar'), function(index, val) {
27139		if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) {
27140			return;
27141		}
27142		if (!UNCODE.isMobile) {
27143			new Waypoint({
27144				context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window,
27145				element: val,
27146				handler: function() {
27147					var element = jQuery(this.element);
27148					element.find('.vc_single_bar').each(function(index) {
27149						var $this = jQuery(this),
27150							bar = $this.find('.vc_bar'),
27151							val = bar.data('percentage-value');
27152						setTimeout(function() {
27153							bar.css({
27154								"width": val + '%'
27155							});
27156						}, index * 200);
27157					});
27158				},
27159				offset: '80%'
27160			});
27161		} else {
27162			var element = jQuery(val);
27163			element.find('.vc_single_bar').each(function(index) {
27164				var $this = jQuery(this),
27165					bar = $this.find('.vc_bar'),
27166					val = bar.data('percentage-value');
27167				setTimeout(function() {
27168					bar.css({
27169						"width": val + '%'
27170					});
27171				}, index * 200);
27172			});
27173		}
27174	});
27175};
27176uncode_progress_bar();
27177
27178/*!
27179 * jquery.counterup.js 1.0
27180 *
27181 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal
27182 * Released under the GPL v2 License
27183 *
27184 * Date: Nov 26, 2013
27185 */
27186(function($) {
27187	"use strict";
27188	$.fn.counterUp = function(options) {
27189		// Defaults
27190		var settings = $.extend({
27191			'time': 400,
27192			'delay': 10
27193		}, options);
27194		return this.each(function() {
27195			// Store the object
27196			var $this = $(this);
27197			var $settings = settings;
27198			var counterUpper = function() {
27199				var nums = [];
27200				var divisions = $settings.time / $settings.delay;
27201				var numReal = $this.attr('data-val'),
27202				num = numReal;
27203				var isComma = /[0-9]+,[0-9]+/.test(num);
27204				num = num.replace(/,/g, '');
27205				var isInt = /^[0-9]+$/.test(num);
27206				var isFloat = /^[0-9]+\.[0-9]+$/.test(num);
27207				var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;
27208				// Generate list of incremental numbers to display
27209				for (var i = divisions; i >= 1; i--) {
27210					// Preserve as int if input was int
27211					var newNum = parseInt(num / divisions * i);
27212					// Preserve float if input was float
27213					if (isFloat) {
27214						newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces);
27215					}
27216					// Preserve commas if input had commas
27217					if (isComma) {
27218						while (/(\d+)(\d{3})/.test(newNum.toString())) {
27219							newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
27220						}
27221					}
27222					nums.unshift(newNum);
27223				}
27224				nums.push(numReal);
27225				$this.data('counterup-nums', nums);
27226				$this.text('0');
27227				// Updates the number until we're done
27228				var f = function() {
27229					if ($this.data('counterup-nums') != null) {
27230						$this.text($this.data('counterup-nums').shift());
27231						if ($this.data('counterup-nums').length) {
27232							setTimeout($this.data('counterup-func'), $settings.delay);
27233						} else {
27234							delete $this.data('counterup-nums');
27235							$this.data('counterup-nums', null);
27236							$this.data('counterup-func', null);
27237						}
27238					}
27239				};
27240				$this.data('counterup-func', f);
27241				// Start the count up
27242				setTimeout($this.data('counterup-func'), $settings.delay);
27243			};
27244			// Perform counts when the element gets into view
27245			new Waypoint({
27246				context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window,
27247				element: this,
27248				handler: function() {
27249					counterUpper();
27250					if (!UNCODE.isUnmodalOpen) {
27251						this.destroy();
27252					}
27253				},
27254				offset: '100%'
27255			});
27256		});
27257	};
27258})(jQuery);
27259
27260/*!
27261 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/)
27262 * Copyright (c) 2016 Edson Hilios
27263 *
27264 * Permission is hereby granted, free of charge, to any person obtaining a copy of
27265 * this software and associated documentation files (the "Software"), to deal in
27266 * the Software without restriction, including without limitation the rights to
27267 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
27268 * the Software, and to permit persons to whom the Software is furnished to do so,
27269 * subject to the following conditions:
27270 *
27271 * The above copyright notice and this permission notice shall be included in all
27272 * copies or substantial portions of the Software.
27273 *
27274 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27275 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
27276 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
27277 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
27278 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27279 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27280 */
27281(function(factory) {
27282	"use strict";
27283	if (typeof define === "function" && define.amd) {
27284		define([ "jquery" ], factory);
27285	} else {
27286		factory(jQuery);
27287	}
27288})(function($) {
27289	"use strict";
27290	var instances = [], matchers = [], defaultOptions = {
27291		precision: 100,
27292		elapse: false,
27293		defer: false
27294	};
27295	matchers.push(/^[0-9]*$/.source);
27296	matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
27297	matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
27298	matchers = new RegExp(matchers.join("|"));
27299	function parseDateString(dateString) {
27300		if (dateString instanceof Date) {
27301			return dateString;
27302		}
27303		if (String(dateString).match(matchers)) {
27304			if (String(dateString).match(/^[0-9]*$/)) {
27305				dateString = Number(dateString);
27306			}
27307			if (String(dateString).match(/\-/)) {
27308				dateString = String(dateString).replace(/\-/g, "/");
27309			}
27310			return new Date(dateString);
27311		} else {
27312			throw new Error("Couldn't cast `" + dateString + "` to a date object.");
27313		}
27314	}
27315	var DIRECTIVE_KEY_MAP = {
27316		Y: "years",
27317		m: "months",
27318		n: "daysToMonth",
27319		d: "daysToWeek",
27320		w: "weeks",
27321		W: "weeksToMonth",
27322		H: "hours",
27323		M: "minutes",
27324		S: "seconds",
27325		D: "totalDays",
27326		I: "totalHours",
27327		N: "totalMinutes",
27328		T: "totalSeconds"
27329	};
27330	function escapedRegExp(str) {
27331		var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
27332		return new RegExp(sanitize);
27333	}
27334	function strftime(offsetObject) {
27335		return function(format) {
27336			var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);
27337			if (directives) {
27338				for (var i = 0, len = directives.length; i < len; ++i) {
27339					var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null;
27340					directive = directive[2];
27341					if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) {
27342						value = DIRECTIVE_KEY_MAP[directive];
27343						value = Number(offsetObject[value]);
27344					}
27345					if (value !== null) {
27346						if (modifier === "!") {
27347							value = pluralize(plural, value);
27348						}
27349						if (modifier === "") {
27350							if (value < 10) {
27351								value = "0" + value.toString();
27352							}
27353						}
27354						format = format.replace(regexp, value.toString());
27355					}
27356				}
27357			}
27358			format = format.replace(/%%/, "%");
27359			return format;
27360		};
27361	}
27362	function pluralize(format, count) {
27363		var plural = "s", singular = "";
27364		if (format) {
27365			format = format.rep
vendor: 8,618 bytes, lines 27365-27509
27365lace(/(:|;|\s)/gi, "").split(/\,/);
27366			if (format.length === 1) {
27367				plural = format[0];
27368			} else {
27369				singular = format[0];
27370				plural = format[1];
27371			}
27372		}
27373		if (Math.abs(count) > 1) {
27374			return plural;
27375		} else {
27376			return singular;
27377		}
27378	}
27379	var Countdown = function(el, finalDate, options) {
27380		this.el = el;
27381		this.$el = $(el);
27382		this.interval = null;
27383		this.offset = {};
27384		this.options = $.extend({}, defaultOptions);
27385		this.instanceNumber = instances.length;
27386		instances.push(this);
27387		this.$el.data("countdown-instance", this.instanceNumber);
27388		if (options) {
27389			if (typeof options === "function") {
27390				this.$el.on("update.countdown", options);
27391				this.$el.on("stoped.countdown", options);
27392				this.$el.on("finish.countdown", options);
27393			} else {
27394				this.options = $.extend({}, defaultOptions, options);
27395			}
27396		}
27397		this.setFinalDate(finalDate);
27398		if (this.options.defer === false) {
27399			this.start();
27400		}
27401	};
27402	$.extend(Countdown.prototype, {
27403		start: function() {
27404			if (this.interval !== null) {
27405				clearInterval(this.interval);
27406			}
27407			var self = this;
27408			this.update();
27409			this.interval = setInterval(function() {
27410				self.update.call(self);
27411			}, this.options.precision);
27412		},
27413		stop: function() {
27414			clearInterval(this.interval);
27415			this.interval = null;
27416			this.dispatchEvent("stoped");
27417		},
27418		toggle: function() {
27419			if (this.interval) {
27420				this.stop();
27421			} else {
27422				this.start();
27423			}
27424		},
27425		pause: function() {
27426			this.stop();
27427		},
27428		resume: function() {
27429			this.start();
27430		},
27431		remove: function() {
27432			this.stop.call(this);
27433			instances[this.instanceNumber] = null;
27434			delete this.$el.data().countdownInstance;
27435		},
27436		setFinalDate: function(value) {
27437			this.finalDate = parseDateString(value);
27438		},
27439		update: function() {
27440			if (this.$el.closest("html").length === 0) {
27441				this.remove();
27442				return;
27443			}
27444			var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft;
27445			newTotalSecsLeft = this.finalDate.getTime() - now.getTime();
27446			newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3);
27447			newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft);
27448			if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) {
27449				return;
27450			} else {
27451				this.totalSecsLeft = newTotalSecsLeft;
27452			}
27453			this.elapsed = now >= this.finalDate;
27454			this.offset = {
27455				seconds: this.totalSecsLeft % 60,
27456				minutes: Math.floor(this.totalSecsLeft / 60) % 60,
27457				hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24,
27458				days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7,
27459				daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7,
27460				daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368),
27461				weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7),
27462				weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4,
27463				months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368),
27464				years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()),
27465				totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24),
27466				totalHours: Math.floor(this.totalSecsLeft / 60 / 60),
27467				totalMinutes: Math.floor(this.totalSecsLeft / 60),
27468				totalSeconds: this.totalSecsLeft
27469			};
27470			if (!this.options.elapse && this.totalSecsLeft === 0) {
27471				this.stop();
27472				this.dispatchEvent("finish");
27473			} else {
27474				this.dispatchEvent("update");
27475			}
27476		},
27477		dispatchEvent: function(eventName) {
27478			var event = $.Event(eventName + ".countdown");
27479			event.finalDate = this.finalDate;
27480			event.elapsed = this.elapsed;
27481			event.offset = $.extend({}, this.offset);
27482			event.strftime = strftime(this.offset);
27483			this.$el.trigger(event);
27484		}
27485	});
27486	$.fn.countdown = function() {
27487		var argumentsArray = Array.prototype.slice.call(arguments, 0);
27488		return this.each(function() {
27489			var instanceNumber = $(this).data("countdown-instance");
27490			if (instanceNumber !== undefined) {
27491				var instance = instances[instanceNumber], method = argumentsArray[0];
27492				if (Countdown.prototype.hasOwnProperty(method)) {
27493					instance[method].apply(instance, argumentsArray.slice(1));
27494				} else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) {
27495					instance.setFinalDate.call(instance, method);
27496					instance.start();
27497				} else {
27498					$.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method));
27499				}
27500			} else {
27501				new Countdown(this, argumentsArray[0], argumentsArray[1]);
27502			}
27503		});
27504	};
27505});
27506
27507!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Share=e()}}(function(){var define,module,exports;
27508function getStyles(config){
27509  // return ""+config.selector+"{width:92px;height:20px;-webkit-touch-callout:none;-khtml-user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"+config.selector+" [class*=social-]:before{font-family:'uncodeicon'}"+config.selector+" label{font-size:16px;cursor:pointer;margin:0;padding:5px 10px;border-radius:5px;background:#a29baa;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}"+config.selector+" label:hover{opacity:.8}"+config.selector+" label span{text-transform:uppercase;font-size:.9em;font-family:Lato,sans-serif;font-weight:700;-webkit-font-smoothing:antialiased;padding-left:6px}"+config.selector+" .social{opacity:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;margin-left:-15px;visibility:hidden}"+config.selector+" .social.top{-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;margin-top:-80px}"+config.selector+" .social.bottom{-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;margin-top:5px}"+config.selector+" .social.middle{margin-top:-34px}"+config.selector+" .social.middle.right{-webkit-transform-origin:5% 50%;-ms-transform-origin:5% 50%;transform-origin:5% 50%;margin-left:105px}"+config.selector+" .social.middle.left{-webkit-transform-origin:5% 50%;-ms-transform-origin:5% 50%;transform-origin:5% 50%}"+config.selector+" .social.right{margin-left:14px}"+config.selector+" .social.load{-webkit-transition:none!important;transition:none!important}"+config.selector+" .social.networks-1{width:60px}"+config.selector+" .social.networks-1.center,"+config.selector+" .social.networks-1.left{margin-left:14px}"+config.selector+" .social.networks-1.middle.left{margin-left:-70px}"+config.selector+" .social.networks-1 ul{width:60px}"+config.selector+" .social.networks-2{width:120px}"+config.selector+" .social.networks-2.center{margin-left:-13px}"+config.selector+" .social.networks-2.left{margin-left:-44px}"+config.selector+" .social.networks-2.middle.left{margin-left:-130px}"+config.selector+" .social.networks-2 ul{width:120px}"+config.selector+" .social.networks-3{width:180px}"+config.selector+" .social.networks-3.center{margin-left:-45px}"+config.selector+" .social.networks-3.left{margin-left:-102px}"+config.selector+" .social.networks-3.middle.left{margin-left:-190px}"+config.selector+" .social.networks-3 ul{width:180px}"+config.selector+" .social.networks-4{width:240px}"+config.selector+" .social.networks-4.center{margin-left:-75px}"+config.selector+" .social.networks-4.left{margin-left:162px}"+config.selector+" .social.networks-4.middle.left{margin-left:-250px}"+config.selector+" .social.networks-4 ul{width:240px}"+config.selector+" .social.networks-5{width:300px}"+config.selector+" .social.networks-5.center{margin-left:-105px}"+config.selector+" .social.networks-5.left{margin-left:-225px}"+config.selector+" .social.networks-5.middle.left{margin-left:-320px}"+config.selector+" .social.networks-5 ul{width:300px}"+config.selector+" .social.active{opacity:1;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;visibility:visible}"+config.selector+" .social.active.top{-webkit-transform:scale(1) translateY(-20px);-ms-transform:scale(1) translateY(-20px);transform:scale(1) translateY(-20px)}"+config.selector+" .social.active.bottom{-webkit-transform:scale(1) translateY(15px);-ms-transform:scale(1) translateY(15px);transform:scale(1) translateY(15px)}"+config.selector+" .social.active.middle.right{-webkit-transform:scale(1) translateX(10px);-ms-transform:scale(1) translateX(10px);transform:scale(1) translateX(10px)}"+config.selector+" .social.active.middle.left{-webkit-transform:scale(1) translateX(-20px);-ms-transform:scale(1) translateX(-20px);transform:scale(1) translateX(-20px)}"+config.selector+" .social ul{position:relative;
27509left:0;right:0;height:46px;color:#fff;margin:auto;padding:0;list-style:none}"+config.selector+" .social ul li{font-size:20px;cursor:pointer;width:60px;margin:0;padding:12px 0;text-align:center;float:left;display:none;height:22px;position:relative;z-index:2;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}"+config.selector+" .social ul li:hover{}"+config.selector+" .social li[class*=facebook]{display:"+config.networks.facebook.display+"}"+config.selector+" .social li[class*=twitter]{display:"+config.networks.twitter.display+"}"+config.selector+" .social li[class*=gplus]{display:"+config.networks.google_plus.display+"}"+config.selector+" .social li[class*=pinterest]{display:"+config.networks.pinterest.display+"}"+config.selector+" .social li[class*=paper-plane]{display:"+config.networks.email.display+"}"
27510};
27511  var ShareUtils;
27512
27513if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") {
27514  Object.defineProperty(HTMLElement.prototype, "classList", {
27515    get: function() {
27516      var ret, self, update;
27517      update = function(fn) {
27518        return function(value) {
27519          var classes, index;
27520          classes = self.className.split(/\s+/);
27521          index = classes.indexOf(value);
27522          fn(classes, index, value);
27523          self.className = classes.join(" ");
27524        };
27525      };
27526      self = this;
27527      ret = {
27528        add: update(function(classes, index, value) {
27529          ~index || classes.push(value);
27530        }),
27531        remove: update(function(classes, index) {
27532          ~index && classes.splice(index, 1);
27533        }),
27534        toggle: update(function(classes, index, value) {
27535          if (~index) {
27536            classes.splice(index, 1);
27537          } else {
27538            classes.push(value);
27539          }
27540        }),
27541        contains: function(value) {
27542          return !!~self.className.split(/\s+/).indexOf(value);
27543        },
27544        item: function(i) {
27545          return self.className.split(/\s+/)[i] || null;
27546        }
27547      };
27548      Object.defineProperty(ret, "length", {
27549        get: function() {
27550          return self.className.split(/\s+/).length;
27551        }
27552      });
27553      return ret;
27554    }
27555  });
27556}
27557
27558String.prototype.to_rfc3986 = function() {
27559  var tmp;
27560  tmp = encodeURIComponent(this);
27561  return tmp.replace(/[!'()*]/g, function(c) {
27562    return "%" + c.charCodeAt(0).toString(16);
27563  });
27564};
27565
27566ShareUtils = (function() {
27567  function ShareUtils() {}
27568
27569  ShareUtils.prototype.extend = function(to, from, overwrite) {
27570    var hasProp, prop;
27571    for (prop in from) {
27572      hasProp = to[prop] !== undefined;
27573      if (hasProp && typeof from[prop] === "object") {
27574        this.extend(to[prop], from[prop], overwrite);
27575      } else {
27576        if (overwrite || !hasProp) {
27577          to[prop] = from[prop];
27578        }
27579      }
27580    }
27581  };
27582
27583  ShareUtils.prototype.hide = function(el) {
27584    return el.style.display = "none";
27585  };
27586
27587  ShareUtils.prototype.show = function(el) {
27588    return el.style.display = "block";
27589  };
27590
27591  ShareUtils.prototype.has_class = function(el, class_name) {
27592    return el.classList.contains(class_name);
27593  };
27594
27595  ShareUtils.prototype.add_class = function(el, class_name) {
27596    return el.classList.add(class_name);
27597  };
27598
27599  ShareUtils.prototype.remove_class = function(el, class_name) {
27600    return el.classList.remove(class_name);
27601  };
27602
27603  ShareUtils.prototype.is_encoded = function(str) {
27604    str = str.to_rfc3986();
27605    return decodeURIComponent(str) !== str;
27606  };
27607
27608  ShareUtils.prototype.encode = function(str) {
27609    if (typeof str === "undefined" || this.is_encoded(str)) {
27610      return str;
27611    } else {
27612      return str.to_rfc3986();
27613    }
27614  };
27615
27616  ShareUtils.prototype.popup = function(url, params) {
27617    var k, popup, qs, v;
27618    if (params == null) {
27619      params = {};
27620    }
27621    popup = {
27622      width: 500,
27623      height: 350
27624    };
27625    popup.top = (screen.height / 2) - (popup.height / 2);
27626    popup.left = (screen.width / 2) - (popup.width / 2);
27627    qs = ((function() {
27628      var _results;
27629      _results = [];
27630      for (k in params) {
27631        v = params[k];
27632        _results.push("" + k + "=" + (this.encode(v)));
27633      }
27634      return _results;
27635    }).call(this)).join('&');
27636    if (qs) {
27637      qs = "?" + qs;
27638    }
27639    return window.open(url + qs, 'targetWindow', "toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,left=" + popup.left + ",top=" + popup.top + ",width=" 
27639+ popup.width + ",height=" + popup.height);
27640  };
27641
27642  return ShareUtils;
27643
27644})();
27645var Share,
27646  __hasProp = {}.hasOwnProperty,
27647  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
27648
27649Share = (function(_super) {
27650  __extends(Share, _super);
27651
27652  function Share(element, options) {
27653    this.element = element;
27654    this.el = {
27655      head: document.getElementsByTagName('head')[0],
27656      body: document.getElementsByTagName('body')[0]
27657    };
27658    this.config = {
27659      enabled_networks: 0,
27660      protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//',
27661      url: window.location.href.replace("&", "%26"),
27662      caption: null,
27663      title: this.default_title(),
27664      image: this.default_image(),
27665      description: this.default_description(),
27666      ui: {
27667        flyout: 'top center',
27668        button_text: 'Share',
27669        button_font: true,
27670        icon_font: true
27671      },
27672      networks: {
27673        twitter: {
27674          enabled: true,
27675          url: null,
27676          title: null,
27677          description: null
27678        },
27679        facebook: {
27680          enabled: true,
27681          load_sdk: true,
27682          url: null,
27683          app_id: null,
27684          title: null,
27685          caption: null,
27686          description: null,
27687          image: null
27688        },
27689        threads: {
27690          enabled: true,
27691          url: null,
27692          title: null,
27693          description: null
27694        },
27695        bluesky: {
27696          enabled: true,
27697          url: null,
27698          title: null,
27699          description: null
27700        },
27701        pinterest: {
27702          enabled: true,
27703          url: null,
27704          image: null,
27705          description: null
27706        },
27707        reddit: {
27708          enabled: true,
27709          url: null,
27710          title: null
27711        },
27712        linkedin: {
27713          enabled: true,
27714          url: null,
27715          title: null,
27716          description: null
27717        },
27718        xing: {
27719          enabled: true,
27720          url: null,
27721          title: null,
27722          image: null,
27723          description: null
27724        },
27725        whatsapp: {
27726          enabled: true,
27727          title: null,
27728          url: null
27729        },
27730        email: {
27731          enabled: true,
27732          title: null,
27733          description: null,
27734          url: null
27735        }
27736      }
27737    };
27738    this.setup(element, options);
27739    return this;
27740  }
27741
27742  Share.prototype.setup = function(element, opts) {
27743    var index, instance, instances, _i, _len;
27744    instances = document.querySelectorAll(element);
27745    this.extend(this.config, opts, true);
27746    this.set_global_configuration();
27747    this.normalize_network_configuration();
27748    if (this.config.ui.icon_font) {
27749      this.inject_icons();
27750    }
27751    if (this.config.ui.button_font) {
27752      this.inject_fonts();
27753    }
27754    if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) {
27755      this.inject_facebook_sdk();
27756    }
27757    for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) {
27758      instance = instances[index];
27759      this.setup_instance(element, index);
27760    }
27761  };
27762
27763  Share.prototype.setup_instance = function(element, index) {
27764    var button, instance, label, network, networks, _i, _len, _results,
27765      _this = this;
27766    instance = document.querySelectorAll(element)[index];
27767    this.hide(instance);
27768    this.add_class(instance, "sharer-" + index);
27769    instance = document.querySelectorAll(element)[index];
27770    this.inject_css(instance);
27771    this.inject_html(instance);
27772    this.show(instance);
27773    label = instance.getElementsByTagName("label")[0];
27774    button = instance.getElementsByClassName("social")[0];
27775    networks = instance.getElementsByTagName('li');
27776    this.add_class(button, "networks-" + this.config.enabled_networks);
27777    label.addEventListener("click", function() {
27778      return _this.event_toggle(button);
27779    });
27780    _this = this;
27781    _results = [];
27782    for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) {
27783      network = networks[index];
27784      _results.push(network.addEventListener("click", function() {
27785        _this.event_network(instance, this);
27786        return _this.event_close(button);
27787      }));
27788    }
27789    return _results;
27790  };
27791
27792  Share.prototype.event_toggle = function(button) {
27793    if (this.has_class(button, "active")) {
27794      return this.event_close(button);
27795    } else {
27796      return this.event_open(button);
27797    }
27798  };
27799
27800  Share.prototype.event_open = function(button) {
27801    if (this.has_class(button, "load")) {
27802      this.remove_class(button, "load");
27803    }
27804    return this.add_class(button, "active");
27805  };
27806
27807  Share.prototype.event_close = function(button) {
27808    return this.remove_class(button, "active");
27809  };
27810
27811  Share.prototype.event_network = function(instance, network) {
27812    var name;
27813    name = network.getAttribute("data-network");
27814    this.hook("before", name, instance);
27815    this["network_" + name]();
27816    return this.hook("after", name, instance);
27817  };
27818
27819  Share.prototype.open = function() {
27820    return this["public"]("open");
27821  };
27822
27823  Share.prototype.close = function() {
27824    return this["public"]("close");
27825  };
27826
27827  Share.prototype.toggle = function() {
27828    return this["public"]("toggle");
27829  };
27830
27831  Share.prototype["public"] = function(action) {
27832    var button, index, instance, _i, _len, _ref, _results;
27833    _ref = document.querySelectorAll(this.element);
27834    _results = [];
27835    for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
27836      instance = _ref[index];
27837      button = instance.getElementsByClassName("social")[0];
27838      _results.push(this["event_" + action](button));
27839    }
27840    return _results;
27841  };
27842
27843  Share.prototype.network_facebook = function() {
27844    if (this.config.networks.facebook.load_sdk) {
27845      if (!window.FB) {
27846        return console.error("The Facebook JS SDK hasn't loaded yet.");
27847      }
27848      return FB.ui({
27849        method: 'feed',
27850        name: this.config.networks.facebook.title,
27851        link: this.config.networks.facebook.url,
27852        picture: this.config.networks.facebook.image,
27853        caption: this.config.networks.facebook.caption,
27854        description: this.config.networks.facebook.description
27855      });
27856    } else {
27857      return this.popup('https://www.facebook.com/sharer/sharer.php', {
27858        u: this.config.networks.facebook.url
27859      });
27860    }
27861  };
27862
27863  Share.prototype.network_threads = function() {
27864    return this.popup('https://threads.net/intent/post', {
27865      text: this.config.networks.threads.title,
27866      url: this.config.networks.threads.url
27867    });
27868  };
27869
27870  Share.prototype.network_bluesky = function() {
27871    return this.popup('https://bsky.app/intent/compose', {
27872      text: this.config.networks.bluesky.title + ' ' + this.config.networks.bluesky.url
27873    });
27874  };
27875
27876  Share.prototype.network_twitter = function() {
27877    return this.popup('https://twitter.com/intent/tweet', {
27878      text: this.config.networks.twitter.title,
27879      url: this.config.networks.twitter.url
27880    });
27881  };
27882
27883  Share.prototype.network_pinterest = function() {
27884    return this.popup('https://www.pinterest.com/pin/create/button', {
27885      url: this.config.networks.pinterest.url,
27886      media: this.config.networks.pinterest.image,
27887      description: this.config.networks.pinterest.description
27888    });
27889  };
27890
27891  Share.prototype.network_linkedin = function() {
27892    return this.popup('https://www.linkedin.com/shareArticle', {
27893      url: this.config.networks.linkedin.url,
27894      title: this.config.networks.linkedin.title,
27895      summary: this.config.networks.linkedin.description
27896    });
27897  }
27898
27899  Share.prototype.network_xing = function() {
27900    return this.popup('https://www.xing.com/spi/shares/new', {
27901      url: this.config.networks.xing.url,
27902      image: this.config.networks.xing.image,
27903      title: this.config.networks.xing.title,
27904      summary: this.config.networks.xing.description
27905    });
27906  }
27907
27908  Share.prototype.network_whatsapp = function() {
27909    return this.popup('https://api.whatsapp.com/send', {
27910      text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url,
27911    });
27912  }
27913
27914  Share.prototype.network_email = function() {
27915    return this.popup('mailto:', {
27916      subject: this.config.networks.email.title,
27917      body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description,
27918    });
27919  };
27920
27921  Share.prototype.inject_icons = function() {
27922  //  return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css");
27923  };
27924
27925  Share.prototype.inject_fonts = function() {
27926   // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text);
27927  };
27928
27929  Share.prototype.inject_stylesheet = function(url) {
27930    var link;
27931    if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) {
27932      link = document.createElement("link");
27933      link.setAttribute("rel", "stylesheet");
27934      link.setAttribute("href", url);
27935      return this.el.head.appendChild(link);
27936    }
27937  };
27938
27939  Share.prototype.inject_css = function(instance) {
27940    var css, meta, selector, style;
27941    selector = "." + (instance.getAttribute('class').split(" ").join("."));
27942    if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) {
27943      this.config.selector = selector;
27944      css = getStyles(this.config);
27945      style = document.createElement("style");
27946      style.type = "text/css";
27947      if (style.styleSheet) {
27948        style.styleSheet.cssText = css;
27949      } else {
27950        style.appendChild(document.createTextNode(css));
27951      }
27952      this.el.head.appendChild(style);
27953      delete this.config.selector;
27954      meta = document.createElement("meta");
27955      meta.setAttribute("name", "sharer" + selector);
27956      return this.el.head.appendChild(meta);
27957    }
27958  };
27959
27960  Share.prototype.inject_html = function(instance) {
27961    //return instance.innerHTML = "<label class='social-export'><span>" + this.config.ui.button_text + "</span></label><div class='social load " + this.config.ui.flyout + "'><ul><li class='social-facebook' data-network='facebook' tabindex='0'></li><li class='social-twitter' data-network='twitter' tabindex='0'></li><li class='social-gplus' data-network='google_plus' tabindex='0'></li><li class='social-pinterest' data-network='pinterest' tabindex='0'></li><li class='social-linkedin' data-network='linkedin' tabindex='0'></li><li class='social-xing' data-network='xing' tabindex='0'></li><li class='social-paper-plane' data-network='email' tabindex='0'></li></ul></div>";
27962    return instance.innerHTML = "<label class='social-export'><span>" + this.config.ui.button_text + "</span></label><div class='social load " + this.config.ui.flyout + "'><ul><li class='social-facebook' data-network='facebook' tabindex='0' role='button'></li><li class='social-twitter' data-network='twitter' tabindex='0' role='button'></li><li class='social-threads' data-network='threads' tabindex='0' role='button'></li><li class='social-pinterest' data-network='pinterest' tabindex='0' role='button'></li><li class='social-linkedin' data-network='linkedin' tabindex='0' role='button'></li><li class='social-whatsapp' data-network='whatsapp' tabindex='0' role='button'></li><li class='social-bluesky' data-network='bluesky' tabindex='0' role='button'></li><li class='social-xing' data-network='xing' tabindex='0' role='button'></li><li class='social-paper-plane' data-network='email' tabindex='0' role='button'></li></ul></div>";
27963  };
27964
27965  Share.prototype.inject_facebook_sdk = function() {
27966    var fb_root, script;
27967    if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) {
27968      script = document.createElement("script");
27969      script.text = "window.fbAsyncInit=function(){FB.init({appId:'" + this.config.networks.facebook.app_id + "',status:true,xfbml:true})};(function(e,t,n){var r,i=e.getElementsByTagName(t)[0];if(e.getElementById(n)){return}r=e.createElement(t);r.id=n;r.src='" + this.config.protocol + "connect.facebook.net/en_US/all.js';i.parentNode.insertBefore(r,i)})(document,'script','facebook-jssdk')";
27970      fb_root = document.createElement("div");
27971      fb_root.id = "fb-root";
27972      this.el.body.appendChild(fb_root);
27973      return this.el.body.appendChild(script);
27974    }
27975  };
27976
27977  Share.prototype.hook = function(type, network, instance) {
27978    var fn, opts;
27979    fn = this.config.networks[network][type];
27980    if (typeof fn === "function") {
27981      opts = fn.call(this.config.networks[network], instance);
27982      if (opts !== void 0) {
27983        opts = this.normalize_filter_config_updates(opts);
27984        this.extend(this.config.networks[network], opts, true);
27985        this.normalize_network_configuration();
27986      }
27987    }
27988  };
27989
27990  Share.prototype.default_title = function() {
27991    var content;
27992    if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) {
27993      return encodeURIComponent(content.getAttribute('content'));
27994    } else if (content = document.querySelector('title')) {
27995      return encodeURIComponent(content.innerText);
27996    }
27997  };
27998
27999  Share.prototype.default_image = function() {
28000    var content;
28001    if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) {
28002      return content.getAttribute('content');
28003    }
28004  };
28005
28006  Share.prototype.default_description = function() {
28007    var content;
28008    if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) {
28009      return encodeURIComponent(content.getAttribute('content'));
28010    } else {
28011      return '';
28012    }
28013  };
28014
28015  Share.prototype.set_global_configuration = function() {
28016    var display, network, option, options, _ref, _results;
28017    _ref = this.config.networks;
28018    _results = [];
28019    for (network in _ref) {
28020      options = _ref[network];
28021      for (option in options) {
28022        if (this.config.networks[network][option] == null) {
28023          this.config.networks[network][option] = this.config[option];
28024        }
28025      }
28026      if (this.config.networks[network].enabled) {
28027        display = 'block';
28028        this.config.enabled_networks += 1;
28029      } else {
28030        display = 'none';
28031      }
28032      _results.push(this.config.networks[network].display = display);
28033    }
28034    return _results;
28035  };
28036
28037  Share.prototype.normalize_network_configuration = function() {
28038    if (!this.config.networks.facebook.app_id) {
28039      this.config.networks.facebook.load_sdk = false;
28040    }
28041    if (!this.is_encoded(this.config.networks.twitter.description)) {
28042      this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description);
28043    }
28044    if (typeof this.config.networks.facebook.app_id === 'number') {
28045      return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString();
28046    }
28047  };
28048
28049  Share.prototype.normalize_filter_config_updates = function(opts) {
28050    if (this.config.networks.facebook.app_id !== opts.app_id) {
28051      console.warn("You are unable to change the Facebook app_id after the button has been initialized. Please-in-out update your Facebook filters accordingly.");
28052      delete opts.app_id;
28053    }
28054    if (this.config.networks.facebook.load_sdk !== opts.load_sdk) {
28055      console.warn("You are unable to change the Facebook load_sdk option after the button has been initialized. Please-in-out update your Facebook filters accordingly.");
28056      delete opts.app_id;
28057    }
28058    return opts;
28059  };
28060
28061  return Share;
28062
28063})(ShareUtils);
28064 return Share;
28065});
28066
28067// Generated by CoffeeScript 1.9.2
28068
28069// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net
28070
28071(function() {
28072  var $, win;
28073
28074  $ = this.jQuery || window.jQuery;
28075
28076  win = $(window);
28077
28078  $.fn.stick_in_parent = function(opts) {
28079    var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class;
28080    if (opts == null) {
28081      opts = {};
28082    }
28083    sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, recalc_every = opts.recalc_every, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer, enable_bottoming = opts.bottoming;
28084    if (offset_top == null) {
28085      offset_top = 0;
28086    }
28087    if (parent_selector == null) {
28088      parent_selector = void 0;
28089    }
28090    if (inner_scrolling == null) {
28091      inner_scrolling = true;
28092    }
28093    if (sticky_class == null) {
28094      sticky_class = "is_stuck";
28095    }
28096    doc = $(document);
28097    if (enable_bottoming == null) {
28098      enable_bottoming = true;
28099    }
28100    outer_width = function(el) {
28101      var _el, computed, w;
28102      if (window.getComputedStyle) {
28103        _el = el[0];
28104        computed = window.getComputedStyle(el[0]);
28105        w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right"));
28106        if (computed.getPropertyValue("box-sizing") !== "border-box") {
28107          w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right"));
28108        }
28109        return w;
28110      } else {
28111        return el.outerWidth(true);
28112      }
28113    };
28114    fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) {
28115      var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick;
28116      if (elm.data("sticky_kit")) {
28117        return;
28118      }
28119      elm.data("sticky_kit", true);
28120      last_scroll_height = doc.height();
28121      parent = elm.parent();
28122      if (parent_selector != null) {
28123        parent = parent.closest(parent_selector);
28124      }
28125      if (!parent.length) {
28126        throw "failed to find stick parent";
28127      }
28128      fixed = false;
28129      bottomed = false;
28130      spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />");
28131      if (spacer) {
28132        spacer.css('position', elm.css('position'));
28133      }
28134      recalc = function() {
28135        var border_top, padding_top, restore;
28136        if (detached) {
28137          return;
28138        }
28139        last_scroll_height = doc.height();
28140        border_top = parseInt(parent.css("border-top-width"), 10);
28141        padding_top = parseInt(parent.css("padding-top"), 10);
28142        padding_bottom = parseInt(parent.css("padding-bottom"), 10);
28143        parent_top = parent.offset().top + border_top + padding_top;
28144        parent_height = parent.height();
28145        if (fixed) {
28146          fixed = false;
vendor: 6,068 bytes, lines 28147-28341
28147          bottomed = false;
28148          if (manual_spacer == null) {
28149            elm.insertAfter(spacer);
28150            spacer.detach();
28151          }
28152          elm.css({
28153            position: "",
28154            top: "",
28155            width: "",
28156            bottom: ""
28157          }).removeClass(sticky_class);
28158          restore = true;
28159        }
28160        top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top;
28161        height = elm.outerHeight(true);
28162        el_float = elm.css("float");
28163        if (spacer) {
28164          spacer.css({
28165            width: outer_width(elm),
28166            height: height,
28167            display: elm.css("display"),
28168            "vertical-align": elm.css("vertical-align"),
28169            "float": el_float
28170          });
28171        }
28172        if (restore) {
28173          return tick();
28174        }
28175      };
28176      recalc();
28177      if (height === parent_height) {
28178        return;
28179      }
28180      last_pos = void 0;
28181      offset = offset_top;
28182      recalc_counter = recalc_every;
28183      tick = function() {
28184        var css, delta, recalced, scroll, will_bottom, win_height;
28185        if (detached) {
28186          return;
28187        }
28188        recalced = false;
28189        if (recalc_counter != null) {
28190          recalc_counter -= 1;
28191          if (recalc_counter <= 0) {
28192            recalc_counter = recalc_every;
28193            recalc();
28194            recalced = true;
28195          }
28196        }
28197        if (!recalced && doc.height() !== last_scroll_height) {
28198          recalc();
28199          recalced = true;
28200        }
28201        scroll = win.scrollTop();
28202        if (last_pos != null) {
28203          delta = scroll - last_pos;
28204        }
28205        last_pos = scroll;
28206        if (fixed) {
28207          if (enable_bottoming) {
28208            will_bottom = scroll + height + offset > parent_height + parent_top;
28209            if (bottomed && !will_bottom) {
28210              bottomed = false;
28211              elm.css({
28212                position: "fixed",
28213                bottom: "",
28214                top: offset
28215              }).trigger("sticky_kit:unbottom");
28216            }
28217          }
28218          if (scroll < top) {
28219            fixed = false;
28220            offset = offset_top;
28221            if (manual_spacer == null) {
28222              if (el_float === "left" || el_float === "right") {
28223                elm.insertAfter(spacer);
28224              }
28225              spacer.detach();
28226            }
28227            css = {
28228              position: "",
28229              width: "",
28230              top: ""
28231            };
28232            elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick");
28233          }
28234          if (inner_scrolling) {
28235            win_height = win.height();
28236            if (height + offset_top > win_height) {
28237              if (!bottomed) {
28238                offset -= delta;
28239                offset = Math.max(win_height - height, offset);
28240                offset = Math.min(offset_top, offset);
28241                if (fixed) {
28242                  elm.css({
28243                    top: offset + "px"
28244                  });
28245                }
28246              }
28247            }
28248          }
28249        } else {
28250          if (scroll > top) {
28251            fixed = true;
28252            css = {
28253              position: "fixed",
28254              top: offset
28255            };
28256            css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px";
28257            elm.css(css).addClass(sticky_class);
28258            if (manual_spacer == null) {
28259              elm.after(spacer);
28260              if (el_float === "left" || el_float === "right") {
28261                spacer.append(elm);
28262              }
28263            }
28264            elm.trigger("sticky_kit:stick");
28265          }
28266        }
28267        if (fixed && enable_bottoming) {
28268          if (will_bottom == null) {
28269            will_bottom = scroll + height + offset > parent_height + parent_top;
28270          }
28271          if (!bottomed && will_bottom) {
28272            bottomed = true;
28273            if (parent.css("position") === "static") {
28274              parent.css({
28275                position: "relative"
28276              });
28277            }
28278            return elm.css({
28279              position: "absolute",
28280              bottom: padding_bottom,
28281              top: "auto"
28282            }).trigger("sticky_kit:bottom");
28283          }
28284        }
28285      };
28286      recalc_and_tick = function() {
28287        recalc();
28288        return tick();
28289      };
28290      detach = function() {
28291        detached = true;
28292        win.off("touchmove", tick);
28293        win.off("scroll", tick);
28294        win.off("resize", recalc_and_tick);
28295        $(document.body).off("sticky_kit:recalc", recalc_and_tick);
28296        elm.off("sticky_kit:detach", detach);
28297        elm.removeData("sticky_kit");
28298        elm.css({
28299          position: "",
28300          bottom: "",
28301          top: "",
28302          width: ""
28303        });
28304        parent.position("position", "");
28305        if (fixed) {
28306          if (manual_spacer == null) {
28307            if (el_float === "left" || el_float === "right") {
28308              elm.insertAfter(spacer);
28309            }
28310            spacer.remove();
28311          }
28312          return elm.removeClass(sticky_class);
28313        }
28314      };
28315      win.on("touchmove", tick);
28316      win.on("scroll", tick);
28317      win.on("resize", recalc_and_tick);
28318      $(document.body).on("sticky_kit:recalc", recalc_and_tick);
28319      elm.on("sticky_kit:detach", detach);
28320      return setTimeout(tick, 0);
28321    };
28322    for (i = 0, len = this.length; i < len; i++) {
28323      elm = this[i];
28324      fn($(elm));
28325    }
28326    return this;
28327  };
28328
28329}).call(this);
28330/* ==========================================================================
28331 * bootstrap-tab-history.js
28332 * Author: Michael Narayan <[email protected]>
28333 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/
28334 * ==========================================================================
28335 * Licensed under the Apache License, Version 2.0 (the "License"); you may
28336 * not use this file except in compliance with the License. You may obtain a
28337 * copy of the License at
28338 *
28339 * http://www.apache.org/licenses/LICENSE-2.0
28340 *
28341 * Unless required by applicable law or agreed to in writing, softw
28341are
28342 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
28343 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
28344 * License for the specific language governing permissions and limitations
28345 * under the License.
28346 * ========================================================================== */
28347
28348/* ========================================================================== */
28349/* JSHint directives                                                          */
28350/*                                                                            */
28351/* global BootstrapTabHistory: true                                           */
28352/*                                                                            */
28353/* global document                                                            */
28354/* global jQuery                                                              */
28355/* global history                                                             */
28356/* global window                                                              */
28357/* ========================================================================== */
28358
28359/**
28360 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history)
28361 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set
28362 * the `data-tab-history` attribute to true (or a string denoting a tab grouping).
28363 *
28364 * See the README for additional information.
28365 *
28366 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes.
28367 */
28368
28369BootstrapTabHistory = {
28370  options: {
28371    /**
28372     * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the
28373     * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true.
28374     *
28375     * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`.
28376     *
28377     * @public
28378     * @type {?number}
28379     */
28380    defaultAnchorYOffset: 0,
28381    /**
28382     * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp.
28383     *
28384     * May be overriden on a per-element basis by the attribute `data-tab-history-changer`.
28385     *
28386     * @public
28387     * @type {string}
28388     */
28389    defaultChanger: 'replace',
28390    /**
28391     * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise,
28392     * `null` is passed as the third parameter to these calls.
28393     *
28394     * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`.
28395     *
28396     * @public
28397     * @type {boolean}
28398     */
28399    defaultUpdateURL: false,
28400    /**
28401     * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page
28402     * load.
28403     *
28404     * @public
28405     * @type {boolean}
28406     */
28407    showTabsBasedOnAnchor: true
28408  }
28409};
28410
28411(function () {
28412  'use strict';
28413
28414  jQuery(function () {
28415    if(history && history.pushState && history.replaceState) {
28416      var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory;
28417
28418      if(bootstrapTabHistory) {
28419        showTabsBasedOnState(bootstrapTabHistory);
28420      } else {
28421        showTabsBasedOnAnchor();
28422      }
28423
28424      backfillHistoryState();
28425
28426      jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab);
28427      jQuery(window).on('popstate', onPopState);
28428    } else {
28429      showTabsBasedOnAnchor();
28430    }
28431  });
28432
28433  /**
28434   * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState.
28435   *
28436   * @type {boolean}
28437   */
28438  var showingTabsBasedOnState = false;
28439
28440  /**
28441   * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper
28442   * `history.back` handling when `data-tab-history-update-url` is true.
28443   */
28444  function backfillHistoryState() {
28445    var newState = null;
28446
28447    jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode
28448      var $activeTabElement = jQuery(this);
28449      var selector = getTabSelector($activeTabElement);
28450
28451      if(selector) {
28452        var tabGroup = getTabGroup($activeTabElement);
28453
28454        if(tabGroup) {
28455          newState = createNewHistoryState(newState || history.state, tabGroup, selector);
28456        }
28457      }
28458    });
28459
28460    if(newState) {
28461      history.replaceState(newState, '', null);
28462    }
28463  }
28464
28465  /**
28466   * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to
28467   * said bootstrapTabHistory attribute.
28468   *
28469   * @param {?object} existingState
28470   * @param {!string} tabGroup
28471   * @param {!string} selector
28472   * @returns {!object}
28473   */
28474  function createNewHistoryState(existingState, tabGroup, selector) {
28475    // Clone history.state and ensure it has a bootstrapTabHistory entry.
28476    var newState = jQuery.extend(true, {}, existingState, {
28477      bootstrapTabHistory: {}
28478    });
28479
28480    newState.bootstrapTabHistory[tabGroup] = selector;
28481
28482    return newState;
28483  }
28484
28485  /**
28486   * @param {jQuery} $tab
28487   * @returns {?string}
28488   */
28489  function getTabGroup($tab) {
28490    return parseTruthyAttributeValue($tab.data('tab-history'));
28491  }
28492
28493  /**
28494   * @param {jQuery} $tab
28495   * @returns {?string}
28496   */
28497  function getTabSelector($tab) {
28498    return $tab.data('target') || $tab.attr('href');
28499  }
28500
28501  /**
28502   * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate.
28503   *
28504   * @param {jQuery.Event} shownEvt
28505   */
28506  function onShownTab(shownEvt) {
28507    if(!showingTabsBasedOnState) {
28508      var $activatedTab = jQuery(shownEvt.target);
28509      if ( $activatedTab.hasClass('panel-collapse') )
28510        $activatedTab = $activatedTab.closest('.panel').find('a');
28511      var selector = getTabSelector($activatedTab);
28512
28513      if(selector) {
28514        var tabGroup = getTabGroup($activatedTab);
28515
28516        if(tabGroup) {
28517          var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger;
28518          var newState = createNewHistoryState(history.state, tabGroup, selector);
28519          var updateURL = (function ($activatedTab) {
28520            if(selector[0] === '#') {
28521              var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url'));
28522
28523              if(elementUpdateURLOption === undefined) {
28524                return BootstrapTabHistory.options.defaultUpdateURL;
28525              } else {
28526                return elementUpdateURLOption;
28527              }
28528            } else {
28529              return false;
28530            }
28531          })($activatedTab);
28532
28533          switch(historyChanger) {
28534            case 'push':
28535              history.pushState(newState, '', updateURL ? selector : null);
28536              break;
28537            case 'replace':
28538              history.replaceState(newState, '', updateURL ? selector : null);
28539              break;
28540            default:
28541              throw new Error('Unknown tab-history-changer: ' + historyChanger);
28542          }
28543        }
28544      }
28545    }
28546  }
28547
28548  /**
28549   * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate.
28550   */
28551  function onPopState() {
28552    var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory;
28553
28554    if(bootstrapTabHistory) {
28555      showTabsBasedOnState(bootstrapTabHistory);
28556    }
28557  }
28558
28559  /**
28560   * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned.
28561   *
28562   * Rationale: HAML data attributes which are set to `true` are rendered as a blank string.
28563   *
28564   * @param {*} value
28565   * @returns {*}
28566   */
28567  function parseTruthyAttributeValue(value) {
28568    if(value) {
28569      return value;
28570    } else if(value === '') {
28571      return true;
28572    } else {
28573      return value;
28574    }
28575  }
28576
28577  /**
28578   * Show tabs based upon the anchor component of `window.location`.
28579   */
28580  function showTabsBasedOnAnchor() {
28581    if(BootstrapTabHistory.options.showTabsBasedOnAnchor) {
28582      var anchor = window.location && window.location.hash;
28583
28584      if(anchor) {
28585        var $tabElement = showTabForSelector(anchor);
28586
28587        if($tabElement && window.addEventListener && window.removeEventListener) {
28588          var anchorYOffset = (function ($tabElement) {
28589            var elementSetting = $tabElement.data('tab-history-anchor-y-offset');
28590
28591            if(elementSetting === undefined) {
28592              return BootstrapTabHistory.options.defaultAnchorYOffset;
28593            } else {
28594              return elementSetting;
28595            }
28596          })($tabElement);
28597
28598          // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get
28599          //   here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the
28600          //   `history.state` object should have been used (unless the browser did not support the modern History API).
28601          if(anchorYOffset || anchorYOffset === 0) {
28602            var scrollListener = function resetAnchorScroll () {
28603              window.removeEventListener('scroll', scrollListener);
28604              window.scrollTo(0, anchorYOffset);
28605            };
28606
28607            window.addEventListener('scroll', scrollListener);
28608          }
28609        }
28610      }
28611    }
28612  }
28613
28614  /**
28615   * Show a tab which corresponds to the provided selector.
28616   *
28617   * @param {string} selector - A CSS selector.
28618   * @returns {?jQuery} - The tab which was found to show (even if said tab was already active).
28619   */
28620  function showTabForSelector(selector) {
28621    var $tabElement = (function (selector) {
28622      var $ret = null;
28623
28624      jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () {
28625        var $potentialTab = jQuery(this);
28626
28627        if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) {
28628          $ret = $potentialTab;
28629          return false;
vendor: 43,483 bytes, lines 28630-29846
28630        } else {
28631         return null;
28632        }
28633      });
28634
28635      return $ret;
28636    })(selector);
28637
28638    if($tabElement) {
28639      if ( !$tabElement.parent().hasClass('active') ) {
28640        $tabElement.trigger('click');
28641      }
28642      //$tabElement.tab('show');
28643    }
28644
28645    return $tabElement;
28646  }
28647
28648  /**
28649   * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors.
28650   *
28651   * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant.
28652   */
28653  function showTabsBasedOnState(bootstrapTabHistory) {
28654    showingTabsBasedOnState = true;
28655
28656    try {
28657      for(var k in bootstrapTabHistory) {
28658        if(bootstrapTabHistory.hasOwnProperty(k)) {
28659          showTabForSelector(bootstrapTabHistory[k]);
28660        }
28661      }
28662    } finally {
28663      showingTabsBasedOnState = false;
28664    }
28665  }
28666})();
28667
28668/*!
28669 * justifiedGallery - v3.8.1
28670 * http://miromannino.github.io/Justified-Gallery/
28671 * Copyright (c) 2020 Miro Mannino
28672 * Licensed under the MIT license.
28673 */
28674(function (factory) {
28675  if (typeof define === 'function' && define.amd) {
28676    // AMD. Register as an anonymous module.
28677    define(['jquery'], factory);
28678  } else if (typeof module === 'object' && module.exports) {
28679    // Node/CommonJS
28680    module.exports = function (root, jQuery) {
28681      if (jQuery === undefined) {
28682        // require('jQuery') returns a factory that requires window to
28683        // build a jQuery instance, we normalize how we use modules
28684        // that require this pattern but the window provided is a noop
28685        // if it's defined (how jquery works)
28686        if (typeof window !== 'undefined') {
28687          jQuery = require('jquery');
28688        }
28689        else {
28690          jQuery = require('jquery')(root);
28691        }
28692      }
28693      factory(jQuery);
28694      return jQuery;
28695    };
28696  } else {
28697    // Browser globals
28698    factory(jQuery);
28699  }
28700}(function ($) {
28701
28702  /**
28703   * Justified Gallery controller constructor
28704   *
28705   * @param $gallery the gallery to build
28706   * @param settings the settings (the defaults are in JustifiedGallery.defaults)
28707   * @constructor
28708   */
28709  var JustifiedGallery = function ($gallery, settings) {
28710
28711    this.settings = settings;
28712    this.checkSettings();
28713
28714    this.imgAnalyzerTimeout = null;
28715    this.entries = null;
28716    this.buildingRow = {
28717      entriesBuff: [],
28718      width: 0,
28719      height: 0,
28720      aspectRatio: 0
28721    };
28722    this.lastFetchedEntry = null;
28723    this.lastAnalyzedIndex = -1;
28724    this.yield = {
28725      every: 2, // do a flush every n flushes (must be greater than 1)
28726      flushed: 0 // flushed rows without a yield
28727    };
28728    this.border = settings.border >= 0 ? settings.border : settings.margins;
28729    this.maxRowHeight = this.retrieveMaxRowHeight();
28730    this.suffixRanges = this.retrieveSuffixRanges();
28731    this.offY = this.border;
28732    this.rows = 0;
28733    this.spinner = {
28734      phase: 0,
28735      timeSlot: 150,
28736      $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'),
28737      intervalId: null
28738    };
28739    this.scrollBarOn = false;
28740    this.checkWidthIntervalId = null;
28741    this.galleryWidth = $gallery.width();
28742    this.$gallery = $gallery;
28743
28744  };
28745
28746  /** @returns {String} the best suffix given the width and the height */
28747  JustifiedGallery.prototype.getSuffix = function (width, height) {
28748    var longestSide, i;
28749    longestSide = (width > height) ? width : height;
28750    for (i = 0; i < this.suffixRanges.length; i++) {
28751      if (longestSide <= this.suffixRanges[i]) {
28752        return this.settings.sizeRangeSuffixes[this.suffixRanges[i]];
28753      }
28754    }
28755    return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]];
28756  };
28757
28758  /**
28759   * Remove the suffix from the string
28760   *
28761   * @returns {string} a new string without the suffix
28762   */
28763  JustifiedGallery.prototype.removeSuffix = function (str, suffix) {
28764    return str.substring(0, str.length - suffix.length);
28765  };
28766
28767  /**
28768   * @returns {boolean} a boolean to say if the suffix is contained in the str or not
28769   */
28770  JustifiedGallery.prototype.endsWith = function (str, suffix) {
28771    return str.indexOf(suffix, str.length - suffix.length) !== -1;
28772  };
28773
28774  /**
28775   * Get the used suffix of a particular url
28776   *
28777   * @param str
28778   * @returns {String} return the used suffix
28779   */
28780  JustifiedGallery.prototype.getUsedSuffix = function (str) {
28781    for (var si in this.settings.sizeRangeSuffixes) {
28782      if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) {
28783        if (this.settings.sizeRangeSuffixes[si].length === 0) continue;
28784        if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si];
28785      }
28786    }
28787    return '';
28788  };
28789
28790  /**
28791   * Given an image src, with the width and the height, returns the new image src with the
28792   * best suffix to show the best quality thumbnail.
28793   *
28794   * @returns {String} the suffix to use
28795   */
28796  JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) {
28797    var newImageSrc;
28798
28799    if (this.settings.thumbnailPath) {
28800      newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image);
28801    } else {
28802      var matchRes = imageSrc.match(this.settings.extension);
28803      var ext = (matchRes !== null) ? matchRes[0] : '';
28804      newImageSrc = imageSrc.replace(this.settings.extension, '');
28805      newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc));
28806      newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext;
28807    }
28808
28809    return newImageSrc;
28810  };
28811
28812  /**
28813   * Shows the images that is in the given entry
28814   *
28815   * @param $entry the entry
28816   * @param callback the callback that is called when the show animation is finished
28817   */
28818  JustifiedGallery.prototype.showImg = function ($entry, callback) {
28819    if (this.settings.cssAnimation) {
28820      $entry.addClass('jg-entry-visible');
28821      if (callback) callback();
28822    } else {
28823      $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
28824      $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
28825    }
28826  };
28827
28828  /**
28829   * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the
28830   * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src.
28831   *
28832   * @param $image the image to analyze
28833   * @returns {String} the extracted src
28834   */
28835  JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) {
28836    var imageSrc = $image.data('safe-src');
28837    var imageSrcLoc = 'data-safe-src';
28838    // Begin Uncode edit
28839    if (typeof imageSrc === 'undefined') {
28840    	var imageCurrentSrc = $image[0].currentSrc;
28841    	if (imageCurrentSrc) {
28842    		imageSrc = imageCurrentSrc;
28843    	} else {
28844    		imageSrc = $image.attr('src');
28845    	}
28846		imageSrcLoc = 'src';
28847    }
28848    // End Uncode edit
28849    $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method
28850    $image.data('jg.src', imageSrc); // this will change overtime
28851    $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method
28852    return imageSrc;
28853  };
28854
28855  /** @returns {jQuery} the image in the given entry */
28856  JustifiedGallery.prototype.imgFromEntry = function ($entry) {
28857    var $img = $entry.find(this.settings.imgSelector);
28858    if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode
28859    return $img.length === 0 ? null : $img;
28860  };
28861
28862  /** @returns {jQuery} the caption in the given entry */
28863  JustifiedGallery.prototype.captionFromEntry = function ($entry) {
28864    var $caption = $entry.find('> .jg-caption');
28865    return $caption.length === 0 ? null : $caption;
28866  };
28867
28868  /**
28869   * Display the entry
28870   *
28871   * @param {jQuery} $entry the entry to display
28872   * @param {int} x the x position where the entry must be positioned
28873   * @param y the y position where the entry must be positioned
28874   * @param imgWidth the image width
28875   * @param imgHeight the image height
28876   * @param rowHeight the row height of the row that owns the entry
28877   */
28878  JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) {
28879    $entry.width(imgWidth);
28880    $entry.height(Math.floor(rowHeight));//hacked by Uncode
28881    $entry.css('top', Math.floor(y));//hacked by Uncode
28882    $entry.css('left', x);
28883
28884    var $image = this.imgFromEntry($entry);
28885    if ($image !== null) {
28886      $image.css('width', imgWidth);
28887      $image.css('height', imgHeight);
28888      $image.css('margin-left', - imgWidth / 2);
28889      $image.css('margin-top', - imgHeight / 2);
28890
28891      // Image reloading for an high quality of thumbnails
28892      var imageSrc = $image.data('jg.src');
28893      if (imageSrc) {
28894        imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]);
28895
28896        $image.one('error', function () {
28897           this.resetImgSrc($image); //revert to the original thumbnail
28898        });
28899
28900        var loadNewImage = function () {
28901          // if (imageSrc !== newImageSrc) {
28902            $image.attr('src', imageSrc);
28903          // }
28904        };
28905
28906        if ($entry.data('jg.loaded') === 'skipped' && imageSrc) {
28907          this.onImageEvent(imageSrc, (function() {
28908            this.showImg($entry, loadNewImage); //load the new image after the fadeIn
28909            $entry.data('jg.loaded', true);
28910          }).bind(this));
28911        } else {
28912          this.showImg($entry, loadNewImage); //load the new image after the fadeIn
28913        }
28914
28915      }
28916
28917    } else {
28918      this.showImg($entry);
28919    }
28920
28921    this.displayEntryCaption($entry);
28922  };
28923
28924  /**
28925   * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt'
28926   * or the 'title' attributes.
28927   *
28928   * @param {jQuery} $entry the entry to process
28929   */
28930  JustifiedGallery.prototype.displayEntryCaption = function ($entry) {
28931    var $image = this.imgFromEntry($entry);
28932    if ($image !== null && this.settings.captions) {
28933      var $imgCaption = this.captionFromEntry($entry);
28934
28935      // Create it if it doesn't exists
28936      if ($imgCaption === null) {
28937        var caption = $image.attr('alt');
28938        if (!this.isValidCaption(caption)) caption = $entry.attr('title');
28939        if (this.isValidCaption(caption)) { // Create only we found something
28940          $imgCaption = $('<div class="jg-caption">' + caption + '</div>');
28941          $entry.append($imgCaption);
28942          $entry.data('jg.createdCaption', true);
28943        }
28944      }
28945
28946      // Create events (we check again the $imgCaption because it can be still inexistent)
28947      if ($imgCaption !== null) {
28948        if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity);
28949        this.addCaptionEventsHandlers($entry);
28950      }
28951    } else {
28952      this.removeCaptionEventsHandlers($entry);
28953    }
28954  };
28955
28956  /**
28957   * Validates the caption
28958   *
28959   * @param caption The caption that should be validated
28960   * @return {boolean} Validation result
28961   */
28962  JustifiedGallery.prototype.isValidCaption = function (caption) {
28963    return (typeof caption !== 'undefined' && caption.length > 0);
28964  };
28965
28966  /**
28967   * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry.
28968   * It shows the caption using jQuery (or using CSS if it is configured so)
28969   *
28970   * @param {Event} eventObject the event object
28971   */
28972  JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) {
28973    var $caption = this.captionFromEntry($(eventObject.currentTarget));
28974    if (this.settings.cssAnimation) {
28975      $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden');
28976    } else {
28977      $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
28978        this.settings.captionSettings.visibleOpacity);
28979    }
28980  };
28981
28982  /**
28983   * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry.
28984   * It hides the caption using jQuery (or using CSS if it is configured so)
28985   *
28986   * @param {Event} eventObject the event object
28987   */
28988  JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) {
28989    var $caption = this.captionFromEntry($(eventObject.currentTarget));
28990    if (this.settings.cssAnimation) {
28991      $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden');
28992    } else {
28993      $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
28994        this.settings.captionSettings.nonVisibleOpacity);
28995    }
28996  };
28997
28998  /**
28999   * Add the handlers of the entry for the caption
29000   *
29001   * @param $entry the entry to modify
29002   */
29003  JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) {
29004    var captionMouseEvents = $entry.data('jg.captionMouseEvents');
29005    if (typeof captionMouseEvents === 'undefined') {
29006      captionMouseEvents = {
29007        mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this),
29008        mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this)
29009      };
29010      $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter);
29011      $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave);
29012      $entry.data('jg.captionMouseEvents', captionMouseEvents);
29013    }
29014  };
29015
29016  /**
29017   * Remove the handlers of the entry for the caption
29018   *
29019   * @param $entry the entry to modify
29020   */
29021  JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) {
29022    var captionMouseEvents = $entry.data('jg.captionMouseEvents');
29023    if (typeof captionMouseEvents !== 'undefined') {
29024      $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter);
29025      $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave);
29026      $entry.removeData('jg.captionMouseEvents');
29027    }
29028  };
29029
29030  /**
29031   * Clear the building row data to be used for a new row
29032   */
29033  JustifiedGallery.prototype.clearBuildingRow = function () {
29034    this.buildingRow.entriesBuff = [];
29035    this.buildingRow.aspectRatio = 0;
29036    this.buildingRow.width = 0;
29037  };
29038
29039  /**
29040   * Justify the building row, preparing it to
29041   *
29042   * @param isLastRow
29043   * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row.
29044   * @returns a boolean to know if the row has been justified or not
29045   */
29046  JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) {
29047    var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true;
29048    var minHeight = 0;
29049    var availableWidth = this.galleryWidth - 2 * this.border - (
29050      (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
29051    var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode
29052    var defaultRowHeight = this.settings.rowHeight;
29053    var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold;
29054
29055    //Skip the last row if we can't justify it and the lastRow == 'hide'
29056    if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) {
29057      for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29058        $entry = this.buildingRow.entriesBuff[i];
29059        if (this.settings.cssAnimation)
29060          $entry.removeClass('jg-entry-visible');
29061        else {
29062          $entry.stop().fadeTo(0, 0.1);
29063          $entry.find('> img, > a > img').fadeTo(0, 0);
29064        }
29065      }
29066      return -1;
29067    }
29068
29069    // With lastRow = nojustify, justify if is justificable (the images will not become too big)
29070    if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') {
29071      justify = false;
29072
29073      if (this.rows > 0) {
29074        defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows;
29075        justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold;
29076      }
29077    }
29078
29079    for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29080      $entry = this.buildingRow.entriesBuff[i];
29081      imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
29082
29083      if (justify) {
29084        newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio;
29085        newImgH = rowHeight;
29086      } else {
29087        newImgW = defaultRowHeight * imgAspectRatio;
29088        newImgH = defaultRowHeight;
29089      }
29090
29091      availableWidth -= Math.round(newImgW);
29092      $entry.data('jg.jwidth', Math.round(newImgW));
29093      $entry.data('jg.jheight', Math.ceil(newImgH));
29094      if (i === 0 || minHeight > newImgH) minHeight = newImgH;
29095    }
29096
29097    this.buildingRow.height = minHeight;
29098    return justify;
29099  };
29100
29101  /**
29102   * Flush a row: justify it, modify the gallery height accordingly to the row height
29103   *
29104   * @param isLastRow
29105   * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row.
29106   */
29107  JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) {
29108    var settings = this.settings;
29109    var $entry, buildingRowRes, offX = this.border, i;
29110
29111    buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow);
29112    if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) {
29113      this.clearBuildingRow();
29114      return;
29115    }
29116
29117    if (this.maxRowHeight) {
29118      if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight;
29119    }
29120
29121    //Align last (unjustified) row
29122    if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) {
29123      var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins;
29124
29125      for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29126        $entry = this.buildingRow.entriesBuff[i];
29127        availableWidth -= $entry.data('jg.jwidth');
29128      }
29129
29130      if (settings.lastRow === 'center')
29131        offX += Math.round(availableWidth / 2);
29132      else if (settings.lastRow === 'right')
29133        offX += availableWidth;
29134    }
29135
29136    var lastEntryIdx = this.buildingRow.entriesBuff.length - 1;
29137    for (i = 0; i <= lastEntryIdx; i++) {
29138      $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i];
29139      this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height);
29140      offX += $entry.data('jg.jwidth') + settings.margins;
29141    }
29142
29143    //Gallery Height
29144    this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border;
29145    this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight());
29146
29147    if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) {
29148      //Ready for a new row
29149      this.offY += this.buildingRow.height + settings.margins;
29150      this.rows += 1;
29151      this.clearBuildingRow();
29152      this.settings.triggerEvent.call(this, 'jg.rowflush');
29153    }
29154  };
29155
29156
29157  // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221
29158  var galleryPrevStaticHeight = 0;
29159
29160  JustifiedGallery.prototype.rememberGalleryHeight = function () {
29161    galleryPrevStaticHeight = this.$gallery.height();
29162    this.$gallery.height(galleryPrevStaticHeight);
29163  };
29164
29165  // grow only
29166  JustifiedGallery.prototype.setGalleryTempHeight = function (height) {
29167    galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight);
29168    this.$gallery.height(galleryPrevStaticHeight);
29169  };
29170
29171  JustifiedGallery.prototype.setGalleryFinalHeight = function (height) {
29172    galleryPrevStaticHeight = height;
29173    this.$gallery.height(height);
29174  };
29175
29176  /**
29177   * Checks the width of the gallery container, to know if a new justification is needed
29178   */
29179  JustifiedGallery.prototype.checkWidth = function () {
29180    this.checkWidthIntervalId = setInterval($.proxy(function () {
29181
29182      // if the gallery is not currently visible, abort.
29183      if (!this.$gallery.is(":visible")) return;
29184
29185      var galleryWidth = parseFloat(this.$gallery.width());
29186      if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) {
29187        this.galleryWidth = galleryWidth;
29188        this.rewind();
29189
29190        this.rememberGalleryHeight();
29191
29192        // Restart to analyze
29193        this.startImgAnalyzer(true);
29194      }
29195    }, this), this.settings.refreshTime);
29196  };
29197
29198  /**
29199   * @returns {boolean} a boolean saying if the spinner is active or not
29200   */
29201  JustifiedGallery.prototype.isSpinnerActive = function () {
29202    return this.spinner.intervalId !== null;
29203  };
29204
29205  /**
29206   * @returns {int} the spinner height
29207   */
29208  JustifiedGallery.prototype.getSpinnerHeight = function () {
29209    return this.spinner.$el.innerHeight();
29210  };
29211
29212  /**
29213   * Stops the spinner animation and modify the gallery height to exclude the spinner
29214   */
29215  JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () {
29216    clearInterval(this.spinner.intervalId);
29217    this.spinner.intervalId = null;
29218    this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight());
29219    this.spinner.$el.detach();
29220  };
29221
29222  /**
29223   * Starts the spinner animation
29224   */
29225  JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () {
29226    var spinnerContext = this.spinner;
29227    var $spinnerPoints = spinnerContext.$el.find('span');
29228    clearInterval(spinnerContext.intervalId);
29229    this.$gallery.append(spinnerContext.$el);
29230    this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight());
29231    spinnerContext.intervalId = setInterval(function () {
29232      if (spinnerContext.phase < $spinnerPoints.length) {
29233        $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1);
29234      } else {
29235        $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0);
29236      }
29237      spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2);
29238    }, spinnerContext.timeSlot);
29239  };
29240
29241  /**
29242   * Rewind the image analysis to start from the first entry.
29243   */
29244  JustifiedGallery.prototype.rewind = function () {
29245    this.lastFetchedEntry = null;
29246    this.lastAnalyzedIndex = -1;
29247    this.offY = this.border;
29248    this.rows = 0;
29249    this.clearBuildingRow();
29250  };
29251
29252  /**
29253   * @returns {String} `settings.selector` rejecting spinner element
29254   */
29255  JustifiedGallery.prototype.getSelectorWithoutSpinner = function () {
29256    return this.settings.selector + ', div:not(.jg-spinner)';
29257  };
29258
29259  /**
29260   * @returns {Array} all entries matched by `settings.selector`
29261   */
29262  JustifiedGallery.prototype.getAllEntries = function () {
29263    var selector = this.getSelectorWithoutSpinner();
29264    return this.$gallery.children(selector).toArray();
29265  };
29266
29267  /**
29268   * Update the entries searching it from the justified gallery HTML element
29269   *
29270   * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered)
29271   * @returns {boolean} true if some entries has been founded
29272   */
29273  JustifiedGallery.prototype.updateEntries = function (norewind) {
29274    var newEntries;
29275
29276    if (norewind && this.lastFetchedEntry != null) {
29277      var selector = this.getSelectorWithoutSpinner();
29278      newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray();
29279    } else {
29280      this.entries = [];
29281      newEntries = this.getAllEntries();
29282    }
29283
29284    if (newEntries.length > 0) {
29285
29286      // Sort or randomize
29287      if ($.isFunction(this.settings.sort)) {
29288        newEntries = this.sortArray(newEntries);
29289      } else if (this.settings.randomize) {
29290        newEntries = this.shuffleArray(newEntries);
29291      }
29292      this.lastFetchedEntry = newEntries[newEntries.length - 1];
29293
29294      // Filter
29295      if (this.settings.filter) {
29296        newEntries = this.filterArray(newEntries);
29297      } else {
29298        this.resetFilters(newEntries);
29299      }
29300
29301    }
29302
29303    this.entries = this.entries.concat(newEntries);
29304    return true;
29305  };
29306
29307  /**
29308   * Apply the entries order to the DOM, iterating the entries and appending the images
29309   *
29310   * @param entries the entries that has been modified and that must be re-ordered in the DOM
29311   */
29312  JustifiedGallery.prototype.insertToGallery = function (entries) {
29313    var that = this;
29314    $.each(entries, function () {
29315      $(this).appendTo(that.$gallery);
29316    });
29317  };
29318
29319  /**
29320   * Shuffle the array using the Fisher-Yates shuffle algorithm
29321   *
29322   * @param a the array to shuffle
29323   * @return the shuffled array
29324   */
29325  JustifiedGallery.prototype.shuffleArray = function (a) {
29326    var i, j, temp;
29327    for (i = a.length - 1; i > 0; i--) {
29328      j = Math.floor(Math.random() * (i + 1));
29329      temp = a[i];
29330      a[i] = a[j];
29331      a[j] = temp;
29332    }
29333    this.insertToGallery(a);
29334    return a;
29335  };
29336
29337  /**
29338   * Sort the array using settings.comparator as comparator
29339   *
29340   * @param a the array to sort (it is sorted)
29341   * @return the sorted array
29342   */
29343  JustifiedGallery.prototype.sortArray = function (a) {
29344    a.sort(this.settings.sort);
29345    this.insertToGallery(a);
29346    return a;
29347  };
29348
29349  /**
29350   * Reset the filters removing the 'jg-filtered' class from all the entries
29351   *
29352   * @param a the array to reset
29353   */
29354  JustifiedGallery.prototype.resetFilters = function (a) {
29355    for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered');
29356  };
29357
29358  /**
29359   * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering.
29360   *
29361   * @param a the array to filter
29362   * @return the filtered array
29363   */
29364  JustifiedGallery.prototype.filterArray = function (a) {
29365    var settings = this.settings;
29366    if ($.type(settings.filter) === 'string') {
29367      // Filter only keeping the entries passed in the string
29368      return a.filter(function (el) {
29369        var $el = $(el);
29370        if ($el.is(settings.filter)) {
29371          $el.removeClass('jg-filtered');
29372          return true;
29373        } else {
29374          $el.addClass('jg-filtered').removeClass('jg-visible');
29375          return false;
29376        }
29377      });
29378    } else if ($.isFunction(settings.filter)) {
29379      // Filter using the passed function
29380      var filteredArr = a.filter(settings.filter);
29381      for (var i = 0; i < a.length; i++) {
29382        if (filteredArr.indexOf(a[i]) === -1) {
29383          $(a[i]).addClass('jg-filtered').removeClass('jg-visible');
29384        } else {
29385          $(a[i]).removeClass('jg-filtered');
29386        }
29387      }
29388      return filteredArr;
29389    }
29390  };
29391
29392  /**
29393   * Revert the image src to the default value.
29394   */
29395  JustifiedGallery.prototype.resetImgSrc = function ($img) {
29396    if ($img.data('jg.originalSrcLoc') === 'src') {
29397      $img.attr('src', $img.data('jg.originalSrc'));
29398    } else {
29399      $img.attr('src', '');
29400    }
29401  };
29402
29403  /**
29404   * Destroy the Justified Gallery instance.
29405   *
29406   * It clears all the css properties added in the style attributes. We doesn't backup the original
29407   * values for those css attributes, because it costs (performance) and because in general one
29408   * shouldn't use the style attribute for an uniform set of images (where we suppose the use of
29409   * classes). Creating a backup is also difficult because JG could be called multiple times and
29410   * with different style attributes.
29411   */
29412  JustifiedGallery.prototype.destroy = function () {
29413    clearInterval(this.checkWidthIntervalId);
29414    this.stopImgAnalyzerStarter();
29415
29416    // Get fresh entries list since filtered entries are absent in `this.entries`
29417    $.each(this.getAllEntries(), $.proxy(function (_, entry) {
29418      var $entry = $(entry);
29419
29420      // Reset entry style
29421      $entry.css('width', '');
29422      $entry.css('height', '');
29423      $entry.css('top', '');
29424      $entry.css('left', '');
29425      $entry.data('jg.loaded', undefined);
29426      $entry.removeClass('jg-entry jg-filtered jg-entry-visible');
29427
29428      // Reset image style
29429      var $img = this.imgFromEntry($entry);
29430      if ($img) {
29431        $img.css('width', '');
29432        $img.css('height', '');
29433        $img.css('margin-left', '');
29434        $img.css('margin-top', '');
29435        this.resetImgSrc($img);
29436        $img.data('jg.originalSrc', undefined);
29437        $img.data('jg.originalSrcLoc', undefined);
29438        $img.data('jg.src', undefined);
29439      }
29440
29441      // Remove caption
29442      this.removeCaptionEventsHandlers($entry);
29443      var $caption = this.captionFromEntry($entry);
29444      if ($entry.data('jg.createdCaption')) {
29445        // remove also the caption element (if created by jg)
29446        $entry.data('jg.createdCaption', undefined);
29447        if ($caption !== null) $caption.remove();
29448      } else {
29449        if ($caption !== null) $caption.fadeTo(0, 1);
29450      }
29451
29452    }, this));
29453
29454    this.$gallery.css('height', '');
29455    this.$gallery.removeClass('justified-gallery');
29456    this.$gallery.data('jg.controller', undefined);
29457    this.settings.triggerEvent.call(this, 'jg.destroy');
29458  };
29459
29460  /**
29461   * Analyze the images and builds the rows. It returns if it found an image that is not loaded.
29462   *
29463   * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end
29464   */
29465  JustifiedGallery.prototype.analyzeImages = function (isForResize) {
29466    for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) {
29467      var $entry = $(this.entries[i]);
29468      if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') {
29469        var availableWidth = this.galleryWidth - 2 * this.border - (
29470          (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
29471        var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
29472
29473        this.buildingRow.entriesBuff.push($entry);
29474        this.buildingRow.aspectRatio += imgAspectRatio;
29475        this.buildingRow.width += imgAspectRatio * this.settings.rowHeight;
29476        this.lastAnalyzedIndex = i;
29477
29478        if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) {
29479          this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount);
29480
29481          if (++this.yield.flushed >= this.yield.every) {
29482            this.startImgAnalyzer(isForResize);
29483            return;
29484          }
29485        }
29486      } else if ($entry.data('jg.loaded') !== 'error') {
29487        return;
29488      }
29489    }
29490
29491    // Last row flush (the row is not full)
29492    if (this.buildingRow.entriesBuff.length > 0) {
29493      this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount);
29494    }
29495
29496    if (this.isSpinnerActive()) {
29497      this.stopLoadingSpinnerAnimation();
29498    }
29499
29500    /* Stop, if there is, the timeout to start the analyzeImages.
29501     This is because an image can be set loaded, and the timeout can be set,
29502     but this image can be analyzed yet.
29503     */
29504    this.stopImgAnalyzerStarter();
29505
29506    this.setGalleryFinalHeight(this.galleryHeightToSet);
29507
29508    //On complete callback
29509    this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete');
29510  };
29511
29512  /**
29513   * Stops any ImgAnalyzer starter (that has an assigned timeout)
29514   */
29515  JustifiedGallery.prototype.stopImgAnalyzerStarter = function () {
29516    this.yield.flushed = 0;
29517    if (this.imgAnalyzerTimeout !== null) {
29518      clearTimeout(this.imgAnalyzerTimeout);
29519      this.imgAnalyzerTimeout = null;
29520    }
29521  };
29522
29523  /**
29524   * Starts the image analyzer. It is not immediately called to let the browser to update the view
29525   *
29526   * @param isForResize specifies if the image analyzer must be called for resizing or not
29527   */
29528  JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) {
29529    var that = this;
29530    this.stopImgAnalyzerStarter();
29531    this.imgAnalyzerTimeout = setTimeout(function () {
29532      that.analyzeImages(isForResize);
29533    }, 0.001); // we can't start it immediately due to a IE different behaviour
29534  };
29535
29536  /**
29537   * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property,
29538   * because some browsers, with a 404 set complete = true.
29539   *
29540   * @param imageSrc the image src to load
29541   * @param onLoad callback that is called when the image has been loaded
29542   * @param onError callback that is called in case of an error
29543   */
29544  JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) {
29545    if (!onLoad && !onError) return;
29546
29547    var memImage = new Image();
29548    var $memImage = $(memImage);
29549    if (onLoad) {
29550      $memImage.one('load', function () {
29551        $memImage.off('load error');
29552        onLoad(memImage);
29553      });
29554    }
29555    if (onError) {
29556      $memImage.one('error', function () {
29557        $memImage.off('load error');
29558        onError(memImage);
29559      });
29560    }
29561    memImage.src = imageSrc;
29562  };
29563
29564  /**
29565   * Init of Justified Gallery controlled
29566   * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images)
29567   */
29568  JustifiedGallery.prototype.init = function () {
29569    var imagesToLoad = false, skippedImages = false, that = this;
29570    $.each(this.entries, function (index, entry) {
29571      var $entry = $(entry);
29572      var $image = that.imgFromEntry($entry);
29573
29574      $entry.addClass('jg-entry');
29575
29576      if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') {
29577
29578        // Link Rel global overwrite
29579        if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel);
29580
29581        // Link Target global overwrite
29582        if (that.settings.target !== null) $entry.attr('target', that.settings.target);
29583
29584        if ($image !== null) {
29585
29586          // Image src
29587          var imageSrc = that.extractImgSrcFromImage($image);
29588
29589          /* If we have the height and the width, we don't wait that the image is loaded,
29590             but we start directly with the justification */
29591          if (that.settings.waitThumbnailsLoad === false || !imageSrc) {
29592            var width = parseFloat($image.attr('width'));
29593            var height = parseFloat($image.attr('height'));
29594            if ($image.prop('tagName') === 'svg') {
29595              width = parseFloat($image[0].getBBox().width);
29596              height = parseFloat($image[0].getBBox().height);
29597            }
29598            if (!isNaN(width) && !isNaN(height)) {
29599              $entry.data('jg.width', width);
29600              $entry.data('jg.height', height);
29601              $entry.data('jg.loaded', 'skipped');
29602              skippedImages = true;
29603              that.startImgAnalyzer(false);
29604              return true; // continue
29605            }
29606          }
29607
29608          $entry.data('jg.loaded', false);
29609          imagesToLoad = true;
29610
29611          // Spinner start
29612          if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation();
29613
29614          that.onImageEvent(imageSrc, function (loadImg) { // image loaded
29615            $entry.data('jg.width', loadImg.width);
29616            $entry.data('jg.height', loadImg.height);
29617            $entry.data('jg.loaded', true);
29618            that.startImgAnalyzer(false);
29619          }, function () { // image load error
29620            $entry.data('jg.loaded', 'error');
29621            that.startImgAnalyzer(false);
29622          });
29623
29624        } else {
29625          $entry.data('jg.loaded', true);
29626          $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1);
29627          $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1);
29628        }
29629
29630      }
29631
29632    });
29633
29634    if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false);
29635    this.checkWidth();
29636  };
29637
29638  /**
29639   * Checks that it is a valid number. If a string is passed it is converted to a number
29640   *
29641   * @param settingContainer the object that contains the setting (to allow the conversion)
29642   * @param settingName the setting name
29643   */
29644  JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) {
29645    if ($.type(settingContainer[settingName]) === 'string') {
29646      settingContainer[settingName] = parseFloat(settingContainer[settingName]);
29647    }
29648
29649    if ($.type(settingContainer[settingName]) === 'number') {
29650      if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName;
29651    } else {
29652      throw settingName + ' must be a number';
29653    }
29654  };
29655
29656  /**
29657   * Checks the sizeRangeSuffixes and, if necessary, converts
29658   * its keys from string (e.g. old settings with 'lt100') to int.
29659   */
29660  JustifiedGallery.prototype.checkSizeRangesSuffixes = function () {
29661    if ($.type(this.settings.sizeRangeSuffixes) !== 'object') {
29662      throw 'sizeRangeSuffixes must be defined and must be an object';
29663    }
29664
29665    var suffixRanges = [];
29666    for (var rangeIdx in this.settings.sizeRangeSuffixes) {
29667      if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx);
29668    }
29669
29670    var newSizeRngSuffixes = { 0: '' };
29671    for (var i = 0; i < suffixRanges.length; i++) {
29672      if ($.type(suffixRanges[i]) === 'string') {
29673        try {
29674          var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10);
29675          newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
29676        } catch (e) {
29677          throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')';
29678        }
29679      } else {
29680        newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
29681      }
29682    }
29683
29684    this.settings.sizeRangeSuffixes = newSizeRngSuffixes;
29685  };
29686
29687  /**
29688   * check and convert the maxRowHeight setting
29689   * requires rowHeight to be already set
29690   * TODO: should be always called when only rowHeight is changed
29691   * @return number or null
29692   */
29693  JustifiedGallery.prototype.retrieveMaxRowHeight = function () {
29694    var newMaxRowHeight = null;
29695    var rowHeight = this.settings.rowHeight;
29696
29697    if ($.type(this.settings.maxRowHeight) === 'string') {
29698      if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) {
29699        newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100;
29700      } else {
29701        newMaxRowHeight = parseFloat(this.settings.maxRowHeight);
29702      }
29703    } else if ($.type(this.settings.maxRowHeight) === 'number') {
29704      newMaxRowHeight = this.settings.maxRowHeight;
29705    } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) {
29706      return null;
29707    } else {
29708      throw 'maxRowHeight must be a number or a percentage';
29709    }
29710
29711    // check if the converted value is not a number
29712    if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight';
29713
29714    // check values, maxRowHeight must be >= rowHeight
29715    if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight;
29716
29717    return newMaxRowHeight;
29718  };
29719
29720  /**
29721   * Checks the settings
29722   */
29723  JustifiedGallery.prototype.checkSettings = function () {
29724    this.checkSizeRangesSuffixes();
29725
29726    this.checkOrConvertNumber(this.settings, 'rowHeight');
29727    this.checkOrConvertNumber(this.settings, 'margins');
29728    this.checkOrConvertNumber(this.settings, 'border');
29729    this.checkOrConvertNumber(this.settings, 'maxRowsCount');
29730
29731    var lastRowModes = [
29732      'justify',
29733      'nojustify',
29734      'left',
29735      'center',
29736      'right',
29737      'hide'
29738    ];
29739    if (lastRowModes.indexOf(this.settings.lastRow) === -1) {
29740      throw 'lastRow must be one of: ' + lastRowModes.join(', ');
29741    }
29742
29743    this.checkOrConvertNumber(this.settings, 'justifyThreshold');
29744    if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) {
29745      throw 'justifyThreshold must be in the interval [0,1]';
29746    }
29747    if ($.type(this.settings.cssAnimation) !== 'boolean') {
29748      throw 'cssAnimation must be a boolean';
29749    }
29750
29751    if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean';
29752    this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration');
29753
29754    this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity');
29755    if (this.settings.captionSettings.visibleOpacity < 0 ||
29756      this.settings.captionSettings.visibleOpacity > 1) {
29757      throw 'captionSettings.visibleOpacity must be in the interval [0, 1]';
29758    }
29759
29760    this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity');
29761    if (this.settings.captionSettings.nonVisibleOpacity < 0 ||
29762      this.settings.captionSettings.nonVisibleOpacity > 1) {
29763      throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]';
29764    }
29765
29766    this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration');
29767    this.checkOrConvertNumber(this.settings, 'refreshTime');
29768    this.checkOrConvertNumber(this.settings, 'refreshSensitivity');
29769    if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean';
29770    if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string';
29771
29772    if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) {
29773      throw 'sort must be false or a comparison function';
29774    }
29775
29776    if (this.settings.filter !== false && !$.isFunction(this.settings.filter) &&
29777      $.type(this.settings.filter) !== 'string') {
29778      throw 'filter must be false, a string or a filter function';
29779    }
29780  };
29781
29782  /**
29783   * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned.
29784   * @returns {Array} sorted suffix ranges
29785   */
29786  JustifiedGallery.prototype.retrieveSuffixRanges = function () {
29787    var suffixRanges = [];
29788    for (var rangeIdx in this.settings.sizeRangeSuffixes) {
29789      if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10));
29790    }
29791    suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; });
29792    return suffixRanges;
29793  };
29794
29795  /**
29796   * Update the existing settings only changing some of them
29797   *
29798   * @param newSettings the new settings (or a subgroup of them)
29799   */
29800  JustifiedGallery.prototype.updateSettings = function (newSettings) {
29801    // In this case Justified Gallery has been called again changing only some options
29802    this.settings = $.extend({}, this.settings, newSettings);
29803    this.checkSettings();
29804
29805    // As reported in the settings: negative value = same as margins, 0 = disabled
29806    this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins;
29807
29808    this.maxRowHeight = this.retrieveMaxRowHeight();
29809    this.suffixRanges = this.retrieveSuffixRanges();
29810  };
29811
29812  JustifiedGallery.prototype.defaults = {
29813    sizeRangeSuffixes: {}, /* e.g. Flickr configuration
29814        {
29815          100: '_t',  // used when longest is less than 100px
29816          240: '_m',  // used when longest is between 101px and 240px
29817          320: '_n',  // ...
29818          500: '',
29819          640: '_z',
29820          1024: '_b'  // used as else case because it is the last
29821        }
29822    */
29823    thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the
29824    path relative to a specific thumbnail size. The function should accept respectively three arguments:
29825    current path, width and height */
29826    rowHeight: 120, // required? required to be > 0?
29827    maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels,
29828    // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height
29829    // can't exceed 3 * rowHeight)
29830    maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled)
29831    margins: 1,
29832    border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border
29833
29834    lastRow: 'nojustify', // … which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide'
29835
29836    justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified
29837                             * (i.e. lastRow setting is not considered) */
29838    waitThumbnailsLoad: true,
29839    captions: true,
29840    cssAnimation: true,
29841    imagesAnimationDuration: 500, // ignored with css animations
29842    captionSettings: { // ignored with css animations
29843      animationDuration: 500,
29844      visibleOpacity: 0.7,
29845      nonVisibleOpacity: 0.0
29846    },
29847    rel: null, // rewrite the rel of each analyzed links
29848    target: null, // rewrite the target of all links
29849    extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image
29850    refreshTime: 200, // time interval (in ms) to check if the page changes its width
29851    refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery
29852    randomize: false,
29853    rtl: false, // right-to-left mode
29854    sort: false, /*
29855      - false: to do not sort
29856      - function: to sort them using the function as comparator (see Array.prototype.sort())
29857    */
29858    filter: false, /*
29859      - false, null or undefined: for a disabled filter
29860      - a string: an entry is kept if entry.is(filter string) returns true
29861                  see jQuery's .is() function for further information
29862      - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise.
29863                    It follows the specifications of the Array.prototype.filter() function of JavaScript.
29864    */
29865    selector: 'a', // The selector that is used to know what are the entries of the gallery
29866    imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry
29867    triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger
29868      this.$gallery.trigger(event);  // Consider that 'this' is this set to the JustifiedGallery object, so it can
29869    }                                // access to fields such as $gallery, useful to trigger events with jQuery.
29870  };
29871
29872
29873  /**
29874   * Justified Gallery plugin for jQuery
29875   *
29876   * Events
29877   *  - jg.complete : called when all the gallery has been created
29878   *  - jg.resize : called when the gallery has been resized
29879   *  - jg.rowflush : when a new row appears
29880   *
29881   * @param arg the action (or the settings) passed when the plugin is called
29882   * @returns {*} the object itself
29883   */
29884  $.fn.justifiedGallery = function (arg) {
29885    return this.each(function (index, gallery) {
29886
29887      var $gallery = $(gallery);
29888      $gallery.addClass('justified-gallery');
29889
29890      var controller = $gallery.data('jg.controller');
29891      if (typeof controller === 'undefined') {
29892        // Create controller and assign it to the object data
29893        if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') {
29894          if (arg === 'destroy') return; // Just a call to an unexisting object
29895          throw 'The argument must be an object';
29896        }
29897        controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg));
29898        $gallery.data('jg.controller', controller);
29899      } else if (arg === 'norewind') {
29900        // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row
29901        // ... left to be more readable
29902      } else if (arg === 'destroy') {
29903        controller.destroy();
29904        return;
29905      } else {
29906        // In this case Justified Gallery has been called again changing only some options
29907        controller.updateSettings(arg);
29908        controller.rewind();
29909      }
29910
29911      // Update the entries list
29912      if (!controller.updateEntries(arg === 'norewind')) return;
29913
29914      // Init justified gallery
29915      controller.init();
29916
29917    });
29918  };
29919
29920}));
29921
29922/*!
29923* Customized version of iScroll.js 0.0.1
29924* It fixes bugs affecting its integration with fullpage.js
29925*/
29926/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */
29927(function (window, document, Math) {
29928var rAF = window.requestAnimationFrame  ||
29929    window.webkitRequestAnimationFrame  ||
29930    window.mozRequestAnimationFrame     ||
29931    window.oRequestAnimationFrame       ||
29932    window.msRequestAnimationFrame      ||
29933    function (callback) { window.setTimeout(callback, 1000 / 60); };
29934
29935var utils = (function () {
29936    var me = {};
29937
29938    var _elementStyle = document.createElement('div').style;
29939    var _vendor = (function () {
29940        var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'],
29941            transform,
29942            i = 0,
29943            l = vendors.length;
29944
29945        for ( ; i < l; i++ ) {
29946            transform = vendors[i] + 'ransform';
29947            if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1);
29948        }
29949
29950        return false;
29951    })();
29952
29953    function _prefixStyle (style) {
29954        if ( _vendor === false ) return false;
29955        if ( _vendor === '' ) return style;
29956        return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
29957    }
29958
29959    me.getTime = Date.now || function getTime () { return new Date().getTime(); };
29960
29961    me.extend = function (target, obj) {
29962        for ( var i in obj ) {
29963            target[i] = obj[i];
29964        }
29965    };
29966
29967    me.addEvent = function (el, type, fn, capture) {
29968        el.addEventListener(type, fn, !!capture);
29969    };
29970
29971    me.removeEvent = function (el, type, fn, capture) {
29972        el.removeEventListener(type, fn, !!capture);
29973    };
29974
29975    me.prefixPointerEvent = function (pointerEvent) {
29976        return window.MSPointerEvent ?
29977            'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8):
29978            pointerEvent;
29979    };
29980
29981    me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
29982        var distance = current - start,
29983            speed = Math.abs(distance) / time,
29984            destination,
29985            duration;
29986
29987        deceleration = deceleration === undefined ? 0.0006 : deceleration;
29988
29989        destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
29990        duration = speed / deceleration;
29991
29992        if ( destination < lowerMargin ) {
29993            destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;
29994            distance = Math.abs(destination - current);
29995            duration = distance / speed;
29996        } else if ( destination > 0 ) {
29997            destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
29998            distance = Math.abs(current) + destination;
29999            duration = distance / speed;
30000        }
30001
30002        return {
30003            destination: Math.round(destination),
30004            duration: duration
30005        };
30006    };
30007
30008    var _transform = _prefixStyle('transform');
30009
30010    me.extend(me, {
30011        hasTransform: _transform !== false,
30012        hasPerspective: _prefixStyle('perspective') in _elementStyle,
30013        hasTouch: 'ontouchstart' in window,
30014        hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
30015        hasTransition: _prefixStyle('transition') in _elementStyle
30016    });
30017
30018    /*
30019    This should find all Android browsers lower than build 535.19 (both stock browser and webview)
30020    - galaxy S2 is ok
30021    - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
30022    - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30023   - galaxy S3 is badAndroid (stock brower, webview)
30024     `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30025   - galaxy S4 is badAndroid (stock brower, webview)
30026     `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30027   - galaxy S5 is OK
30028     `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
30029   - galaxy S6 is OK
30030     `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
30031  */
30032    me.isBadAndroid = (function() {
30033        var appVersion = window.navigator.appVersion;
30034        // Android browser is not a chrome browser.
30035        if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) {
30036            var safariVersion = appVersion.match(/Safari\/(\d+.\d)/);
30037            if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) {
30038                return parseFloat(safariVersion[1]) < 535.19;
30039            } else {
30040                return true;
30041            }
30042        } else {
30043            return false;
30044        }
30045    })();
30046
30047    me.extend(me.style = {}, {
30048        transform: _transform,
30049        transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
30050        transitionDuration: _prefixStyle('transitionDuration'),
30051        transitionDelay: _prefixStyle('transitionDelay'),
30052        transformOrigin: _prefixStyle('transformOrigin')
30053    });
30054
30055    me.hasClass = function (e, c) {
30056        var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
30057        return re.test(e.className);
30058    };
30059
30060    me.addClass = function (e, c) {
30061        if ( me.hasClass(e, c) ) {
30062            return;
30063        }
30064
30065        var newclass = e.className.split(' ');
30066        newclass.push(c);
30067        e.className = newclass.join(' ');
30068    };
30069
30070    me.removeClass = function (e, c) {
30071        if ( !me.hasClass(e, c) ) {
30072            return;
30073        }
30074
30075        var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g');
30076        e.className = e.className.replace(re, ' ');
30077    };
30078
30079    me.offset = function (el) {
30080        var left = -el.offsetLeft,
30081            top = -el.offsetTop;
30082
30083        // jshint -W084
30084        while (el = el.offsetParent) {
30085            left -= el.offsetLeft;
30086            top -= el.offsetTop;
30087        }
30088        // jshint +W084
30089
30090        return {
30091            left: left,
30092            top: top
30093        };
30094    };
30095
30096    me.preventDefaultException = function (el, exceptions) {
30097        for ( var i in exceptions ) {
30098            if ( exceptions[i].test(el[i]) ) {
30099                return true;
30100            }
30101        }
30102
30103        return false;
30104    };
30105
30106    me.extend(me.eventType = {}, {
30107        touchstart: 1,
30108        touchmove: 1,
30109        touchend: 1,
30110
30111        mousedown: 2,
30112        mousemove: 2,
30113        mouseup: 2,
30114
30115        pointerdown: 3,
30116        pointermove: 3,
30117        pointerup: 3,
30118
30119        MSPointerDown: 3,
30120        MSPointerMove: 3,
30121        MSPointerUp: 3
30122    });
30123
30124    me.extend(me.ease = {}, {
30125        quadratic: {
30126            style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
30127            fn: function (k) {
30128                return k * ( 2 - k );
30129            }
30130        },
30131        circular: {
30132            style: 'cubic-bezier(0.1, 0.57, 0.1, 1)',   // Not properly "circular" but this looks better, it should be (0.075, 0.82, 0.165, 1)
30133            fn: function (k) {
30134                return Math.sqrt( 1 - ( --k * k ) );
30135            }
30136        },
30137        back: {
30138            style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
30139            fn: function (k) {
30140                var b = 4;
30141                return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
30142            }
30143        },
30144        bounce: {
30145            style: '',
30146            fn: function (k) {
30147                if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
30148                    return 7.5625 * k * k;
30149                } else if ( k < ( 2 / 2.75 ) ) {
30150                    return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
30151                } else if ( k < ( 2.5 / 2.75 ) ) {
30152                    return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
30153                } else {
30154                    return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
30155                }
30156            }
30157        },
30158        elastic: {
30159            style: '',
30160            fn: function (k) {
30161                var f = 0.22,
30162                    e = 0.4;
30163
30164                if ( k === 0 ) { return 0; }
30165                if ( k == 1 ) { return 1; }
30166
30167                return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
30168            }
30169        }
30170    });
30171
30172    me.tap = function (e, eventName) {
30173        var ev = document.createEvent('Event');
30174        ev.initEvent(eventName, true, true);
30175        ev.pageX = e.pageX;
30176        ev.pageY = e.pageY;
30177        e.target.dispatchEvent(ev);
30178    };
30179
30180    me.click = function (e) {
30181        var target = e.target,
30182            ev;
30183
30184        if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
30185            // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
30186            // initMouseEvent is deprecated.
30187            ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event');
30188            ev.initEvent('click', true, true);
30189            ev.view = e.view || window;
30190            ev.detail = 1;
30191            ev.screenX = target.screenX || 0;
30192            ev.screenY = target.screenY || 0;
30193            ev.clientX = target.clientX || 0;
30194            ev.clientY = target.clientY || 0;
30195            ev.ctrlKey = !!e.ctrlKey;
30196            ev.altKey = !!e.altKey;
30197            ev.shiftKey = !!e.shiftKey;
30198            ev.metaKey = !!e.metaKey;
30199            ev.button = 0;
30200            ev.relatedTarget = null;
30201            ev._constructed = true;
30202            target.dispatchEvent(ev);
30203        }
30204    };
30205
30206    return me;
30207})();
30208function IScroll (el, options) {
30209    this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
30210    this.scroller = this.wrapper.children[0];
30211    this.scrollerStyle = this.scroller.style;       // cache style for better performance
30212
30213    this.options = {
30214
30215        resizeScrollbars: true,
30216
30217        mouseWheelSpeed: 20,
30218
30219        snapThreshold: 0.334,
30220
30221// INSERT POINT: OPTIONS
30222        disablePointer : !utils.hasPointer,
30223        disableTouch : utils.hasPointer || !utils.hasTouch,
30224        disableMouse : utils.hasPointer || utils.hasTouch,
30225        startX: 0,
30226        startY: 0,
30227        scrollY: true,
30228        directionLockThreshold: 5,
30229        momentum: true,
30230
30231        bounce: true,
30232        bounceTime: 600,
30233        bounceEasing: '',
30234
30235        preventDefault: true,
30236        preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ },
30237
30238        HWCompositing: true,
30239        useTransition: true,
30240        useTransform: true,
30241        bindToWrapper: typeof window.onmousedown === "undefined"
30242    };
30243
30244    for ( var i in options ) {
30245        this.options[i] = options[i];
30246    }
30247
30248    // Normalize options
30249    this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
30250
30251    this.options.useTransition = utils.hasTransition && this.options.useTransition;
30252    this.options.useTransform = utils.hasTransform && this.options.useTransform;
30253
30254    this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
30255    this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
30256
30257    // If you want eventPassthrough I have to lock one of the axes
30258    this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
30259    this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
30260
30261    // With eventPassthrough we also need lockDirection mechanism
30262    this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
30263    this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
30264
30265    this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing;
30266
30267    this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
30268
30269    if ( this.options.tap === true ) {
30270        this.options.tap = 'tap';
30271    }
30272
30273    // https://github.com/cubiq/iscroll/issues/1029
30274    if (!this.options.useTransition && !this.options.useTransform) {
30275        if(!(/relative|absolute/i).test(this.scrollerStyle.position)) {
30276            this.scrollerStyle.position = "relative";
30277        }
30278    }
30279
30280    if ( this.options.shrinkScrollbars == 'scale' ) {
30281        this.options.useTransition = false;
30282    }
30283
30284    this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;
30285
30286// INSERT POINT: NORMALIZATION
30287
30288    // Some defaults
30289    this.x = 0;
30290    this.y = 0;
30291    this.directionX = 0;
30292    this.directionY = 0;
30293    this._events = {};
30294
30295// INSERT POINT: DEFAULTS
30296
30297    this._init();
30298    this.refresh();
30299
30300    this.scrollTo(this.options.startX, this.options.startY);
30301    this.enable();
30302}
30303
30304IScroll.prototype = {
30305    version: '5.2.0',
30306
30307    _init: function () {
30308        this._initEvents();
30309
30310        if ( this.options.scrollbars || this.options.indicators ) {
30311            this._initIndicators();
30312        }
30313
30314        if ( this.options.mouseWheel ) {
30315            this._initWheel();
30316        }
30317
30318        if ( this.options.snap ) {
30319            this._initSnap();
30320        }
30321
30322        if ( this.options.keyBindings ) {
30323            this._initKeys();
30324        }
30325
30326// INSERT POINT: _init
30327
30328    },
30329
30330    destroy: function () {
30331        this._initEvents(true);
30332        clearTimeout(this.resizeTimeout);
30333        this.resizeTimeout = null;
30334        this._execEvent('destroy');
30335    },
30336
30337    _transitionEnd: function (e) {
30338        if ( e.target != this.scroller || !this.isInTransition ) {
30339            return;
30340        }
30341
30342        this._transitionTime();
30343        if ( !this.resetPosition(this.options.bounceTime) ) {
30344            this.isInTransition = false;
30345            this._execEvent('scrollEnd');
30346        }
30347    },
30348
30349    _start: function (e) {
30350        // React to left mouse button only
30351        if ( utils.eventType[e.type] != 1 ) {
30352          // for button property
30353          // http://unixpapa.com/js/mouse.html
30354          var button;
30355        if (!e.which) {
30356          /* IE case */
30357          button = (e.button < 2) ? 0 :
30358                   ((e.button == 4) ? 1 : 2);
30359        } else {
30360          /* All others */
30361          button = e.button;
30362        }
30363            if ( button !== 0 ) {
30364                return;
30365            }
30366        }
30367
30368        if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) {
30369            return;
30370        }
30371
30372        if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
30373            e.preventDefault();
30374        }
30375
30376        var point = e.touches ? e.touches[0] : e,
30377            pos;
30378
30379        this.initiated  = utils.eventType[e.type];
30380        this.moved      = false;
30381        this.distX      = 0;
30382        this.distY      = 0;
30383        this.directionX = 0;
30384        this.directionY = 0;
30385        this.directionLocked = 0;
30386
30387        this.startTime = utils.getTime();
30388
30389        if ( this.options.useTransition && this.isInTransition ) {
30390            this._transitionTime();
30391            this.isInTransition = false;
30392            pos = this.getComputedPosition();
30393            this._translate(Math.round(pos.x), Math.round(pos.y));
30394            this._execEvent('scrollEnd');
30395        } else if ( !this.options.useTransition && this.isAnimating ) {
30396            this.isAnimating = false;
30397            this._execEvent('scrollEnd');
30398        }
30399
30400        this.startX    = this.x;
30401        this.startY    = this.y;
30402        this.absStartX = this.x;
30403        this.absStartY = this.y;
30404        this.pointX    = point.pageX;
30405        this.pointY    = point.pageY;
30406
30407        this._execEvent('beforeScrollStart');
30408    },
30409
30410    _move: function (e) {
30411        if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
30412            return;
30413        }
30414
30415        if ( this.options.preventDefault ) {    // increases performance on Android? TODO: check!
30416            e.preventDefault();
30417        }
30418
30419        var point       = e.touches ? e.touches[0] : e,
30420            deltaX      = point.pageX - this.pointX,
30421            deltaY      = point.pageY - this.pointY,
30422            timestamp   = utils.getTime(),
30423            newX, newY,
30424            absDistX, absDistY;
30425
30426        this.pointX     = point.pageX;
30427        this.pointY     = point.pageY;
30428
30429        this.distX      += deltaX;
30430        this.distY      += deltaY;
30431        absDistX        = Math.abs(this.distX);
30432        absDistY        = Math.abs(this.distY);
30433
30434        // We need to move at least 10 pixels for the scrolling to initiate
30435        if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) {
30436            return;
30437        }
30438
30439        // If you are scrolling in one direction lock the other
30440        if ( !this.directionLocked && !this.options.freeScroll ) {
30441            if ( absDistX > absDistY + this.options.directionLockThreshold ) {
30442                this.directionLocked = 'h';     // lock horizontally
30443            } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) {
30444                this.directionLocked = 'v';     // lock vertically
30445            } else {
30446                this.directionLocked = 'n';     // no lock
30447            }
30448        }
30449
30450        if ( this.directionLocked == 'h' ) {
30451            if ( this.options.eventPassthrough == 'vertical' ) {
30452                e.preventDefault();
30453            } else if ( this.options.eventPassthrough == 'horizontal' ) {
30454                this.initiated = false;
30455                return;
30456            }
30457
30458            deltaY = 0;
30459        } else if ( this.directionLocked == 'v' ) {
30460            if ( this.options.eventPassthrough == 'horizontal' ) {
30461                e.preventDefault();
30462            } else if ( this.options.eventPassthrough == 'vertical' ) {
30463                this.initiated = false;
30464                return;
30465            }
30466
30467            deltaX = 0;
30468        }
30469
30470        deltaX = this.hasHorizontalScroll ? deltaX : 0;
30471        deltaY = this.hasVerticalScroll ? deltaY : 0;
30472
30473        newX = this.x + deltaX;
30474        newY = this.y + deltaY;
30475
30476        // Slow down if outside of the boundaries
30477        if ( newX > 0 || newX < this.maxScrollX ) {
30478            newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
30479        }
30480        if ( newY > 0 || newY < this.maxScrollY ) {
30481            newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
30482        }
30483
30484        this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
30485        this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
30486
30487        if ( !this.moved ) {
30488            this._execEvent('scrollStart');
30489        }
30490
30491        this.moved = true;
30492
30493        this._translate(newX, newY);
30494
30495/* REPLACE START: _move */
30496
30497        if ( timestamp - this.startTime > 300 ) {
30498            this.startTime = timestamp;
30499            this.startX = this.x;
30500            this.startY = this.y;
30501        }
30502
30503/* REPLACE END: _move */
30504
30505    },
30506
30507    _end: function (e) {
30508        if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
30509            return;
30510        }
30511
30512        if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
30513            e.preventDefault();
30514        }
30515
30516        var point = e.changedTouches ? e.changedTouches[0] : e,
30517            momentumX,
30518            momentumY,
30519            duration = utils.getTime() - this.startTime,
30520            newX = Math.round(this.x),
30521            newY = Math.round(this.y),
30522            distanceX = Math.abs(newX - this.startX),
30523            distanceY = Math.abs(newY - this.startY),
30524            time = 0,
30525            easing = '';
30526
30527        this.isInTransition = 0;
30528        this.initiated = 0;
30529        this.endTime = utils.getTime();
30530
30531        // reset if we are outside of the boundaries
30532        if ( this.resetPosition(this.options.bounceTime) ) {
30533            return;
30534        }
30535
30536        this.scrollTo(newX, newY);  // ensures that the last position is rounded
30537
30538        // we scrolled less than 10 pixels
30539        if ( !this.moved ) {
30540            if ( this.options.tap ) {
30541                utils.tap(e, this.options.tap);
30542            }
30543
30544            if ( this.options.click ) {
30545                utils.click(e);
30546            }
30547
30548            this._execEvent('scrollCancel');
30549            return;
30550        }
30551
30552        if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) {
30553            this._execEvent('flick');
30554            return;
30555        }
30556
30557        // start momentum animation if needed
30558        if ( this.options.momentum && duration < 300 ) {
30559            momentumX = this.hasHorizontalScroll ? utils.momentum(this.x, this.startX, duration, this.maxScrollX, this.options.bounce ? this.wrapperWidth : 0, this.options.deceleration) : { destination: newX, duration: 0 };
30560            momentumY = this.hasVerticalScroll ? utils.momentum(this.y, this.startY, duration, this.maxScrollY, this.options.bounce ? this.wrapperHeight : 0, this.options.deceleration) : { destination: newY, duration: 0 };
30561            newX = momentumX.destination;
30562            newY = momentumY.destination;
30563            time = Math.max(momentumX.duration, momentumY.duration);
30564            this.isInTransition = 1;
30565        }
30566
30567
30568        if ( this.options.snap ) {
30569            var snap = this._nearestSnap(newX, newY);
30570            this.currentPage = snap;
30571            time = this.options.snapSpeed || Math.max(
30572                    Math.max(
30573                        Math.min(Math.abs(newX - snap.x), 1000),
30574                        Math.min(Math.abs(newY - snap.y), 1000)
30575                    ), 300);
30576            newX = snap.x;
30577            newY = snap.y;
30578
30579            this.directionX = 0;
30580            this.directionY = 0;
30581            easing = this.options.bounceEasing;
30582        }
30583
30584// INSERT POINT: _end
30585
30586        if ( newX != this.x || newY != this.y ) {
30587            // change easing function when scroller goes out of the boundaries
30588            if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
30589                easing = utils.ease.quadratic;
30590            }
30591
30592            this.scrollTo(newX, newY, time, easing);
30593            return;
30594        }
30595
30596        this._execEvent('scrollEnd');
30597    },
30598
30599    _resize: function () {
30600        var that = this;
30601
30602        clearTimeout(this.resizeTimeout);
30603
30604        this.resizeTimeout = setTimeout(function () {
30605            that.refresh();
30606        }, this.options.resizePolling);
30607    },
30608
30609    resetPosition: function (time) {
30610        var x = this.x,
30611            y = this.y;
30612
30613        time = time || 0;
30614
30615        if ( !this.hasHorizontalScroll || this.x > 0 ) {
30616            x = 0;
30617        } else if ( this.x < this.maxScrollX ) {
30618            x = this.maxScrollX;
30619        }
30620
30621        if ( !this.hasVerticalScroll || this.y > 0 ) {
30622            y = 0;
30623        } else if ( this.y < this.maxScrollY ) {
30624            y = this.maxScrollY;
30625        }
30626
30627        if ( x == this.x && y == this.y ) {
30628            return false;
30629        }
30630
30631        this.scrollTo(x, y, time, this.options.bounceEasing);
30632
30633        return true;
30634    },
30635
30636    disable: function () {
30637        this.enabled = false;
30638    },
30639
30640    enable: function () {
30641        this.enabled = true;
30642    },
30643
30644    refresh: function () {
30645        var rf = this.wrapper.offsetHeight;     // Force reflow
30646
30647        this.wrapperWidth   = this.wrapper.clientWidth;
30648        this.wrapperHeight  = this.wrapper.clientHeight;
30649
30650/* REPLACE START: refresh */
30651
30652        this.scrollerWidth  = this.scroller.offsetWidth;
30653        this.scrollerHeight = this.scroller.offsetHeight;
30654
30655        this.maxScrollX     = this.wrapperWidth - this.scrollerWidth;
30656        this.maxScrollY     = this.wrapperHeight - this.scrollerHeight;
30657
30658/* REPLACE END: refresh */
30659
30660        this.hasHorizontalScroll    = this.options.scrollX && this.maxScrollX < 0;
30661        this.hasVerticalScroll      = this.options.scrollY && this.maxScrollY < 0;
30662
30663        if ( !this.hasHorizontalScroll ) {
30664            this.maxScrollX = 0;
30665            this.scrollerWidth = this.wrapperWidth;
30666        }
30667
30668        if ( !this.hasVerticalScroll ) {
30669            this.maxScrollY = 0;
30670            this.scrollerHeight = this.wrapperHeight;
30671        }
30672
30673        this.endTime = 0;
30674        this.directionX = 0;
30675        this.directionY = 0;
30676
30677        this.wrapperOffset = utils.offset(this.wrapper);
30678
30679        this._execEvent('refresh');
30680
30681        this.resetPosition();
30682
30683// INSERT POINT: _refresh
30684
30685    },
30686
30687
30688    on: function (type, fn) {
30689        if ( !this._events[type] ) {
30690            this._events[type] = [];
30691        }
30692
30693        this._events[type].push(fn);
30694    },
30695
30696    off: function (type, fn) {
30697        if ( !this._events[type] ) {
30698            return;
30699        }
30700
30701        var index = this._events[type].indexOf(fn);
30702
30703        if ( index > -1 ) {
30704            this._events[type].splice(index, 1);
30705        }
30706    },
30707
30708    _execEvent: function (type) {
30709        if ( !this._events[type] ) {
30710            return;
30711        }
30712
30713        var i = 0,
30714            l = this._events[type].length;
30715
30716        if ( !l ) {
30717            return;
30718        }
30719
30720        for ( ; i < l; i++ ) {
30721            this._events[type][i].apply(this, [].slice.call(arguments, 1));
30722        }
30723    },
30724
30725    scrollBy: function (x, y, time, easing) {
30726        x = this.x + x;
30727        y = this.y + y;
30728        time = time || 0;
30729
30730        this.scrollTo(x, y, time, easing);
30731    },
30732
30733    scrollTo: function (x, y, time, easing) {
30734        easing = easing || utils.ease.circular;
30735
30736        this.isInTransition = this.options.useTransition && time > 0;
30737        var transitionType = this.options.useTransition && easing.style;
30738        if ( !time || transitionType ) {
30739                if(transitionType) {
30740                    this._transitionTimingFunction(easing.style);
30741                    this._transitionTime(time);
30742                }
30743            this._translate(x, y);
30744        } else {
30745            this._animate(x, y, time, easing.fn);
30746        }
30747    },
30748
30749    scrollToElement: function (el, time, offsetX, offsetY, easing) {
30750        el = el.nodeType ? el : this.scroller.querySelector(el);
30751
30752        if ( !el ) {
30753            return;
30754        }
30755
30756        var pos = utils.offset(el);
30757
30758        pos.left -= this.wrapperOffset.left;
30759        pos.top  -= this.wrapperOffset.top;
30760
30761        // if offsetX/Y are true we center the element to the screen
30762        if ( offsetX === true ) {
30763            offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2);
30764        }
30765        if ( offsetY === true ) {
30766            offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2);
30767        }
30768
30769        pos.left -= offsetX || 0;
30770        pos.top  -= offsetY || 0;
30771
30772        pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
30773        pos.top  = pos.top  > 0 ? 0 : pos.top  < this.maxScrollY ? this.maxScrollY : pos.top;
30774
30775        time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time;
30776
30777        this.scrollTo(pos.left, pos.top, time, easing);
30778    },
30779
30780    _transitionTime: function (time) {
30781        if (!this.options.useTransition) {
30782            return;
30783        }
30784        time = time || 0;
30785        var durationProp = utils.style.transitionDuration;
30786        if(!durationProp) {
30787            return;
30788        }
30789
30790        this.scrollerStyle[durationProp] = time + 'ms';
30791
30792        if ( !time && utils.isBadAndroid ) {
30793            this.scrollerStyle[durationProp] = '0.0001ms';
30794            // remove 0.0001ms
30795            var self = this;
30796            rAF(function() {
30797                if(self.scrollerStyle[durationProp] === '0.0001ms') {
30798                    self.scrollerStyle[durationProp] = '0s';
30799                }
30800            });
30801        }
30802
30803
30804        if ( this.indicators ) {
30805            for ( var i = this.indicators.length; i--; ) {
30806                this.indicators[i].transitionTime(time);
30807            }
30808        }
30809
30810
30811// INSERT POINT: _transitionTime
30812
30813    },
30814
30815    _transitionTimingFunction: function (easing) {
30816        this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
30817
30818
30819        if ( this.indicators ) {
30820            for ( var i = this.indicators.length; i--; ) {
30821                this.indicators[i].transitionTimingFunction(easing);
30822            }
30823        }
30824
30825
30826// INSERT POINT: _transitionTimingFunction
30827
30828    },
30829
30830    _translate: function (x, y) {
30831        //Uncode addition
30832        if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 )
30833            return false;
30834
30835        if ( this.options.useTransform ) {
30836
30837/* REPLACE START: _translate */
30838
30839            this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ;
30840
30841/* REPLACE END: _translate */
30842
30843        } else {
30844            x = Math.round(x);
30845            y = Math.round(y);
30846            this.scrollerStyle.left = x + 'px';
30847            this.scrollerStyle.top = y + 'px';
30848        }
30849
30850        this.x = x;
30851        this.y = y;
30852
30853
30854        if ( this.indicators ) {
30855            for ( var i = this.indicators.length; i--; ) {
30856                this.indicators[i].updatePosition();
30857            }
30858        }
30859
30860        //Uncode addition
30861        var uncodevent = new CustomEvent('fp-slide-scroll');
30862        window.dispatchEvent(uncodevent);
30863
30864// INSERT POINT: _translate
30865
30866    },
30867
30868    _initEvents: function (remove) {
30869        var eventType = remove ? utils.removeEvent : utils.addEvent,
30870            target = this.options.bindToWrapper ? this.wrapper : window;
30871
30872        eventType(window, 'orientationchange', this);
30873        eventType(window, 'resize', this);
30874
30875        if ( this.options.click ) {
30876            eventType(this.wrapper, 'click', this, true);
30877        }
30878
30879        if ( !this.options.disableMouse ) {
30880            eventType(this.wrapper, 'mousedown', this);
30881            eventType(target, 'mousemove', this);
30882            eventType(target, 'mousecancel', this);
30883            eventType(target, 'mouseup', this);
30884        }
30885
30886        if ( utils.hasPointer && !this.options.disablePointer ) {
30887            eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
30888            eventType(target, utils.prefixPointerEvent('pointermove'), this);
30889            eventType(target, utils.prefixPointerEvent('pointercancel'), this);
30890            eventType(target, utils.prefixPointerEvent('pointerup'), this);
30891        }
30892
30893        if ( utils.hasTouch && !this.options.disableTouch ) {
30894            eventType(this.wrapper, 'touchstart', this);
30895            eventType(target, 'touchmove', this);
30896            eventType(target, 'touchcancel', this);
30897            eventType(target, 'touchend', this);
30898        }
30899
30900        eventType(this.scroller, 'transitionend', this);
30901        eventType(this.scroller, 'webkitTransitionEnd', this);
30902        eventType(this.scroller, 'oTransitionEnd', this);
30903        eventType(this.scroller, 'MSTransitionEnd', this);
30904    },
30905
30906    getComputedPosition: function () {
30907        var matrix = window.getComputedStyle(this.scroller, null),
30908            x, y;
30909
30910        if ( this.options.useTransform ) {
30911            matrix = matrix[utils.style.transform].split(')')[0].split(', ');
30912            x = +(matrix[12] || matrix[4]);
30913            y = +(matrix[13] || matrix[5]);
30914        } else {
30915            x = +matrix.left.replace(/[^-\d.]/g, '');
30916            y = +matrix.top.replace(/[^-\d.]/g, '');
30917        }
30918
30919        return { x: x, y: y };
30920    },
30921    _initIndicators: function () {
30922        var interactive = this.options.interactiveScrollbars,
30923            customStyle = typeof this.options.scrollbars != 'string',
30924            indicators = [],
30925            indicator;
30926
30927        var that = this;
30928
30929        this.indicators = [];
30930
30931        if ( this.options.scrollbars ) {
30932            // Vertical scrollbar
30933            if ( this.options.scrollY ) {
30934                indicator = {
30935                    el: createDefaultScrollbar('v', interactive, this.options.scrollbars),
30936                    interactive: interactive,
30937                    defaultScrollbars: true,
30938                    customStyle: customStyle,
30939                    resize: this.options.resizeScrollbars,
30940                    shrink: this.options.shrinkScrollbars,
30941                    fade: this.options.fadeScrollbars,
30942                    listenX: false
30943                };
30944
30945                this.wrapper.appendChild(indicator.el);
30946                indicators.push(indicator);
30947            }
30948
30949            // Horizontal scrollbar
30950            if ( this.options.scrollX ) {
30951                indicator = {
30952                    el: createDefaultScrollbar('h', interactive, this.options.scrollbars),
30953                    interactive: interactive,
30954                    defaultScrollbars: true,
30955                    customStyle: customStyle,
30956                    resize: this.options.resizeScrollbars,
30957                    shrink: this.options.shrinkScrollbars,
30958                    fade: this.options.fadeScrollbars,
30959                    listenY: false
30960                };
30961
30962                this.wrapper.appendChild(indicator.el);
30963                indicators.push(indicator);
30964            }
30965        }
30966
30967        if ( this.options.indicators ) {
30968            // TODO: check concat compatibility
30969            indicators = indicators.concat(this.options.indicators);
30970        }
30971
30972        for ( var i = indicators.length; i--; ) {
30973            this.indicators.push( new Indicator(this, indicators[i]) );
30974        }
30975
30976        // TODO: check if we can use array.map (wide compatibility and performance issues)
30977        function _indicatorsMap (fn) {
30978            if (that.indicators) {
30979                for ( var i = that.indicators.length; i--; ) {
30980                    fn.call(that.indicators[i]);
30981                }
30982            }
30983        }
30984
30985        if ( this.options.fadeScrollbars ) {
30986            this.on('scrollEnd', function () {
30987                _indicatorsMap(function () {
30988                    this.fade();
30989                });
30990            });
30991
30992            this.on('scrollCancel', function () {
30993                _indicatorsMap(function () {
30994                    this.fade();
30995                });
30996            });
30997
30998            this.on('scrollStart', function () {
30999                _indicatorsMap(function () {
31000                    this.fade(1);
31001                });
31002            });
31003
31004            this.on('beforeScrollStart', function () {
31005                _indicatorsMap(function () {
31006                    this.fade(1, true);
31007                });
31008            });
31009        }
31010
31011
31012        this.on('refresh', function () {
31013            _indicatorsMap(function () {
31014                this.refresh();
31015            });
31016        });
31017
31018        this.on('destroy', function () {
31019            _indicatorsMap(function () {
31020                this.destroy();
31021            });
31022
31023            delete this.indicators;
31024        });
31025    },
31026
31027    _initWheel: function () {
31028        utils.addEvent(this.wrapper, 'wheel', this);
31029        utils.addEvent(this.wrapper, 'mousewheel', this);
31030        utils.addEvent(this.wrapper, 'DOMMouseScroll', this);
31031
31032        this.on('destroy', function () {
31033            clearTimeout(this.wheelTimeout);
31034            this.wheelTimeout = null;
31035            utils.removeEvent(this.wrapper, 'wheel', this);
31036            utils.removeEvent(this.wrapper, 'mousewheel', this);
31037            utils.removeEvent(this.wrapper, 'DOMMouseScroll', this);
31038        });
31039    },
31040
31041    _wheel: function (e) {
31042        if ( !this.enabled ) {
31043            return;
31044        }
31045
31046        var wheelDeltaX, wheelDeltaY,
31047            newX, newY,
31048            that = this;
31049
31050        if ( this.wheelTimeout === undefined ) {
31051            that._execEvent('scrollStart');
31052        }
31053
31054        // Execute the scrollEnd event after 400ms the wheel stopped scrolling
31055        clearTimeout(this.wheelTimeout);
31056        this.wheelTimeout = setTimeout(function () {
31057            if(!that.options.snap) {
31058                that._execEvent('scrollEnd');
31059            }
31060            that.wheelTimeout = undefined;
31061        }, 400);
31062
31063        if ( 'deltaX' in e ) {
31064            if (e.deltaMode === 1) {
31065                wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed;
31066                wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed;
31067            } else {
31068                wheelDeltaX = -e.deltaX;
31069                wheelDeltaY = -e.deltaY;
31070            }
31071        } else if ( 'wheelDeltaX' in e ) {
31072            wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed;
31073            wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed;
31074        } else if ( 'wheelDelta' in e ) {
31075            wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed;
31076        } else if ( 'detail' in e ) {
31077            wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed;
31078        } else {
31079            return;
31080        }
31081
31082        wheelDeltaX *= this.options.invertWheelDirection;
31083        wheelDeltaY *= this.options.invertWheelDirection;
31084
31085        if ( !this.hasVerticalScroll ) {
31086            wheelDeltaX = wheelDeltaY;
31087            wheelDeltaY = 0;
31088        }
31089
31090        if ( this.options.snap ) {
31091            newX = this.currentPage.pageX;
31092            newY = this.currentPage.pageY;
31093
31094            if ( wheelDeltaX > 0 ) {
31095                newX--;
31096            } else if ( wheelDeltaX < 0 ) {
31097                newX++;
31098            }
31099
31100            if ( wheelDeltaY > 0 ) {
31101                newY--;
31102            } else if ( wheelDeltaY < 0 ) {
31103                newY++;
31104            }
31105
31106            this.goToPage(newX, newY);
31107
31108            return;
31109        }
31110
31111        newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0);
31112        newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0);
31113
31114        this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0;
31115        this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0;
31116
31117        if ( newX > 0 ) {
31118            newX = 0;
31119        } else if ( newX < this.maxScrollX ) {
31120            newX = this.maxScrollX;
31121        }
31122
31123        if ( newY > 0 ) {
31124            newY = 0;
31125        } else if ( newY < this.maxScrollY ) {
31126            newY = this.maxScrollY;
31127        }
31128
31129        this.scrollTo(newX, newY, 0);
31130
31131// INSERT POINT: _wheel
31132    },
31133
31134    _initSnap: function () {
31135        this.currentPage = {};
31136
31137        if ( typeof this.options.snap == 'string' ) {
31138            this.options.snap = this.scroller.querySelectorAll(this.options.snap);
31139        }
31140
31141        this.on('refresh', function () {
31142            var i = 0, l,
31143                m = 0, n,
31144                cx, cy,
31145                x = 0, y,
31146                stepX = this.options.snapStepX || this.wrapperWidth,
31147                stepY = this.options.snapStepY || this.wrapperHeight,
31148                el;
31149
31150            this.pages = [];
31151
31152            if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) {
31153                return;
31154            }
31155
31156            if ( this.options.snap === true ) {
31157                cx = Math.round( stepX / 2 );
31158                cy = Math.round( stepY / 2 );
31159
31160                while ( x > -this.scrollerWidth ) {
31161                    this.pages[i] = [];
31162                    l = 0;
31163                    y = 0;
31164
31165                    while ( y > -this.scrollerHeight ) {
31166                        this.pages[i][l] = {
31167                            x: Math.max(x, this.maxScrollX),
31168                            y: Math.max(y, this.maxScrollY),
31169                            width: stepX,
31170                            height: stepY,
31171                            cx: x - cx,
31172                            cy: y - cy
31173                        };
31174
31175                        y -= stepY;
31176                        l++;
31177                    }
31178
31179                    x -= stepX;
31180                    i++;
31181                }
31182            } else {
31183                el = this.options.snap;
31184                l = el.length;
31185                n = -1;
31186
31187                for ( ; i < l; i++ ) {
31188                    if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) {
31189                        m = 0;
31190                        n++;
31191                    }
31192
31193                    if ( !this.pages[m] ) {
31194                        this.pages[m] = [];
31195                    }
31196
31197                    x = Math.max(-el[i].offsetLeft, this.maxScrollX);
31198                    y = Math.max(-el[i].offsetTop, this.maxScrollY);
31199                    cx = x - Math.round(el[i].offsetWidth / 2);
31200                    cy = y - Math.round(el[i].offsetHeight / 2);
31201
31202                    this.pages[m][n] = {
31203                        x: x,
31204                        y: y,
31205                        width: el[i].offsetWidth,
31206                        height: el[i].offsetHeight,
31207                        cx: cx,
31208                        cy: cy
31209                    };
31210
31211                    if ( x > this.maxScrollX ) {
31212                        m++;
31213                    }
31214                }
31215            }
31216
31217            this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0);
31218
31219            // Update snap threshold if needed
31220            if ( this.options.snapThreshold % 1 === 0 ) {
31221                this.snapThresholdX = this.options.snapThreshold;
31222                this.snapThresholdY = this.options.snapThreshold;
31223            } else {
31224                this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold);
31225                this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold);
31226            }
31227        });
31228
31229        this.on('flick', function () {
31230            var time = this.options.snapSpeed || Math.max(
31231                    Math.max(
31232                        Math.min(Math.abs(this.x - this.startX), 1000),
31233                        Math.min(Math.abs(this.y - this.startY), 1000)
31234                    ), 300);
31235
31236            this.goToPage(
31237                this.currentPage.pageX + this.directionX,
31238                this.currentPage.pageY + this.directionY,
31239                time
31240            );
31241        });
31242    },
31243
31244    _nearestSnap: function (x, y) {
31245        if ( !this.pages.length ) {
31246            return { x: 0, y: 0, pageX: 0, pageY: 0 };
31247        }
31248
31249        var i = 0,
31250            l = this.pages.length,
31251            m = 0;
31252
31253        // Check if we exceeded the snap threshold
31254        if ( Math.abs(x - this.absStartX) < this.snapThresholdX &&
31255            Math.abs(y - this.absStartY) < this.snapThresholdY ) {
31256            return this.currentPage;
31257        }
31258
31259        if ( x > 0 ) {
31260            x = 0;
31261        } else if ( x < this.maxScrollX ) {
31262            x = this.maxScrollX;
31263        }
31264
31265        if ( y > 0 ) {
31266            y = 0;
31267        } else if ( y < this.maxScrollY ) {
31268            y = this.maxScrollY;
31269        }
31270
31271        for ( ; i < l; i++ ) {
31272            if ( x >= this.pages[i][0].cx ) {
31273                x = this.pages[i][0].x;
31274                break;
31275            }
31276        }
31277
31278        l = this.pages[i].length;
31279
31280        for ( ; m < l; m++ ) {
31281            if ( y >= this.pages[0][m].cy ) {
31282                y = this.pages[0][m].y;
31283                break;
31284            }
31285        }
31286
31287        if ( i == this.currentPage.pageX ) {
31288            i += this.directionX;
31289
31290            if ( i < 0 ) {
31291                i = 0;
31292            } else if ( i >= this.pages.length ) {
31293                i = this.pages.length - 1;
31294            }
31295
31296            x = this.pages[i][0].x;
31297        }
31298
31299        if ( m == this.currentPage.pageY ) {
31300            m += this.directionY;
31301
31302            if ( m < 0 ) {
31303                m = 0;
31304            } else if ( m >= this.pages[0].length ) {
31305                m = this.pages[0].length - 1;
31306            }
31307
31308            y = this.pages[0][m].y;
31309        }
31310
31311        return {
31312            x: x,
31313            y: y,
31314            pageX: i,
31315            pageY: m
31316        };
31317    },
31318
31319    goToPage: function (x, y, time, easing) {
31320        easing = easing || this.options.bounceEasing;
31321
31322        if ( x >= this.pages.length ) {
31323            x = this.pages.length - 1;
31324        } else if ( x < 0 ) {
31325            x = 0;
31326        }
31327
31328        if ( y >= this.pages[x].length ) {
31329            y = this.pages[x].length - 1;
31330        } else if ( y < 0 ) {
31331            y = 0;
31332        }
31333
31334        var posX = this.pages[x][y].x,
31335            posY = this.pages[x][y].y;
31336
31337        time = time === undefined ? this.options.snapSpeed || Math.max(
31338            Math.max(
31339                Math.min(Math.abs(posX - this.x), 1000),
31340                Math.min(Math.abs(posY - this.y), 1000)
31341            ), 300) : time;
31342
31343        this.currentPage = {
31344            x: posX,
31345            y: posY,
31346            pageX: x,
31347            pageY: y
31348        };
31349
31350        this.scrollTo(posX, posY, time, easing);
31351    },
31352
31353    next: function (time, easing) {
31354        var x = this.currentPage.pageX,
31355            y = this.currentPage.pageY;
31356
31357        x++;
31358
31359        if ( x >= this.pages.length && this.hasVerticalScroll ) {
31360            x = 0;
31361            y++;
31362        }
31363
31364        this.goToPage(x, y, time, easing);
31365    },
31366
31367    prev: function (time, easing) {
31368        var x = this.currentPage.pageX,
31369            y = this.currentPage.pageY;
31370
31371        x--;
31372
31373        if ( x < 0 && this.hasVerticalScroll ) {
31374            x = 0;
31375            y--;
31376        }
31377
31378        this.goToPage(x, y, time, easing);
31379    },
31380
31381    _initKeys: function (e) {
31382        // default key bindings
31383        var keys = {
31384            pageUp: 33,
31385            pageDown: 34,
31386            end: 35,
31387            home: 36,
31388            left: 37,
31389            up: 38,
31390            right: 39,
31391            down: 40
31392        };
31393        var i;
31394
31395        // if you give me characters I give you keycode
31396        if ( typeof this.options.keyBindings == 'object' ) {
31397            for ( i in this.options.keyBindings ) {
31398                if ( typeof this.options.keyBindings[i] == 'string' ) {
31399                    this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
31399deAt(0);
31400                }
31401            }
31402        } else {
31403            this.options.keyBindings = {};
31404        }
31405
31406        for ( i in keys ) {
31407            this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
31408        }
31409
31410        utils.addEvent(window, 'keydown', this);
31411
31412        this.on('destroy', function () {
31413            utils.removeEvent(window, 'keydown', this);
31414        });
31415    },
31416
31417    _key: function (e) {
31418        if ( !this.enabled ) {
31419            return;
31420        }
31421
31422        var snap = this.options.snap,   // we are using this alot, better to cache it
31423            newX = snap ? this.currentPage.pageX : this.x,
31424            newY = snap ? this.currentPage.pageY : this.y,
31425            now = utils.getTime(),
31426            prevTime = this.keyTime || 0,
31427            acceleration = 0.250,
31428            pos;
31429
31430        if ( this.options.useTransition && this.isInTransition ) {
31431            pos = this.getComputedPosition();
31432
31433            this._translate(Math.round(pos.x), Math.round(pos.y));
31434            this.isInTransition = false;
31435        }
31436
31437        this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0;
31438
31439        switch ( e.keyCode ) {
31440            case this.options.keyBindings.pageUp:
31441                if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
31442                    newX += snap ? 1 : this.wrapperWidth;
31443                } else {
31444                    newY += snap ? 1 : this.wrapperHeight;
31445                }
31446                break;
31447            case this.options.keyBindings.pageDown:
31448                if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
31449                    newX -= snap ? 1 : this.wrapperWidth;
31450                } else {
31451                    newY -= snap ? 1 : this.wrapperHeight;
31452                }
31453                break;
31454            case this.options.keyBindings.end:
31455                newX = snap ? this.pages.length-1 : this.maxScrollX;
31456                newY = snap ? this.pages[0].length-1 : this.maxScrollY;
31457                break;
31458            case this.options.keyBindings.home:
31459                newX = 0;
31460                newY = 0;
31461                break;
31462            case this.options.keyBindings.left:
31463                newX += snap ? -1 : 5 + this.keyAcceleration>>0;
31464                break;
31465            case this.options.keyBindings.up:
31466                newY += snap ? 1 : 5 + this.keyAcceleration>>0;
31467                break;
31468            case this.options.keyBindings.right:
31469                newX -= snap ? -1 : 5 + this.keyAcceleration>>0;
31470                break;
31471            case this.options.keyBindings.down:
31472                newY -= snap ? 1 : 5 + this.keyAcceleration>>0;
31473                break;
31474            default:
31475                return;
31476        }
31477
31478        if ( snap ) {
31479            this.goToPage(newX, newY);
31480            return;
31481        }
31482
31483        if ( newX > 0 ) {
31484            newX = 0;
31485            this.keyAcceleration = 0;
31486        } else if ( newX < this.maxScrollX ) {
31487            newX = this.maxScrollX;
31488            this.keyAcceleration = 0;
31489        }
31490
31491        if ( newY > 0 ) {
31492            newY = 0;
31493            this.keyAcceleration = 0;
31494        } else if ( newY < this.maxScrollY ) {
31495            newY = this.maxScrollY;
31496            this.keyAcceleration = 0;
31497        }
31498
31499        this.scrollTo(newX, newY, 0);
31500
31501        this.keyTime = now;
31502    },
31503
31504    _animate: function (destX, destY, duration, easingFn) {
31505        var that = this,
31506            startX = this.x,
31507            startY = this.y,
31508            startTime = utils.getTime(),
31509            destTime = startTime + duration;
31510
31511        function step () {
31512            var now = utils.getTime(),
31513                newX, newY,
31514                easing;
31515
31516            if ( now >= destTime ) {
31517                that.isAnimating = false;
31518                that._translate(destX, destY);
31519
31520                if ( !that.resetPosition(that.options.bounceTime) ) {
31521                    that._execEvent('scrollEnd');
31522                }
31523
31524                return;
31525            }
31526
31527            now = ( now - startTime ) / duration;
31528            easing = easingFn(now);
31529            newX = ( destX - startX ) * easing + startX;
31530            newY = ( destY - startY ) * easing + startY;
31531            that._translate(newX, newY);
31532
31533            if ( that.isAnimating ) {
31534                rAF(step);
31535            }
31536        }
31537
31538        this.isAnimating = true;
31539        step();
31540    },
31541    handleEvent: function (e) {
31542        switch ( e.type ) {
31543            case 'touchstart':
31544            case 'pointerdown':
31545            case 'MSPointerDown':
31546            case 'mousedown':
31547                this._start(e);
31548                break;
31549            case 'touchmove':
31550            case 'pointermove':
31551            case 'MSPointerMove':
31552            case 'mousemove':
31553                this._move(e);
31554                break;
31555            case 'touchend':
31556            case 'pointerup':
31557            case 'MSPointerUp':
31558            case 'mouseup':
31559            case 'touchcancel':
31560            case 'pointercancel':
31561            case 'MSPointerCancel':
31562            case 'mousecancel':
31563                this._end(e);
31564                break;
31565            case 'orientationchange':
31566            case 'resize':
31567                this._resize();
31568                break;
31569            case 'transitionend':
31570            case 'webkitTransitionEnd':
31571            case 'oTransitionEnd':
31572            case 'MSTransitionEnd':
31573                this._transitionEnd(e);
31574                break;
31575            case 'wheel':
31576            case 'DOMMouseScroll':
31577            case 'mousewheel':
31578                this._wheel(e);
31579                break;
31580            case 'keydown':
31581                this._key(e);
31582                break;
31583            case 'click':
31584                if ( this.enabled && !e._constructed ) {
31585                    e.preventDefault();
31586                    e.stopPropagation();
31587                }
31588                break;
31589        }
31590    }
31591};
31592function createDefaultScrollbar (direction, interactive, type) {
31593    var scrollbar = document.createElement('div'),
31594        indicator = document.createElement('div');
31595
31596    if ( type === true ) {
31597        scrollbar.style.cssText = 'position:absolute;z-index:9999';
31598        indicator.style.cssText = '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;background:rgba(0,0,0,0.5);border:1px solid rgba(255,255,255,0.9);border-radius:3px';
31599    }
31600
31601    indicator.className = 'iScrollIndicator';
31602
31603    if ( direction == 'h' ) {
31604        if ( type === true ) {
31605            scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0';
31606            indicator.style.height = '100%';
31607        }
31608        scrollbar.className = 'iScrollHorizontalScrollbar';
31609    } else {
31610        if ( type === true ) {
31611            scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px';
31612            indicator.style.width = '100%';
31613        }
31614        scrollbar.className = 'iScrollVerticalScrollbar';
31615    }
31616
31617    scrollbar.style.cssText += ';overflow:hidden';
31618
31619    if ( !interactive ) {
31620        scrollbar.style.pointerEvents = 'none';
31621    }
31622
31623    scrollbar.appendChild(indicator);
31624
31625    return scrollbar;
31626}
31627
31628function Indicator (scroller, options) {
31629    this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
31630    this.wrapperStyle = this.wrapper.style;
31631    this.indicator = this.wrapper.children[0];
31632    this.indicatorStyle = this.indicator.style;
31633    this.scroller = scroller;
31634
31635    this.options = {
31636        listenX: true,
31637        listenY: true,
31638        interactive: false,
31639        resize: true,
31640        defaultScrollbars: false,
31641        shrink: false,
31642        fade: false,
31643        speedRatioX: 0,
31644        speedRatioY: 0
31645    };
31646
31647    for ( var i in options ) {
31648        this.options[i] = options[i];
31649    }
31650
31651    this.sizeRatioX = 1;
31652    this.sizeRatioY = 1;
31653    this.maxPosX = 0;
31654    this.maxPosY = 0;
31655
31656    if ( this.options.interactive ) {
31657        if ( !this.options.disableTouch ) {
31658            utils.addEvent(this.indicator, 'touchstart', this);
31659            utils.addEvent(window, 'touchend', this);
31660        }
31661        if ( !this.options.disablePointer ) {
31662            utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
31663            utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this);
31664        }
31665        if ( !this.options.disableMouse ) {
31666            utils.addEvent(this.indicator, 'mousedown', this);
31667            utils.addEvent(window, 'mouseup', this);
31668        }
31669    }
31670
31671    if ( this.options.fade ) {
31672        this.wrapperStyle[utils.style.transform] = this.scroller.translateZ;
31673        var durationProp = utils.style.transitionDuration;
31674        if(!durationProp) {
31675            return;
31676        }
31677        this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms';
31678        // remove 0.0001ms
31679        var self = this;
31680        if(utils.isBadAndroid) {
31681            rAF(function() {
31682                if(self.wrapperStyle[durationProp] === '0.0001ms') {
31683                    self.wrapperStyle[durationProp] = '0s';
31684                }
31685            });
31686        }
31687        this.wrapperStyle.opacity = '0';
31688    }
31689}
31690
31691Indicator.prototype = {
31692    handleEvent: function (e) {
31693        switch ( e.type ) {
31694            case 'touchstart':
31695            case 'pointerdown':
31696            case 'MSPointerDown':
31697            case 'mousedown':
31698                this._start(e);
31699                break;
31700            case 'touchmove':
31701            case 'pointermove':
31702            case 'MSPointerMove':
31703            case 'mousemove':
31704                this._move(e);
31705                break;
31706            case 'touchend':
31707            case 'pointerup':
31708            case 'MSPointerUp':
31709            case 'mouseup':
31710            case 'touchcancel':
31711            case 'pointercancel':
31712            case 'MSPointerCancel':
31713            case 'mousecancel':
31714                this._end(e);
31715                break;
31716        }
31717    },
31718
31719    destroy: function () {
31720        if ( this.options.fadeScrollbars ) {
31721            clearTimeout(this.fadeTimeout);
31722            this.fadeTimeout = null;
31723        }
31724        if ( this.options.interactive ) {
31725            utils.removeEvent(this.indicator, 'touchstart', this);
31726            utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
31727            utils.removeEvent(this.indicator, 'mousedown', this);
31728
31729            utils.removeEvent(window, 'touchmove', this);
31730            utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
31731            utils.removeEvent(window, 'mousemove', this);
31732
31733            utils.removeEvent(window, 'touchend', this);
31734            utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this);
31735            utils.removeEvent(window, 'mouseup', this);
31736        }
31737
31738        if ( this.options.defaultScrollbars ) {
31739            this.wrapper.parentNode.removeChild(this.wrapper);
31740        }
31741    },
31742
31743    _start: function (e) {
31744        var point = e.touches ? e.touches[0] : e;
31745
31746        e.preventDefault();
31747        e.stopPropagation();
31748
31749        this.transitionTime();
31750
31751        this.initiated = true;
31752        this.moved = false;
31753        this.lastPointX = point.pageX;
31754        this.lastPointY = point.pageY;
31755
31756        this.startTime  = utils.getTime();
31757
31758        if ( !this.options.disableTouch ) {
31759            utils.addEvent(window, 'touchmove', this);
31760        }
31761        if ( !this.options.disablePointer ) {
31762            utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this);
31763        }
31764        if ( !this.options.disableMouse ) {
31765            utils.addEvent(window, 'mousemove', this);
31766        }
31767
31768        this.scroller._execEvent('beforeScrollStart');
31769    },
31770
31771    _move: function (e) {
31772        var point = e.touches ? e.touches[0] : e,
31773            deltaX, deltaY,
31774            newX, newY,
31775            timestamp = utils.getTime();
31776
31777        if ( !this.moved ) {
31778            this.scroller._execEvent('scrollStart');
31779        }
31780
31781        this.moved = true;
31782
31783        deltaX = point.pageX - this.lastPointX;
31784        this.lastPointX = point.pageX;
31785
31786        deltaY = point.pageY - this.lastPointY;
31787        this.lastPointY = point.pageY;
31788
31789        newX = this.x + deltaX;
31790        newY = this.y + deltaY;
31791
31792        this._pos(newX, newY);
31793
31794// INSERT POINT: indicator._move
31795
31796        e.preventDefault();
31797        e.stopPropagation();
31798    },
31799
31800    _end: function (e) {
31801        if ( !this.initiated ) {
31802            return;
31803        }
31804
31805        this.initiated = false;
31806
31807        e.preventDefault();
31808        e.stopPropagation();
31809
31810        utils.removeEvent(window, 'touchmove', this);
31811        utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
31812        utils.removeEvent(window, 'mousemove', this);
31813
31814        if ( this.scroller.options.snap ) {
31815            var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y);
31816
31817            var time = this.options.snapSpeed || Math.max(
31818                    Math.max(
31819                        Math.min(Math.abs(this.scroller.x - snap.x), 1000),
31820                        Math.min(Math.abs(this.scroller.y - snap.y), 1000)
31821                    ), 300);
31822
31823            if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) {
31824                this.scroller.directionX = 0;
31825                this.scroller.directionY = 0;
31826                this.scroller.currentPage = snap;
31827                this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing);
31828            }
31829        }
31830
31831        if ( this.moved ) {
31832            this.scroller._execEvent('scrollEnd');
31833        }
31834    },
31835
31836    transitionTime: function (time) {
31837        time = time || 0;
31838        var durationProp = utils.style.transitionDuration;
31839        if(!durationProp) {
31840            return;
31841        }
31842
31843        this.indicatorStyle[durationProp] = time + 'ms';
31844
31845        if ( !time && utils.isBadAndroid ) {
31846            this.indicatorStyle[durationProp] = '0.0001ms';
31847            // remove 0.0001ms
31848            var self = this;
31849            rAF(function() {
31850                if(self.indicatorStyle[durationProp] === '0.0001ms') {
31851                    self.indicatorStyle[durationProp] = '0s';
31852                }
31853            });
31854        }
31855    },
31856
31857    transitionTimingFunction: function (easing) {
31858        this.indicatorStyle[utils.style.transitionTimingFunction] = easing;
31859    },
31860
31861    refresh: function () {
31862        this.transitionTime();
31863
31864        if ( this.options.listenX && !this.options.listenY ) {
31865            this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
31866        } else if ( this.options.listenY && !this.options.listenX ) {
31867            this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
31868        } else {
31869            this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
31870        }
31871
31872        if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) {
31873            utils.addClass(this.wrapper, 'iScrollBothScrollbars');
31874            utils.removeClass(this.wrapper, 'iScrollLoneScrollbar');
31875
31876            if ( this.options.defaultScrollbars && this.options.customStyle ) {
31877                if ( this.options.listenX ) {
31878                    this.wrapper.style.right = '8px';
31879                } else {
31880                    this.wrapper.style.bottom = '8px';
31881                }
31882            }
31883        } else {
31884            utils.removeClass(this.wrapper, 'iScrollBothScrollbars');
31885            utils.addClass(this.wrapper, 'iScrollLoneScrollbar');
31886
31887            if ( this.options.defaultScrollbars && this.options.customStyle ) {
31888                if ( this.options.listenX ) {
31889                    this.wrapper.style.right = '2px';
31890                } else {
31891                    this.wrapper.style.bottom = '2px';
31892                }
31893            }
31894        }
31895
31896        var r = this.wrapper.offsetHeight;  // force refresh
31897
31898        if ( this.options.listenX ) {
31899            this.wrapperWidth = this.wrapper.clientWidth;
31900            if ( this.options.resize ) {
31901                this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
31902                this.indicatorStyle.width = this.indicatorWidth + 'px';
31903            } else {
31904                this.indicatorWidth = this.indicator.clientWidth;
31905            }
31906
31907            this.maxPosX = this.wrapperWidth - this.indicatorWidth;
31908
31909            if ( this.options.shrink == 'clip' ) {
31910                this.minBoundaryX = -this.indicatorWidth + 8;
31911                this.maxBoundaryX = this.wrapperWidth - 8;
31912            } else {
31913                this.minBoundaryX = 0;
31914                this.maxBoundaryX = this.maxPosX;
31915            }
31916
31917            this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
31918        }
31919
31920        if ( this.options.listenY ) {
31921            this.wrapperHeight = this.wrapper.clientHeight;
31922            if ( this.options.resize ) {
31923                this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
31924                this.indicatorStyle.height = this.indicatorHeight + 'px';
31925            } else {
31926                this.indicatorHeight = this.indicator.clientHeight;
31927            }
31928
31929            this.maxPosY = this.wrapperHeight - this.indicatorHeight;
31930
31931            if ( this.options.shrink == 'clip' ) {
31932                this.minBoundaryY = -this.indicatorHeight + 8;
31933                this.maxBoundaryY = this.wrapperHeight - 8;
31934            } else {
31935                this.minBoundaryY = 0;
31936                this.maxBoundaryY = this.maxPosY;
31937            }
31938
31939            this.maxPosY = this.wrapperHeight - this.indicatorHeight;
31940            this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
31941        }
31942
31943        this.updatePosition();
31944    },
31945
31946    updatePosition: function () {
31947        var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
31948            y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
31949
31950        if ( !this.options.ignoreBoundaries ) {
31951            if ( x < this.minBoundaryX ) {
31952                if ( this.options.shrink == 'scale' ) {
31953                    this.width = Math.max(this.indicatorWidth + x, 8);
31954                    this.indicatorStyle.width = this.width + 'px';
31955                }
31956                x = this.minBoundaryX;
31957            } else if ( x > this.maxBoundaryX ) {
31958                if ( this.options.shrink == 'scale' ) {
31959                    this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
31960                    this.indicatorStyle.width = this.width + 'px';
31961                    x = this.maxPosX + this.indicatorWidth - this.width;
31962                } else {
31963                    x = this.maxBoundaryX;
31964                }
31965            } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) {
31966                this.width = this.indicatorWidth;
31967                this.indicatorStyle.width = this.width + 'px';
31968            }
31969
31970            if ( y < this.minBoundaryY ) {
31971                if ( this.options.shrink == 'scale' ) {
31972                    this.height = Math.max(this.indicatorHeight + y * 3, 8);
31973                    this.indicatorStyle.height = this.height + 'px';
31974                }
31975                y = this.minBoundaryY;
31976            } else if ( y > this.maxBoundaryY ) {
31977                if ( this.options.shrink == 'scale' ) {
31978                    this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
31979                    this.indicatorStyle.height = this.height + 'px';
31980                    y = this.maxPosY + this.indicatorHeight - this.height;
31981                } else {
31982                    y = this.maxBoundaryY;
31983                }
31984            } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) {
31985                this.height = this.indicatorHeight;
31986                this.indicatorStyle.height = this.height + 'px';
31987            }
31988        }
31989
31990        this.x = x;
31991        this.y = y;
31992
31993        if ( this.scroller.options.useTransform ) {
31994            this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ;
31995        } else {
31996            this.indicatorStyle.left = x + 'px';
31997            this.indicatorStyle.top = y + 'px';
31998        }
31999    },
32000
32001    _pos: function (x, y) {
32002        if ( x < 0 ) {
32003            x = 0;
32004        } else if ( x > this.maxPosX ) {
32005            x = this.maxPosX;
32006        }
32007
32008        if ( y < 0 ) {
32009            y = 0;
32010        } else if ( y > this.maxPosY ) {
32011            y = this.maxPosY;
32012        }
32013
32014        x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x;
32015        y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y;
32016
32017        this.scroller.scrollTo(x, y);
32018    },
32019
32020    fade: function (val, hold) {
32021        if ( hold && !this.visible ) {
32022            return;
32023        }
32024
32025        clearTimeout(this.fadeTimeout);
32026        this.fadeTimeout = null;
32027
32028        var time = val ? 250 : 500,
32029            delay = val ? 0 : 300;
32030
32031        val = val ? '1' : '0';
32032
32033        this.wrapperStyle[utils.style.transitionDuration] = time + 'ms';
32034
32035        this.fadeTimeout = setTimeout((function (val) {
32036            this.wrapperStyle.opacity = val;
32037            this.visible = +val;
32038        }).bind(this, val), delay);
32039    }
32040};
32041
32042IScroll.utils = utils;
32043
32044if ( typeof module != 'undefined' && module.exports ) {
32045    module.exports = IScroll;
32046} else if ( typeof define == 'function' && define.amd ) {
32047        define( function () { return IScroll; } );
32048} else {
32049    window.IScroll = IScroll;
32050}
32051
32052})(window, document, Math);
32053/*!
32054 * fullPage 2.9.4
32055 * https://github.com/alvarotrigo/fullPage.js
32056 * @license MIT licensed
32057 *
32058 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo
32059 */
32060(function(global, factory) {
32061    'use strict';
32062    if (typeof define === 'function' && define.amd) {
32063        define(['jquery'], function($) {
32064          return factory($, global, global.document, global.Math);
32065        });
32066    } else if (typeof exports === "object" && exports) {
32067        module.exports = factory(require('jquery'), global, global.document, global.Math);
32068    } else {
32069        factory(jQuery, global, global.document, global.Math);
32070    }
32071})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) {
32072    'use strict';
32073
32074    // keeping central set of classnames and selectors
32075    var WRAPPER =               'fullpage-wrapper';
32076    var WRAPPER_SEL =           '.' + WRAPPER;
32077
32078    // slimscroll
32079    var SCROLLABLE =            'fp-scrollable';
32080    var SCROLLABLE_SEL =        '.' + SCROLLABLE;
32081
32082    // util
32083    var RESPONSIVE =            'fp-responsive';
32084    var NO_TRANSITION =         'fp-notransition';
32085    var DESTROYED =             'fp-destroyed';
32086    var ENABLED =               'fp-enabled';
32087    var VIEWING_PREFIX =        'fp-viewing';
32088    var ACTIVE =                'active';
32089    var ACTIVE_SEL =            '.' + ACTIVE;
32090    var COMPLETELY =            'fp-completely';
32091    var COMPLETELY_SEL =        '.' + COMPLETELY;
32092
32093    // section
32094    var SECTION_DEFAULT_SEL =   '.section';
32095    var SECTION =               'fp-section';
32096    var SECTION_SEL =           '.' + SECTION;
32097    var SECTION_ACTIVE_SEL =    SECTION_SEL + ACTIVE_SEL;
32098    var SECTION_FIRST_SEL =     SECTION_SEL + ':first';
32099    var SECTION_LAST_SEL =      SECTION_SEL + ':last';
32100    var TABLE_CELL =            'fp-tableCell';
32101    var TABLE_CELL_SEL =        '.' + TABLE_CELL;
32102    var AUTO_HEIGHT =           'fp-auto-height';
32103    var AUTO_HEIGHT_SEL =       '.fp-auto-height';
32104    var NORMAL_SCROLL =         'fp-normal-scroll';
32105    var NORMAL_SCROLL_SEL =     '.fp-normal-scroll';
32106
32107    // section nav
32108    var SECTION_NAV =           'fp-nav';
32109    var SECTION_NAV_SEL =       '#' + SECTION_NAV;
32110    var SECTION_NAV_TOOLTIP =   'fp-tooltip';
32111    var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP;
32112    var SHOW_ACTIVE_TOOLTIP =   'fp-show-active';
32113
32114    // slide
32115    var SLIDE_DEFAULT_SEL =     '.slide';
32116    var SLIDE =                 'fp-slide';
32117    var SLIDE_SEL =             '.' + SLIDE;
32118    var SLIDE_ACTIVE_SEL =      SLIDE_SEL + ACTIVE_SEL;
32119    var SLIDES_WRAPPER =        'fp-slides';
32120    var SLIDES_WRAPPER_SEL =    '.' + SLIDES_WRAPPER;
32121    var SLIDES_CONTAINER =      'fp-slidesContainer';
32122    var SLIDES_CONTAINER_SEL =  '.' + SLIDES_CONTAINER;
32123    var TABLE =                 'fp-table';
32124
32125    // slide nav
32126    var SLIDES_NAV =            'fp-slidesNav';
32127    var SLIDES_NAV_SEL =        '.' + SLIDES_NAV;
32128    var SLIDES_NAV_LINK_SEL =   SLIDES_NAV_SEL + ' a';
32129    var SLIDES_ARROW =          'fp-controlArrow';
32130    var SLIDES_ARROW_SEL =      '.' + SLIDES_ARROW;
32131    var SLIDES_PREV =           'fp-prev';
32132    var SLIDES_PREV_SEL =       '.' + SLIDES_PREV;
32133    var SLIDES_ARROW_PREV =     SLIDES_ARROW + ' ' + SLIDES_PREV;
32134    var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL;
32135    var SLIDES_NEXT =           'fp-next';
32136    var SLIDES_NEXT_SEL =       '.' + SLIDES_NEXT;
32137    var SLIDES_ARROW_NEXT =     SLIDES_ARROW + ' ' + SLIDES_NEXT;
32138    var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL;
32139
32140    var $window = $(window);
32141    var $document = $(document);
32142
32143    // Default options for iScroll.js used when using scrollOverflow
32144    var iscrollOptions = {
32145        scrollbars: true,
32146        mouseWheel: true,
32147        hideScrollbars: false,
32148        fadeScrollbars: false,
32149        disableMouse: true,
32150        interactiveScrollbars: true,
32151        bounce: false,
32152    };
32153
32154    $.fn.fullpage = function(options) {
32155        //only once my friend!
32156        if($('html').hasClass(ENABLED)){ displayWarnings(); return; }
32157
32158        // common jQuery objects
32159        var $htmlBody = $('html, body');
32160        var $body = $('body');
32161
32162        var FP = $.fn.fullpage;
32163
32164        // Creating some defaults, extending them with any options that were provided
32165        options = $.extend({
32166            //navigation
32167            menu: false,
32168            anchors:[],
32169            lockAnchors: false,
32170            navigation: false,
32171            navigationPosition: 'right',
32172            navigationTooltips: [],
32173            showActiveTooltip: false,
32174            slidesNavigation: false,
32175            slidesNavPosition: 'bottom',
32176            scrollBar: false,
32177            hybrid: false,
32178
32179            //scrolling
32180            css3: true,
32181            scrollingSpeed: 700,
32182            autoScrolling: true,
32183            fitToSection: true,
32184            fitToSectionDelay: 1000,
32185            easing: 'easeInOutCubic',
32186            easingcss3: 'ease',
32187            loopBottom: false,
32188            loopTop: false,
32189            loopHorizontal: true,
32190            continuousVertical: false,
32191            continuousHorizontal: false,
32192            scrollHorizontally: false,
32193            interlockedSlides: false,
32194            dragAndMove: false,
32195            offsetSections: false,
32196            resetSliders: false,
32197            fadingEffect: false,
32198            normalScrollElements: null,
32199            scrollOverflow: false,
32200            scrollOverflowReset: false,
32201            scrollOverflowHandler: iscrollHandler,
32202            scrollOverflowOptions: null,
32203            touchSensitivity: 5,
32204            normalScrollElementTouchThreshold: 5,
32205            bigSectionsDestination: null,
32206
32207            //Accessibility
32208            keyboardScrolling: true,
32209            animateAnchor: true,
32210            recordHistory: true,
32211
32212            //design
32213            controlArrows: true,
32214            controlArrowColor: '#fff',
32215            verticalCentered: true,
32216            sectionsColor : [],
32217            paddingTop: 0,
32218            paddingBottom: 0,
32219            fixedElements: null,
32220            responsive: 0, //backwards compabitility with responsiveWiddth
32221            responsiveWidth: 0,
32222            responsiveHeight: 0,
32223            responsiveSlides: false,
32224            parallax: false,
32225            parallaxOptions: {
32226                type: 'reveal',
32227                percentage: 62,
32228                property: 'translate'
32229            },
32230
32231            //Custom selectors
32232            sectionSelector: SECTION_DEFAULT_SEL,
32233            slideSelector: SLIDE_DEFAULT_SEL,
32234
32235            //events
32236            afterLoad: null,
32237            onLeave: null,
32238            afterRender: null,
32239            afterResize: null,
32240            afterReBuild: null,
32241            afterSlideLoad: null,
32242            onSlideLeave: null,
32243            afterResponsive: null,
32244
32245            lazyLoading: true
32246        }, options);
32247
32248        //flag to avoid very fast sliding for landscape sliders
32249        var slideMoving = false;
32250
32251        var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/);
32252        var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints));
32253        var container = $(this);
32254        var windowsHeight = $window.height();
32255        var isResizing = false;
32256        var isWindowFocused = true;
32257        var lastScrolledDestiny;
32258        var lastScrolledSlide;
32259        var canScroll = true;
32260        var scrollings = [];
32261        var controlPressed;
32262        var startingSection;
32263        var isScrollAllowed = {};
32264        isScrollAllowed.m = {  'up':true, 'down':true, 'left':true, 'right':true };
32265        isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m);
32266        var MSPointer = getMSPointer();
32267        var events = {
32268            touchmove: 'ontouchmove' in window ? 'touchmove' :  MSPointer.move,
32269            touchstart: 'ontouchstart' in window ? 'touchstart' :  MSPointer.down
32270        };
32271
32272        //cheks for passive event support
32273        //added by Uncode from new fullPage updates
32274        var g_supportsPassive = false;
32275        try {
32276          var opts = Object.defineProperty({}, 'passive', {
32277            get: function() {
32278              g_supportsPassive = true;
32279            }
32280          });
32281          window.addEventListener("testPassive", null, opts);
32282          window.removeEventListener("testPassive", null, opts);
32283        } catch (e) {}
32284
32285        //timeouts
32286        var resizeId;
32287        var afterSectionLoadsId;
32288        var afterSlideLoadsId;
32289        var scrollId;
32290        var scrollId2;
32291        var keydownId;
32292        var originals = $.extend(true, {}, options); //deep copy
32293
32294        //Uncode addition
32295        var $masthead = $('#masthead');
32296        var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false;
32297        var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight;
32298        var bodyBorder = UNCODE.bodyBorder;
32299        var adminBarHeight = UNCODE.adminBarHeight;
32300
32301        displayWarnings();
32302
32303        //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783
32304        iscrollOptions.click = isTouch; // see #2035
32305
32306        //extending iScroll options with the user custom ones
32307        iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions);
32308
32309        //easeInOutCubic animation included in the plugin
32310        $.extend($.easing,{ easeInOutCubic: function (x, t, b, c, d) {if ((t/=d/2) < 1) return c/2*t*t*t + b;return c/2*((t-=2)*t*t + 2) + b;}});
32311
32312        /**
32313        * Sets the autoScroll option.
32314        * It changes the scroll bar visibility and the history of the site as a result.
32315        */
32316        function setAutoScrolling(value, type){
32317            //removing the transformation
32318            if(!value){
32319                silentScroll(0);
32320            }
32321
32322            setVariableState('autoScrolling', value, type);
32323
32324            var element = $(SECTION_ACTIVE_SEL);
32325
32326            if(options.autoScrolling && !options.scrollBar){
32327                $htmlBody.css({
32328                    'overflow' : 'hidden !important',
32329                    'height' : '100%'
32330                });
32331
32332                //Uncode addition
32333                //setRecordHistory(originals.recordHistory, 'internal');
32334
32335                //for IE touch devices
32336                container.css({
32337                    '-ms-touch-action': 'none',
32338                    'touch-action': 'none'
32339                });
32340
32341                if(element.length){
32342                    //moving the container up
32343                    silentScroll(element.position().top);
32344                }
32345
32346            }else{
32347                $htmlBody.css({
32348                    'overflow' : 'visible !important',
32349                    'height' : 'initial'
32350                });
32351
32352                //Uncode addition
32353                //setRecordHistory(false, 'internal');
32354
32355                //for IE touch devices
32356                container.css({
32357                    '-ms-touch-action': '',
32358                    'touch-action': ''
32359                });
32360
32361                //scrolling the page to the section with no animation
32362                if (element.length) {
32363                    $htmlBody.scrollTop(element.position().top);
32364                }
32365            }
32366        }
32367
32368        /**
32369        * Defines wheter to record the history for each hash change in the URL.
32370        */
32371        function setRecordHistory(value, type){
32372            setVariableState('recordHistory', value, type);
32373        }
32374
32375        /**
32376        * Defines the scrolling speed
32377        */
32378        function setScrollingSpeed(value, type){
32379            setVariableState('scrollingSpeed', value, type);
32380        }
32381
32382        /**
32383        * Sets fitToSection
32384        */
32385        function setFitToSection(value, type){
32386            setVariableState('fitToSection', value, type);
32387        }
32388
32389        /**
32390        * Sets lockAnchors
32391        */
32392        function setLockAnchors(value){
32393            options.lockAnchors = value;
32394        }
32395
32396        /**
32397        * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad.
32398        */
32399        function setMouseWheelScrolling(value){
32400            if(value){
32401                addMouseWheelHandler();
32402                addMiddleWheelHandler();
32403            }else{
32404                removeMouseWheelHandler();
32405                removeMiddleWheelHandler();
32406            }
32407        }
32408
32409        /**
32410        * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures.
32411        * Optionally a second parameter can be used to specify the direction for which the action will be applied.
32412        *
32413        * @param directions string containing the direction or directions separated by comma.
32414        */
32415        function setAllowScrolling(value, directions){
32416            if(typeof directions !== 'undefined'){
32417                directions = directions.replace(/ /g,'').split(',');
32418
32419                $.each(directions, function (index, direction){
32420                    setIsScrollAllowed(value, direction, 'm');
32421                });
32422            }
32423            else if(value){
32424                setMouseWheelScrolling(true);
32425                addTouchHandler();
32426            }else{
32427                setMouseWheelScrolling(false);
32428                removeTouchHandler();
32429            }
32430        }
32431
32432        /**
32433        * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys
32434        */
32435        function setKeyboardScrolling(value, directions){
32436            if(typeof directions !== 'undefined'){
32437                directions = directions.replace(/ /g,'').split(',');
32438
32439                $.each(directions, function (index, direction){
32440                    setIsScrollAllowed(value, direction, 'k');
32441                });
32442            }else{
32443                options.keyboardScrolling = value;
32444            }
32445        }
32446
32447        /**
32448        * Moves the page up one section.
32449        */
32450        function moveSectionUp(){
32451            var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL);
32452
32453            //looping to the bottom if there's no more sections above
32454            if (!prev.length && (options.loopTop || options.continuousVertical)) {
32455                prev = $(SECTION_SEL).last();
32456            }
32457
32458            if (prev.length) {
32459                scrollPage(prev, null, true);
32460            }
32461        }
32462
32463        /**
32464        * Moves the page down one section.
32465        */
32466        function moveSectionDown(){
32467            var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL);
32468
32469            //looping to the top if there's no more sections below
32470            if(!next.length &&
32471                (options.loopBottom || options.continuousVertical)){
32472                next = $(SECTION_SEL).first();
32473            }
32474
32475            if(next.length){
32476                scrollPage(next, null, false);
32477            }
32478        }
32479
32480        /**
32481        * Moves the page to the given section and slide with no animation.
32482        * Anchors or index positions can be used as params.
32483        */
32484        function silentMoveTo(sectionAnchor, slideAnchor){
32485            setScrollingSpeed (0, 'internal');
32486            moveTo(sectionAnchor, slideAnchor);
32487            setScrollingSpeed (originals.scrollingSpeed, 'internal');
32488        }
32489
32490        /**
32491        * Moves the page to the given section and slide.
32492        * Anchors or index positions can be used as params.
32493        */
32494        function moveTo(sectionAnchor, slideAnchor){
32495            var destiny = getSectionByAnchor(sectionAnchor);
32496
32497            if (typeof slideAnchor !== 'undefined'){
32498                scrollPageAndSlide(sectionAnchor, slideAnchor);
32499            }else if(destiny.length > 0){
32500                scrollPage(destiny);
32501            }
32502        }
32503
32504        /**
32505        * Slides right the slider of the active section.
32506        * Optional `section` param.
32507        */
32508        function moveSlideRight(section){
32509            moveSlide('right', section);
32510        }
32511
32512        /**
32513        * Slides left the slider of the active section.
32514        * Optional `section` param.
32515        */
32516        function moveSlideLeft(section){
32517            moveSlide('left', section);
32518        }
32519
32520        /**
32521         * When resizing is finished, we adjust the slides sizes and positions
32522         */
32523        function reBuild(resizing){
32524            if(container.hasClass(DESTROYED)){ return; }  //nothing to do if the plugin was destroyed
32525
32526            isResizing = true;
32527
32528            windowsHeight = $window.height();  //updating global var
32529
32530            $(SECTION_SEL).each(function(){
32531                var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL);
32532                var slides = $(this).find(SLIDE_SEL);
32533
32534                //adjusting the height of the table-cell for IE and Firefox
32535                if(options.verticalCentered){
32536                    $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px');
32537                }
32538
32539                $(this).css('height', windowsHeight + 'px');
32540
32541                //resizing the scrolling divs
32542                if(options.scrollOverflow){
32543                    if(slides.length){
32544                        slides.each(function(){
32545                            createScrollBar($(this));
32546                        });
32547                    }else{
32548                        createScrollBar($(this));
32549                    }
32550                }
32551
32552                //adjusting the position fo the FULL WIDTH slides...
32553                if (slides.length > 1) {
32554                    landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL));
32555                }
32556            });
32557
32558            var activeSection = $(SECTION_ACTIVE_SEL);
32559            var sectionIndex = activeSection.index(SECTION_SEL);
32560
32561            //isn't it the first section?
32562            if(sectionIndex){
32563                //adjusting the position for the current section
32564                silentMoveTo(sectionIndex + 1);
32565            }
32566
32567            isResizing = false;
32568            // Uncode change
32569            // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container);
32570            $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight());
32571            $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container);
32572        }
32573
32574        /**
32575        * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height`
32576        * are smaller than the set limit values.
32577        */
32578        function setResponsive(active){
32579            var isResponsive = $body.hasClass(RESPONSIVE);
32580
32581            if(active){
32582                if(!isResponsive){
32583                    setAutoScrolling(false, 'internal');
32584                    setFitToSection(false, 'internal');
32585                    $(SECTION_NAV_SEL).hide();
32586                    $body.addClass(RESPONSIVE);
32587                    $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active);
32588                }
32589            }
32590            else if(isResponsive){
32591                setAutoScrolling(originals.autoScrolling, 'internal');
32592                setFitToSection(originals.autoScrolling, 'internal');
32593                $(SECTION_NAV_SEL).show();
32594                $body.removeClass(RESPONSIVE);
32595                $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active);
32596            }
32597        }
32598
32599        if($(this).length){
32600            //public functions
32601            FP.setAutoScrolling = setAutoScrolling;
32602            FP.setRecordHistory = setRecordHistory;
32603            FP.setScrollingSpeed = setScrollingSpeed;
32604            FP.setFitToSection = setFitToSection;
32605            FP.setLockAnchors = setLockAnchors;
32606            FP.setMouseWheelScrolling = setMouseWheelScrolling;
32607            FP.setAllowScrolling = setAllowScrolling;
32608            FP.setKeyboardScrolling = setKeyboardScrolling;
32609            FP.moveSectionUp = moveSectionUp;
32610            FP.moveSectionDown = moveSectionDown;
32611            FP.silentMoveTo = silentMoveTo;
32612            FP.moveTo = moveTo;
32613            FP.moveSlideRight = moveSlideRight;
32614            FP.moveSlideLeft = moveSlideLeft;
32615            FP.fitToSection = fitToSection;
32616            FP.reBuild = reBuild;
32617            FP.setResponsive = setResponsive;
32618            FP.destroy = destroy;
32619
32620            init();
32621
32622            bindEvents();
32623        }
32624
32625        function init(){
32626            //if css3 is not supported, it will use jQuery animations
32627            if(options.css3){
32628                options.css3 = support3d();
32629            }
32630
32631            options.scrollBar = options.scrollBar || options.hybrid;
32632
32633            setOptionsFromDOM();
32634            prepareDom();
32635            setAllowScrolling(true);
32636            setAutoScrolling(options.autoScrolling, 'internal');
32637            responsive();
32638
32639            //setting the class for the body element
32640            setBodyClass();
32641
32642            //Uncode addition
32643            // if(document.readyState === 'complete'){
32644            //     scrollToAnchor();
32645            // }
32646            // $window.on('load', scrollToAnchor);
32647        }
32648
32649        function bindEvents(){
32650            $window
32651                //when scrolling...
32652                //.on('scroll', scrollHandler)
32653
32654                //detecting any change on the URL to scroll to the given anchor link
32655                //(a way to detect back history button as we play with the hashes on the URL)
32656                .on('hashchange', hashChangeHandler)
32657
32658                //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
32659                .blur(blurHandler)
32660
32661                //when resizing the site, we adjust the heights of the sections, slimScroll...
32662                .resize(resizeHandler);
32663
32664            $document
32665                //Sliding with arrow keys, both, vertical and horizontal
32666                .keydown(keydownHandler)
32667
32668                //to prevent scrolling while zooming
32669                .keyup(keyUpHandler)
32670
32671                //Scrolls to the section when clicking the navigation bullet
32672                .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler)
32673
32674                //Scrolls the slider to the given slide destination for the given section
32675                .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler)
32676
32677                .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler);
32678
32679            //Scrolling horizontally when clicking on the slider controls.
32680            $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler);
32681
32682            /**
32683            * Applying normalScroll elements.
32684            * Ignoring the scrolls over the specified selectors.
32685            */
32686            if(options.normalScrollElements){
32687                $document.on('mouseenter', options.normalScrollElements, function () {
32688                    setMouseWheelScrolling(false);
32689                });
32690
32691                $document.on('mouseleave', options.normalScrollElements, function(){
32692                    setMouseWheelScrolling(true);
32693                });
32694            }
32695        }
32696
32697        /**
32698        * Setting options from DOM elements if they are not provided.
32699        */
32700        function setOptionsFromDOM(){
32701            var sections = container.find(options.sectionSelector);
32702
32703            //no anchors option? Checking for them in the DOM attributes
32704            if(!options.anchors.length){
32705                options.anchors = sections.filter('[data-anchor]').map(function(){
32706                    return $(this).data('anchor').toString();
32707                }).get();
32708            }
32709
32710            //no tooltips option? Checking for them in the DOM attributes
32711            if(!options.navigationTooltips.length){
32712                options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){
32713                    return $(this).data('tooltip').toString();
32714                }).get();
32715            }
32716        }
32717
32718        /**
32719        * Works over the DOM structure to set it up for the current fullpage options.
32720        */
32721        function prepareDom(){
32722            container.css({
32723                'height': '100%',
32724                'position': 'relative'
32725            });
32726
32727            //adding a class to recognize the container internally in the code
32728            container.addClass(WRAPPER);
32729            $('html').addClass(ENABLED);
32730
32731            windowsHeight = $window.height();
32732
32733            container.removeClass(DESTROYED); //in case it was destroyed before initializing it again
32734
32735            addInternalSelectors();
32736
32737             //styling the sections / slides / menu
32738            $(SECTION_SEL).each(function(index){
32739                var section = $(this);
32740                var slides = section.find(SLIDE_SEL);
32741                var numSlides = slides.length;
32742
32743                styleSection(section, index);
32744                styleMenu(section, index);
32745
32746                // if there's any slide
32747                if (numSlides > 0) {
32748                    styleSlides(section, slides, numSlides);
32749                }else{
32750                    if(options.verticalCentered){
32751                        addTableClass(section);
32752                    }
32753                }
32754            });
32755
32756            //fixed elements need to be moved out of the plugin container due to problems with CSS3.
32757            if(options.fixedElements && options.css3){
32758                $(options.fixedElements).appendTo($body);
32759            }
32760
32761            //vertical centered of the navigation + active bullet
32762            if(options.navigation){
32763                addVerticalNavigation();
32764            }
32765
32766            enableYoutubeAPI();
32767
32768            if(options.scrollOverflow){
32769                if(document.readyState === 'complete'){
32770                    createScrollBarHandler();
32771                }
32772                //after DOM and images are loaded
32773                $window.on('load', createScrollBarHandler);
32774            }else{
32775                afterRenderActions();
32776            }
32777        }
32778
32779        /**
32780        * Styles the horizontal slides for a section.
32781        */
32782        function styleSlides(section, slides, numSlides){
32783            var sliderWidth = numSlides * 100;
32784            var slideWidth = 100 / numSlides;
32785
32786            slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />');
32787            slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />');
32788
32789            section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%');
32790
32791            if(numSlides > 1){
32792                if(options.controlArrows){
32793                    createSlideArrows(section);
32794                }
32795
32796                if(options.slidesNavigation){
32797                    addSlidesNavigation(section, numSlides);
32798                }
32799            }
32800
32801            slides.each(function(index) {
32802                $(this).css('width', slideWidth + '%');
32803
32804                if(options.verticalCentered){
32805                    addTableClass($(this));
32806                }
32807            });
32808
32809            var startingSlide = section.find(SLIDE_ACTIVE_SEL);
32810
32811            //if the slide won't be an starting point, the default will be the first one
32812            //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
32812ide by default.
32813            if( startingSlide.length &&  ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){
32814                silentLandscapeScroll(startingSlide, 'internal');
32815            }else{
32816                slides.eq(0).addClass(ACTIVE);
32817            }
32818        }
32819
32820        /**
32821        * Styling vertical sections
32822        */
32823        function styleSection(section, index){
32824            //if no active section is defined, the 1st one will be the default one
32825            if(!index && $(SECTION_ACTIVE_SEL).length === 0) {
32826                section.addClass(ACTIVE);
32827            }
32828            startingSection = $(SECTION_ACTIVE_SEL);
32829
32830            section.css('height', windowsHeight + 'px');
32831
32832            if(options.paddingTop){
32833                section.css('padding-top', options.paddingTop);
32834            }
32835
32836            if(options.paddingBottom){
32837                section.css('padding-bottom', options.paddingBottom);
32838            }
32839
32840            if (typeof options.sectionsColor[index] !==  'undefined') {
32841                section.css('background-color', options.sectionsColor[index]);
32842            }
32843
32844            if (typeof options.anchors[index] !== 'undefined') {
32845                section.attr('data-anchor', options.anchors[index]);
32846            }
32847        }
32848
32849        /**
32850        * Sets the data-anchor attributes to the menu elements and activates the current one.
32851        */
32852        function styleMenu(section, index){
32853            if (typeof options.anchors[index] !== 'undefined') {
32854                //activating the menu / nav element on load
32855                if(section.hasClass(ACTIVE)){
32856                    activateMenuAndNav(options.anchors[index], index);
32857                }
32858            }
32859
32860            //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms)
32861            if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){
32862                $(options.menu).appendTo($body);
32863            }
32864        }
32865
32866        /**
32867        * Adds internal classes to be able to provide customizable selectors
32868        * keeping the link with the style sheet.
32869        */
32870        function addInternalSelectors(){
32871            container.find(options.sectionSelector).addClass(SECTION);
32872            container.find(options.slideSelector).addClass(SLIDE);
32873        }
32874
32875        /**
32876        * Creates the control arrows for the given section
32877        */
32878        function createSlideArrows(section){
32879            section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>');
32880
32881            if(options.controlArrowColor!='#fff'){
32882                section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor);
32883                section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent');
32884            }
32885
32886            if(!options.loopHorizontal){
32887                section.find(SLIDES_ARROW_PREV_SEL).hide();
32888            }
32889        }
32890
32891        /**
32892        * Creates a vertical navigation bar.
32893        */
32894        function addVerticalNavigation(){
32895            $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>');
32896            var nav = $(SECTION_NAV_SEL);
32897
32898            nav.addClass(function() {
32899                return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition;
32900            });
32901
32902            for (var i = 0; i < $(SECTION_SEL).length; i++) {
32903                var link = '';
32904                if (options.anchors.length) {
32905                    link = options.anchors[i];
32906                }
32907
32908                var li = '<li><a href="#' + link + '"><span></span></a>';
32909
32910                // Only add tooltip if needed (defined by user)
32911                var tooltip = options.navigationTooltips[i];
32912
32913                if (typeof tooltip !== 'undefined' && tooltip !== '') {
32914                    li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>';
32915                }
32916
32917                li += '</li>';
32918
32919                nav.find('ul').append(li);
32920            }
32921
32922            //centering it vertically
32923            $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px');
32924
32925            //activating the current active section
32926            $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE);
32927        }
32928
32929        /**
32930        * Creates the slim scroll scrollbar for the sections and slides inside them.
32931        */
32932        function createScrollBarHandler(){
32933            $(SECTION_SEL).each(function(){
32934                var slides = $(this).find(SLIDE_SEL);
32935
32936                if(slides.length){
32937                    slides.each(function(){
32938                        createScrollBar($(this));
32939                    });
32940                }else{
32941                    createScrollBar($(this));
32942                }
32943
32944            });
32945            afterRenderActions();
32946        }
32947
32948        /*
32949        * Enables the Youtube videos API so we can control their flow if necessary.
32950        */
32951        function enableYoutubeAPI(){
32952            container.find('iframe[src*="youtube.com/embed/"]').each(function(){
32953                addURLParam($(this), 'enablejsapi=1');
32954            });
32955        }
32956
32957        /**
32958        * Adds a new parameter and its value to the `src` of a given element
32959        */
32960        function addURLParam(element, newParam){
32961            var originalSrc = element.attr('src');
32962            element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam);
32963        }
32964
32965        /*
32966        * Returns the prefix sign to use for a new parameter in an existen URL.
32967        *
32968        * @return {String}  ? | &
32969        */
32970        function getUrlParamSign(url){
32971            return ( !/\?/.test( url ) ) ? '?' : '&';
32972        }
32973
32974        /**
32975        * Actions and callbacks to fire afterRender
32976        */
32977        function afterRenderActions(){
32978            var section = $(SECTION_ACTIVE_SEL);
32979
32980            section.addClass(COMPLETELY);
32981
32982            if(options.scrollOverflowHandler.afterRender){
32983                options.scrollOverflowHandler.afterRender(section);
32984            }
32985            lazyLoad(section);
32986            playMedia(section);
32987            options.scrollOverflowHandler.afterLoad();
32988
32989            if(isDestinyTheStartingSection()){
32990                $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1));
32991            }
32992
32993            // Uncode change
32994            // $.isFunction( options.afterRender ) && options.afterRender.call(container);
32995            $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight());
32996        }
32997
32998        /**
32999        * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization)
33000        */
33001        function isDestinyTheStartingSection(){
33002            var anchors =  window.location.hash.replace('#', '').split('/');
33003            var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0]));
33004
33005            return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index();
33006        }
33007
33008
33009        var isScrolling = false;
33010        var lastScroll = 0;
33011
33012        //when scrolling...
33013        function scrollHandler(){
33014            var currentSection;
33015
33016            if(!options.autoScrolling || options.scrollBar){
33017                var currentScroll = $window.scrollTop();
33018                var scrollDirection = getScrollDirection(currentScroll);
33019                var visibleSectionIndex = 0;
33020                var screen_mid = currentScroll + ($window.height() / 2.0);
33021                var isAtBottom = $body.height() - $window.height() === currentScroll;
33022                var sections =  document.querySelectorAll(SECTION_SEL);
33023
33024                //when using `auto-height` for a small last section it won't be centered in the viewport
33025                if(isAtBottom){
33026                    visibleSectionIndex = sections.length - 1;
33027                }
33028                //is at top? when using `auto-height` for a small first section it won't be centered in the viewport
33029                else if(!currentScroll){
33030                    visibleSectionIndex = 0;
33031                }
33032
33033                //taking the section which is showing more content in the viewport
33034                else{
33035                    for (var i = 0; i < sections.length; ++i) {
33036                        var section = sections[i];
33037
33038                        // Pick the the last section which passes the middle line of the screen.
33039                        if (section.offsetTop <= screen_mid)
33040                        {
33041                            visibleSectionIndex = i;
33042                        }
33043                    }
33044                }
33045
33046                if(isCompletelyInViewPort(scrollDirection)){
33047                    if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){
33048                        $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY);
33049                    }
33050                }
33051
33052                //geting the last one, the current one on the screen
33053                currentSection = $(sections).eq(visibleSectionIndex);
33054
33055                //setting the visible section as active when manually scrolling
33056                //executing only once the first time we reach the section
33057                if(!currentSection.hasClass(ACTIVE)){
33058                    isScrolling = true;
33059                    var leavingSection = $(SECTION_ACTIVE_SEL);
33060                    var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1;
33061                    var yMovement = getYmovement(currentSection);
33062                    var anchorLink  = currentSection.data('anchor');
33063                    var sectionIndex = currentSection.index(SECTION_SEL) + 1;
33064                    var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL);
33065                    var slideIndex;
33066                    var slideAnchorLink;
33067
33068                    if(activeSlide.length){
33069                        slideAnchorLink = activeSlide.data('anchor');
33070                        slideIndex = activeSlide.index();
33071                    }
33072
33073                    if(canScroll){
33074                        currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE);
33075
33076                        $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement);
33077                        $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex);
33078
33079                        stopMedia(leavingSection);
33080                        lazyLoad(currentSection);
33081                        playMedia(currentSection);
33082
33083                        activateMenuAndNav(anchorLink, sectionIndex - 1);
33084
33085                        if(options.anchors.length){
33086                            //needed to enter in hashChange event when using the menu with anchor links
33087                            lastScrolledDestiny = anchorLink;
33088                        }
33089                        setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex);
33090                    }
33091
33092                    //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet
33093                    clearTimeout(scrollId);
33094                    scrollId = setTimeout(function(){
33095                        isScrolling = false;
33096                    }, 100);
33097                }
33098
33099                if(options.fitToSection){
33100                    //for the auto adjust of the viewport to fit a whole section
33101                    clearTimeout(scrollId2);
33102
33103                    scrollId2 = setTimeout(function(){
33104                        //checking it again in case it changed during the delay
33105                        if(options.fitToSection){
33106                            fitToSection();
33107                        }
33108                    }, options.fitToSectionDelay);
33109                }
33110            }
33111        }
33112
33113        /**
33114        * Fits the site to the nearest active section
33115        */
33116        function fitToSection(){
33117            //checking fitToSection again in case it was set to false before the timeout delay
33118            if(canScroll){
33119                //allows to scroll to an active section and
33120                //if the section is already active, we prevent firing callbacks
33121                isResizing = true;
33122
33123                scrollPage($(SECTION_ACTIVE_SEL));
33124                isResizing = false;
33125            }
33126        }
33127
33128        /**
33129        * Determines whether the active section has seen in its whole or not.
33130        */
33131        function isCompletelyInViewPort(movement){
33132            var top = $(SECTION_ACTIVE_SEL).position().top;
33133            var bottom = top + $window.height();
33134
33135            if(movement == 'up'){
33136                return bottom >= ($window.scrollTop() + $window.height());
33137            }
33138            return top <= $window.scrollTop();
33139        }
33140
33141        /**
33142        * Gets the directon of the the scrolling fired by the scroll event.
33143        */
33144        function getScrollDirection(currentScroll){
33145            var direction = currentScroll > lastScroll ? 'down' : 'up';
33146
33147            lastScroll = currentScroll;
33148
33149            //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination
33150            previousDestTop = currentScroll;
33151
33152            return direction;
33153        }
33154
33155        /**
33156        * Determines the way of scrolling up or down:
33157        * by 'automatically' scrolling a section or by using the default and normal scrolling.
33158        */
33159        function scrolling(type, scrollable){
33160            if (!isScrollAllowed.m[type]){
33161                return;
33162            }
33163            var check = (type === 'down') ? 'bottom' : 'top';
33164            var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp;
33165
33166            if(scrollable.length > 0 ){
33167                //is the scrollbar at the start/end of the scroll?
33168                if(options.scrollOverflowHandler.isScrolled(check, scrollable)){
33169                    scrollSection();
33170                }else{
33171                    return true;
33172                }
33173            }else{
33174                // moved up/down
33175                scrollSection();
33176            }
33177        }
33178
33179        /*
33180        * Preventing bouncing in iOS #2285
33181        */
33182        function preventBouncing(event){
33183            var e = event.originalEvent;
33184            if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){
33185                //preventing the easing on iOS devices
33186                event.preventDefault();
33187            }
33188        }
33189
33190        var touchStartY = 0;
33191        var touchStartX = 0;
33192        var touchEndY = 0;
33193        var touchEndX = 0;
33194
33195        /* Detecting touch events
33196
33197        * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it.
33198        * This way, the touchstart and the touch moves shows an small difference between them which is the
33199        * used one to determine the direction.
33200        */
33201        function touchMoveHandler(event){
33202            var e = event.originalEvent;
33203            var activeSection = $(e.target).closest(SECTION_SEL);
33204
33205            // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain
33206            if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) {
33207
33208                if(options.autoScrolling){
33209                    //preventing the easing on iOS devices
33210                    event.preventDefault();
33211                }
33212
33213                var scrollable = options.scrollOverflowHandler.scrollable(activeSection);
33214                var touchEvents = getEventsPage(e);
33215
33216                touchEndY = touchEvents.y;
33217                touchEndX = touchEvents.x;
33218
33219                //if movement in the X axys is greater than in the Y and the currect section has slides...
33220                if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) {
33221
33222                    //is the movement greater than the minimum resistance to scroll?
33223                    if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) {
33224                        if (touchStartX > touchEndX) {
33225                            if(isScrollAllowed.m.right){
33226                                moveSlideRight(activeSection); //next
33227                            }
33228                        } else {
33229                            if(isScrollAllowed.m.left){
33230                                moveSlideLeft(activeSection); //prev
33231                            }
33232                        }
33233                    }
33234                }
33235
33236                //vertical scrolling (only when autoScrolling is enabled)
33237                else if(options.autoScrolling && canScroll){
33238
33239                    //is the movement greater than the minimum resistance to scroll?
33240                    if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) {
33241                        if (touchStartY > touchEndY) {
33242                            scrolling('down', scrollable);
33243                        } else if (touchEndY > touchStartY) {
33244                            scrolling('up', scrollable);
33245                        }
33246                    }
33247                }
33248            }
33249        }
33250
33251        /**
33252         * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements
33253         * Currently works well for iOS - Android might need some testing
33254         * @param  {Element} el  target element / jquery selector (in subsequent nodes)
33255         * @param  {int}     hop current hop compared to options.normalScrollElementTouchThreshold
33256         * @return {boolean} true if there is a match to options.normalScrollElements
33257         */
33258        function checkParentForNormalScrollElement (el, hop) {
33259            hop = hop || 0;
33260            var parent = $(el).parent();
33261
33262            if (hop < options.normalScrollElementTouchThreshold &&
33263                parent.is(options.normalScrollElements) ) {
33264                return true;
33265            } else if (hop == options.normalScrollElementTouchThreshold) {
33266                return false;
33267            } else {
33268                return checkParentForNormalScrollElement(parent, ++hop);
33269            }
33270        }
33271
33272        /**
33273        * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen
33274        * this way we make sure that is really a touch event what IE is detecting.
33275        */
33276        function isReallyTouch(e){
33277            //if is not IE   ||  IE is detecting `touch` or `pen`
33278            return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse';
33279        }
33280
33281        /**
33282        * Handler for the touch start event.
33283        */
33284        function touchStartHandler(event){
33285            var e = event.originalEvent;
33286
33287            //stopping the auto scroll to adjust to a section
33288            if(options.fitToSection){
33289                $htmlBody.stop();
33290            }
33291
33292            if(isReallyTouch(e)){
33293                var touchEvents = getEventsPage(e);
33294                touchStartY = touchEvents.y;
33295                touchStartX = touchEvents.x;
33296            }
33297        }
33298
33299        /**
33300        * Gets the average of the last `number` elements of the given array.
33301        */
33302        function getAverage(elements, number){
33303            var sum = 0;
33304
33305            //taking `number` elements from the end to make the average, if there are not enought, 1
33306            var lastElements = elements.slice(Math.max(elements.length - number, 1));
33307
33308            for(var i = 0; i < lastElements.length; i++){
33309                sum = sum + lastElements[i];
33310            }
33311
33312            return Math.ceil(sum/number);
33313        }
33314
33315        /**
33316         * Detecting mousewheel scrolling
33317         *
33318         * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html
33319         * http://www.sitepoint.com/html5-javascript-mouse-wheel/
33320         */
33321        var prevTime = new Date().getTime();
33322
33323        function MouseWheelHandler(e) {
33324            var curTime = new Date().getTime();
33325            var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL);
33326
33327            //autoscrolling and not zooming?
33328            if(options.autoScrolling && !controlPressed && !isNormalScroll){
33329                // cross-browser wheel delta
33330                e = e || window.event;
33331                var value = e.wheelDelta || -e.deltaY || -e.detail;
33332                var delta = Math.max(-1, Math.min(1, value));
33333
33334                var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined';
33335                var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection);
33336
33337                //Limiting the array to 150 (lets not waste memory!)
33338                if(scrollings.length > 149){
33339                    scrollings.shift();
33340                }
33341
33342                //keeping record of the previous scrollings
33343                scrollings.push(Math.abs(value));
33344
33345                //preventing to scroll the site on mouse wheel when scrollbar is present
33346                if(options.scrollBar){
33347                    e.preventDefault ? e.preventDefault() : e.returnValue = false;
33348                }
33349
33350                var activeSection = $(SECTION_ACTIVE_SEL);
33351                var scrollable = options.scrollOverflowHandler.scrollable(activeSection);
33352
33353                //time difference between the last scroll and the current one
33354                var timeDiff = curTime-prevTime;
33355                prevTime = curTime;
33356
33357                //haven't they scrolled in a while?
33358                //(enough to be consider a different scrolling action to scroll another section)
33359                if(timeDiff > 200){
33360                    //emptying the array, we dont care about old scrollings for our averages
33361                    scrollings = [];
33362                }
33363
33364                if(canScroll){
33365                    var averageEnd = getAverage(scrollings, 10);
33366                    var averageMiddle = getAverage(scrollings, 70);
33367                    var isAccelerating = averageEnd >= averageMiddle;
33368
33369                    //to avoid double swipes...
33370                    if(isAccelerating && isScrollingVertically){
33371                        //scrolling down?
33372                        if (delta < 0) {
33373                            scrolling('down', scrollable);
33374
33375                        //scrolling up?
33376                        }else {
33377                            scrolling('up', scrollable);
33378                        }
33379                    }
33380                }
33381
33382                return false;
33383            }
33384
33385            if(options.fitToSection){
33386                //stopping the auto scroll to adjust to a section
33387                $htmlBody.stop();
33388            }
33389        }
33390
33391        /**
33392        * Slides a slider to the given direction.
33393        * Optional `section` param.
33394        */
33395        function moveSlide(direction, section){
33396            var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section;
33397            var slides = activeSection.find(SLIDES_WRAPPER_SEL);
33398            var numSlides = slides.find(SLIDE_SEL).length;
33399
33400            // more than one slide needed and nothing should be sliding
33401            if (!slides.length || slideMoving || numSlides < 2) {
33402                return;
33403            }
33404
33405            var currentSlide = slides.find(SLIDE_ACTIVE_SEL);
33406            var destiny = null;
33407
33408            if(direction === 'left'){
33409                destiny = currentSlide.prev(SLIDE_SEL);
33410            }else{
33411                destiny = currentSlide.next(SLIDE_SEL);
33412            }
33413
33414            //isn't there a next slide in the secuence?
33415            if(!destiny.length){
33416                //respect loopHorizontal settin
33417                if (!options.loopHorizontal) return;
33418
33419                if(direction === 'left'){
33420                    destiny = currentSlide.siblings(':last');
33421                }else{
33422                    destiny = currentSlide.siblings(':first');
33423                }
33424            }
33425
33426            slideMoving = true;
33427
33428            landscapeScroll(slides, destiny, direction);
33429        }
33430
33431        /**
33432        * Maintains the active slides in the viewport
33433        * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical)
33434        */
33435        function keepSlidesPosition(){
33436            $(SLIDE_ACTIVE_SEL).each(function(){
33437                silentLandscapeScroll($(this), 'internal');
33438            });
33439        }
33440
33441        var previousDestTop = 0;
33442        /**
33443        * Returns the destination Y position based on the scrolling direction and
33444        * the height of the section.
33445        */
33446        function getDestinationPosition(element){
33447            var elemPosition = element.position();
33448
33449            //top of the desination will be at the top of the viewport
33450            var position = elemPosition.top;
33451            var isScrollingDown =  elemPosition.top > previousDestTop;
33452            var sectionBottom = position - windowsHeight + element.outerHeight();
33453            var bigSectionsDestination = options.bigSectionsDestination;
33454
33455            //Uncode addition
33456            var containerH = container.outerHeight();
33457            var containerPosition = container.offset();
33458
33459            //########### Commented by Uncode - START ###########
33460            //is the destination element bigger than the viewport?
33461            // if(element.outerHeight() > windowsHeight){
33462            //     //scrolling up?
33463            //     if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){
33464            //         position = sectionBottom;
33465            //     }
33466            // }
33467
33468            // //sections equal or smaller than the viewport height && scrolling down? ||  is resizing and its in the last section
33469            // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){
33470            //     //The bottom of the destination will be at the bottom of the viewport
33471            //     position = sectionBottom;
33472            // }
33473            //########### Commented by Uncode - END ###########
33474
33475            //Uncode addition
33476            if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') )
33477                position += 18;
33478            if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) {
33479                position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight;
33480            }
33481
33482            /*
33483            Keeping record of the last scrolled position to determine the scrolling direction.
33484            No conventional methods can be used as the scroll bar might not be present
33485            AND the section might not be active if it is auto-height and didnt reach the middle
33486            of the viewport.
33487            */
33488            previousDestTop = position;
33489            return position;
33490        }
33491
33492        /**
33493        * Scrolls the site to the given element and scrolls to the slide if a callback is given.
33494        */
33495        function scrollPage(element, callback, isMovementUp){
33496            if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function
33497
33498            var dtop = getDestinationPosition(element);
33499            var slideAnchorLink;
33500            var slideIndex;
33501
33502            //local variables
33503            var v = {
33504                element: element,
33505                callback: callback,
33506                isMovementUp: isMovementUp,
33507                dtop: dtop,
33508                yMovement: getYmovement(element),
33509                anchorLink: element.data('anchor'),
33510                sectionIndex: element.index(SECTION_SEL),
33511                activeSlide: element.find(SLIDE_ACTIVE_SEL),
33512                activeSection: $(SECTION_ACTIVE_SEL),
33513                leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1,
33514
33515                //caching the value of isResizing at the momment the function is called
33516                //because it will be checked later inside a setTimeout and the value might change
33517                localIsResizing: isResizing
33518            };
33519
33520            //quiting when destination scroll is the same as the current one
33521            if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; }
33522
33523            if(v.activeSlide.length){
33524                slideAnchorLink = v.activeSlide.data('anchor');
33525                slideIndex = v.activeSlide.index();
33526            }
33527
33528            // If continuousVertical && we need to wrap around
33529            if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" &&
33530                ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or
33531                (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down
33532
33533                v = createInfiniteSections(v);
33534            }
33535
33536            //callback (onLeave) if the site is not just resizing and readjusting the slides
33537            if($.isFunction(options.onLeave) && !v.localIsResizing){
33538                if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){
33539                    return;
33540                }
33541            }
33542
33543            //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one)
33544            if(!v.localIsResizing){
33545                stopMedia(v.activeSection);
33546            }
33547
33548            options.scrollOverflowHandler.beforeLeave();
33549            element.addClass(ACTIVE).siblings().removeClass(ACTIVE);
33550            lazyLoad(element);
33551            options.scrollOverflowHandler.onLeave();
33552
33553
33554            //preventing from activating the MouseWheelHandler event
33555            //more than once if the page is scrolling
33556            canScroll = false;
33557
33558            setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex);
33559
33560            performMovement(v);
33561
33562            //flag to avoid callingn `scrollPage()` twice in case of using anchor links
33563            lastScrolledDestiny = v.anchorLink;
33564
33565            //avoid firing it twice (as it does also on scroll)
33566            activateMenuAndNav(v.anchorLink, v.sectionIndex);
33567        }
33568
33569        /**
33570        * Performs the vertical movement (by CSS3 or by jQuery)
33571        */
33572        function performMovement(v){
33573            // using CSS3 translate functionality
33574            if (options.css3 && options.autoScrolling && !options.scrollBar) {
33575
33576                // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
33577                // that's why we round it to 0.
33578                var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)';
33579                transformContainer(translate3d, true);
33580
33581                //even when the scrollingSpeed is 0 there's a little delay, which might cause the
33582                //scrollingSpeed to change in case of using silentMoveTo();
33583                if(options.scrollingSpeed){
33584                    clearTimeout(afterSectionLoadsId);
33585                    afterSectionLoadsId = setTimeout(function () {
33586                        afterSectionLoads(v);
33587                    }, options.scrollingSpeed);
33588                }else{
33589                    afterSectionLoads(v);
33590                }
33591            }
33592
33593            // using jQuery animate
33594            else{
33595                var scrollSettings = getScrollSettings(v);
33596
33597                $(scrollSettings.element).animate(
33598                    scrollSettings.options,
33599                options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating  `html, body`
33600                    if(options.scrollBar){
33601
33602                        /* Hack!
33603                        The timeout prevents setting the most dominant section in the viewport as "active" when the user
33604                        scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar.
33605
33606                        When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished.
33607                        */
33608                        setTimeout(function(){
33609                            afterSectionLoads(v);
33610                        },30);
33611                    }else{
33612                        afterSectionLoads(v);
33613                    }
33614                });
33615            }
33616        }
33617
33618        /**
33619        * Gets the scrolling settings depending on the plugin autoScrolling option
33620        */
33621        function getScrollSettings(v){
33622            var scroll = {};
33623
33624            if(options.autoScrolling && !options.scrollBar){
33625                scroll.options = { 'top': -v.dtop};
33626                scroll.element = WRAPPER_SEL;
33627            }else{
33628                scroll.options = { 'scrollTop': v.dtop};
33629                scroll.element = 'html, body';
33630            }
33631
33632            return scroll;
33633        }
33634
33635        /**
33636        * Adds sections before or after the current one to create the infinite effect.
33637        */
33638        function createInfiniteSections(v){
33639            // Scrolling down
33640            if (!v.isMovementUp) {
33641                // Move all previous sections to after the active section
33642                $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse());
33643            }
33644            else { // Scrolling up
33645                // Move all next sections to before the active section
33646                $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL));
33647            }
33648
33649            // Maintain the displayed position (now that we changed the element order)
33650            silentScroll($(SECTION_ACTIVE_SEL).position().top);
33651
33652            // Maintain the active slides visible in the viewport
33653            keepSlidesPosition();
33654
33655            // save for later the elements that still need to be reordered
33656            v.wrapAroundElements = v.activeSection;
33657
33658            // Recalculate animation variables
33659            v.dtop = v.element.position().top;
33660            v.yMovement = getYmovement(v.element);
33661
33662            return v;
33663        }
33664
33665        /**
33666        * Fix section order after continuousVertical changes have been animated
33667        */
33668        function continuousVerticalFixSectionOrder (v) {
33669            // If continuousVertical is in effect (and autoScrolling would also be in effect then),
33670            // finish moving the elements around so the direct navigation will function more simply
33671            if (!v.wrapAroundElements || !v.wrapAroundElements.length) {
33672                return;
33673            }
33674
33675            if (v.isMovementUp) {
33676                $(SECTION_FIRST_SEL).before(v.wrapAroundElements);
33677            }
33678            else {
33679                $(SECTION_LAST_SEL).after(v.wrapAroundElements);
33680            }
33681
33682            silentScroll($(SECTION_ACTIVE_SEL).position().top);
33683
33684            // Maintain the active slides visible in the viewport
33685            keepSlidesPosition();
33686        }
33687
33688
33689        /**
33690        * Actions to do once the section is loaded.
33691        */
33692        function afterSectionLoads (v){
33693            continuousVerticalFixSectionOrder(v);
33694
33695            //callback (afterLoad) if the site is not just resizing and readjusting the slides
33696            $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1));
33697            options.scrollOverflowHandler.afterLoad();
33698
33699            if(!v.localIsResizing){
33700                playMedia(v.element);
33701            }
33702
33703            v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY);
33704
33705            canScroll = true;
33706
33707            $.isFunction(v.callback) && v.callback.call(this);
33708        }
33709
33710        /**
33711        * Sets the value for the given attribute from the `data-` attribute with the same suffix
33712        * ie: data-srcset ==> srcset  |  data-src ==> src
33713        */
33714        function setSrc(element, attribute){
33715            element
33716                .attr(attribute, element.data(attribute))
33717                .removeAttr('data-' + attribute);
33718        }
33719
33720        /**
33721        * Lazy loads image, video and audio elements.
33722        */
33723        function lazyLoad(destiny){
33724            if (!options.lazyLoading){
33725                return;
33726            }
33727
33728            var panel = getSlideOrSection(destiny);
33729            var element;
33730
33731            panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){
33732                element = $(this);
33733
33734                $.each(['src', 'srcset'], function(index, type){
33735                    var attribute = element.attr('data-' + type);
33736                    if(typeof attribute !== 'undefined' && attribute){
33737                        setSrc(element, type);
33738                    }
33739                });
33740
33741                if(element.is('source')){
33742                    element.closest('video').get(0).load();
33743                }
33744            });
33745        }
33746
33747        /**
33748        * Plays video and audio elements.
33749        */
33750        function playMedia(destiny){
33751            var panel = getSlideOrSection(destiny);
33752
33753            //playing HTML5 media elements
33754            panel.find('video, audio').each(function(){
33755                var element = $(this).get(0);
33756
33757                if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) {
33758                    element.play();
33759                }
33760            });
33761
33762            //youtube videos
33763            panel.find('iframe[src*="youtube.com/embed/"]').each(function(){
33764                var element = $(this).get(0);
33765
33766                if ( element.hasAttribute('data-autoplay') ){
33767                    playYoutube(element);
33768                }
33769
33770                //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load.
33771                element.onload = function() {
33772                    if ( element.hasAttribute('data-autoplay') ){
33773                        playYoutube(element);
33774                    }
33775                };
33776            });
33777        }
33778
33779        /**
33780        * Plays a youtube video
33781        */
33782        function playYoutube(element){
33783            element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
33784        }
33785
33786        /**
33787        * Stops video and audio elements.
33788        */
33789        function stopMedia(destiny){
33790            var panel = getSlideOrSection(destiny);
33791
33792            //stopping HTML5 media elements
33793            panel.find('video, audio').each(function(){
33794                var element = $(this).get(0);
33795
33796                if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) {
33797                    element.pause();
33798                }
33799            });
33800
33801            //youtube videos
33802            panel.find('iframe[src*="youtube.com/embed/"]').each(function(){
33803                var element = $(this).get(0);
33804
33805                if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){
33806                    $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*');
33807                }
33808            });
33809        }
33810
33811        /**
33812        * Gets the active slide (or section) for the given section
33813        */
33814        function getSlideOrSection(destiny){
33815            var slide = destiny.find(SLIDE_ACTIVE_SEL);
33816            if( slide.length ) {
33817                destiny = $(slide);
33818            }
33819
33820            return destiny;
33821        }
33822
33823        /**
33824        * Scrolls to the anchor in the URL when loading the site
33825        */
33826        function scrollToAnchor(){
33827            //getting the anchor link in the URL and deleting the `#`
33828            var value =  window.location.hash.replace('#', '').split('/');
33829            var sectionAnchor = decodeURIComponent(value[0]);
33830            var slideAnchor = decodeURIComponent(value[1]);
33831
33832            if(sectionAnchor){  //if theres any #
33833                if(options.animateAnchor){
33834                    scrollPageAndSlide(sectionAnchor, slideAnchor);
33835                }else{
33836                    silentMoveTo(sectionAnchor, slideAnchor);
33837                }
33838            }
33839        }
33840
33841        /**
33842        * Detecting any change on the URL to scroll to the given anchor link
33843        * (a way to detect back history button as we play with the hashes on the URL)
33844        */
33845        function hashChangeHandler(){
33846            if(!isScrolling && !options.lockAnchors){
33847                var value =  window.location.hash.replace('#', '').split('/');
33848                var sectionAnchor = decodeURIComponent(value[0]);
33849                var slideAnchor = decodeURIComponent(value[1]);
33850
33851                    //when moving to a slide in the first section for the first time (first time to add an anchor to the URL)
33852                    var isFirstSlideMove =  (typeof lastScrolledDestiny === 'undefined');
33853                    var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving);
33854
33855
33856                if(sectionAnchor.length){
33857                    /*in order to call scrollpage() only once for each destination at a time
33858                    It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange`
33859                    event is fired on every scroll too.*/
33860                    if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor ))  {
33861                        scrollPageAndSlide(sectionAnchor, slideAnchor);
33862                    }
33863                }
33864            }
33865        }
33866
33867        //Sliding with arrow keys, both, vertical and horizontal
33868        function keydownHandler(e) {
33869
33870            clearTimeout(keydownId);
33871
33872            var activeElement = $(':focus');
33873
33874            if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') &&
33875                activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' &&
33876                options.keyboardScrolling && options.autoScrolling){
33877                var keyCode = e.which;
33878
33879                //preventing the scroll with arrow keys & spacebar & Page Up & Down keys
33880                var keyControls = [40, 38, 32, 33, 34];
33881                if($.inArray(keyCode, keyControls) > -1){
33882                    e.preventDefault();
33883                }
33884
33885                controlPressed = e.ctrlKey;
33886
33887                keydownId = setTimeout(function(){
33888                    onkeydown(e);
33889                },150);
33890            }
33891        }
33892
33893        function tooltipTextHandler(){
33894            $(this).prev().trigger('click');
33895        }
33896
33897        //to prevent scrolling while zooming
33898        function keyUpHandler(e){
33899            if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox
33900                controlPressed = e.ctrlKey;
33901            }
33902        }
33903
33904        //binding the mousemove when the mouse's middle button is released
33905        function mouseDownHandler(e){
33906            //middle button
33907            if (e.which == 2){
33908                oldPageY = e.pageY;
33909                container.on('mousemove', mouseMoveHandler);
33910            }
33911        }
33912
33913        //unbinding the mousemove when the mouse's middle button is released
33914        function mouseUpHandler(e){
33915            //middle button
33916            if (e.which == 2){
33917                container.off('mousemove');
33918            }
33919        }
33920
33921        //Scrolling horizontally when clicking on the slider controls.
33922        function slideArrowHandler(){
33923            var section = $(this).closest(SECTION_SEL);
33924
33925            if ($(this).hasClass(SLIDES_PREV)) {
33926                if(isScrollAllowed.m.left){
33927                    moveSlideLeft(section);
33928                }
33929            } else {
33930                if(isScrollAllowed.m.right){
33931                    moveSlideRight(section);
33932                }
33933            }
33934        }
33935
33936        //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
33937        function blurHandler(){
33938            isWindowFocused = false;
33939            controlPressed = false;
33940        }
33941
33942        //Scrolls to the section when clicking the navigation bullet
33943        function sectionBulletHandler(e){
33944            e.preventDefault();
33945            var index = $(this).parent().index();
33946            scrollPage($(SECTION_SEL).eq(index));
33947        }
33948
33949        //Scrolls the slider to the given slide destination for the given section
33950        function slideBulletHandler(e){
33951            e.preventDefault();
33952            var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL);
33953            var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index());
33954
33955            landscapeScroll(slides, destiny);
33956        }
33957
33958        /**
33959        * Keydown event
33960        */
33961        function onkeydown(e){
33962            var shiftPressed = e.shiftKey;
33963
33964            //do nothing if we can not scroll or we are not using horizotnal key arrows.
33965            if(!canScroll && [37,39].indexOf(e.which) < 0){
33966                return;
33967            }
33968
33969            switch (e.which) {
33970                //up
33971                case 38:
33972                case 33:
33973                    if(isScrollAllowed.k.up){
33974                        moveSectionUp();
33975                    }
33976                    break;
33977
33978                //down
33979                case 32: //spacebar
33980                    if(shiftPressed && isScrollAllowed.k.up){
33981                        moveSectionUp();
33982                        break;
33983                    }
33984                /* falls through */
33985                case 40:
33986                case 34:
33987                    if(isScrollAllowed.k.down){
33988                        moveSectionDown();
33989                    }
33990                    break;
33991
33992                //Home
33993                case 36:
33994                    if(isScrollAllowed.k.up){
33995                        moveTo(1);
33996                    }
33997                    break;
33998
33999                //End
34000                case 35:
34001                     if(isScrollAllowed.k.down){
34002                        moveTo( $(SECTION_SEL).length );
34003                    }
34004                    break;
34005
34006                //left
34007                case 37:
34008                    if(isScrollAllowed.k.left){
34009                        moveSlideLeft();
34010                    }
34011                    break;
34012
34013                //right
34014                case 39:
34015                    if(isScrollAllowed.k.right){
34016                        moveSlideRight();
34017                    }
34018                    break;
34019
34020                default:
34021                    return; // exit this handler for other keys
34022            }
34023        }
34024
34025        /**
34026        * Detecting the direction of the mouse movement.
34027        * Used only for the middle button of the mouse.
34028        */
34029        var oldPageY = 0;
34030        function mouseMoveHandler(e){
34031            if(canScroll){
34032                // moving up
34033                if (e.pageY < oldPageY && isScrollAllowed.m.up){
34034                    moveSectionUp();
34035                }
34036
34037                // moving down
34038                else if(e.pageY > oldPageY && isScrollAllowed.m.down){
34039                    moveSectionDown();
34040                }
34041            }
34042            oldPageY = e.pageY;
34043        }
34044
34045        /**
34046        * Scrolls horizontal sliders.
34047        */
34048        function landscapeScroll(slides, destiny, direction){
34049            var section = slides.closest(SECTION_SEL);
34050            var v = {
34051                slides: slides,
34052                destiny: destiny,
34053                direction: direction,
34054                destinyPos: destiny.position(),
34055                slideIndex: destiny.index(),
34056                section: section,
34057                sectionIndex: section.index(SECTION_SEL),
34058                anchorLink: section.data('anchor'),
34059                slidesNav: section.find(SLIDES_NAV_SEL),
34060                slideAnchor:  getAnchor(destiny),
34061                prevSlide: section.find(SLIDE_ACTIVE_SEL),
34062                prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(),
34063
34064                //caching the value of isResizing at the momment the function is called
34065                //because it will be checked later inside a setTimeout and the value might change
34066                localIsResizing: isResizing
34067            };
34068            v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex);
34069            v.direction = v.direction ? v.direction : v.xMovement;
34070
34071            //important!! Only do it when not resizing
34072            if(!v.localIsResizing){
34073                //preventing from scrolling to the next/prev section when using scrollHorizontally
34074                canScroll = false;
34075            }
34076
34077            if(options.onSlideLeave){
34078
34079                //if the site is not just resizing and readjusting the slides
34080                if(!v.localIsResizing && v.xMovement!=='none'){
34081                    if($.isFunction( options.onSlideLeave )){
34082                        if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){
34083                            slideMoving = false;
34084                            return;
34085                        }
34086                    }
34087                }
34088            }
34089
34090            destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE);
34091
34092            if(!v.localIsResizing){
34093                stopMedia(v.prevSlide);
34094                lazyLoad(destiny);
34095            }
34096
34097            if(!options.loopHorizontal && options.controlArrows){
34098                //hidding it for the fist slide, showing for the rest
34099                section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0);
34100
34101                //hidding it for the last slide, showing for the rest
34102                section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child'));
34103            }
34104
34105            //only changing the URL if the slides are in the current section (not for resize re-adjusting)
34106            if(section.hasClass(ACTIVE) && !v.localIsResizing){
34107                setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex);
34108            }
34109
34110            performHorizontalMove(slides, v, true);
34111        }
34112
34113
34114        function afterSlideLoads(v){
34115            activeSlidesNavigation(v.slidesNav, v.slideIndex);
34116
34117            //if the site is not just resizing and readjusting the slides
34118            if(!v.localIsResizing){
34119                $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex);
34120
34121                //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally
34122                //and to prevent double scroll right after a windows resize
34123                canScroll = true;
34124
34125                playMedia(v.destiny);
34126            }
34127
34128            //letting them slide again
34129            slideMoving = false;
34130        }
34131
34132        /**
34133        * Performs the horizontal movement. (CSS3 or jQuery)
34134        *
34135        * @param fireCallback {Bool} - determines whether or not to fire the callback
34136        */
34137        function performHorizontalMove(slides, v, fireCallback){
34138            var destinyPos = v.destinyPos;
34139
34140            if(options.css3){
34141                var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)';
34142
34143                addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v);
34144
34145                afterSlideLoadsId = setTimeout(function(){
34146                    fireCallback && afterSlideLoads(v);
34147                }, options.scrollingSpeed, options.easing);
34148            }else{
34149                slides.animate({
34150                    scrollLeft : Math.round(destinyPos.left)
34151                }, options.scrollingSpeed, options.easing, function() {
34152
34153                    fireCallback && afterSlideLoads(v);
34154                });
34155            }
34156        }
34157
34158        /**
34159        * Sets the state for the horizontal bullet navigations.
34160        */
34161        function activeSlidesNavigation(slidesNav, slideIndex){
34162            slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE);
34163            slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE);
34164        }
34165
34166        var previousHeight = windowsHeight;
34167
34168        //when resizing the site, we adjust the heights of the sections, slimScroll...
34169        function resizeHandler(){
34170            //checking if it needs to get responsive
34171            responsive();
34172
34173            // rebuild immediately on touch devices
34174            if (isTouchDevice) {
34175                var activeElement = $(document.activeElement);
34176
34177                //if the keyboard is NOT visible
34178                if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) {
34179                    var currentHeight = $window.height();
34180
34181                    //making sure the change in the viewport size is enough to force a rebuild. (20 % of the window to avoid problems when hidding scroll bars)
34182                    if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){
34183                        reBuild(true);
34184                        previousHeight = currentHeight;
34185                    }
34186                }
34187            }else{
34188                //in order to call the functions only when the resize is finished
34189                //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing
34190                clearTimeout(resizeId);
34191
34192                resizeId = setTimeout(function(){
34193                    reBuild(true);
34194                }, 350);
34195            }
34196        }
34197
34198        /**
34199        * Checks if the site needs to get responsive and disables autoScrolling if so.
34200        * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS.
34201        */
34202        function responsive(){
34203            var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity
34204            var heightLimit = options.responsiveHeight;
34205
34206            //only calculating what we need. Remember its called on the resize event.
34207            var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit;
34208            var isBreakingPointHeight = heightLimit && $window.height() < heightLimit;
34209
34210            if(widthLimit && heightLimit){
34211                setResponsive(isBreakingPointWidth || isBreakingPointHeight);
34212            }
34213            else if(widthLimit){
34214                setResponsive(isBreakingPointWidth);
34215            }
34216            else if(heightLimit){
34217                setResponsive(isBreakingPointHeight);
34218            }
34219        }
34220
34221        /**
34222        * Adds transition animations for the given element
34223        */
34224        function addAnimation(container, element){
34225            var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3;
34226
34227            container.removeClass(NO_TRANSITION);
34228            return container.css({
34229                '-webkit-transition': transition,
34230                'transition': transition
34231            });
34232        }
34233
34234        /**
34235        * Remove transition animations for the given element
34236        */
34237        function removeAnimation(element){
34238            return element.addClass(NO_TRANSITION);
34239        }
34240
34241        /**
34242        * Activating the vertical navigation bullets according to the given slide name.
34243        */
34244        function activateNavDots(name, sectionIndex){
34245            if(options.navigation){
34246                $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE);
34247                if(name){
34248                    $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE);
34249                }else{
34250                    $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE);
34251                }
34252            }
34253        }
34254
34255        /**
34256        * Activating the website main menu elements according to the given slide name.
34257        */
34258        function activateMenuElement(name){
34259            if(options.menu){
34260                $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE);
34261                $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE);
34262            }
34263        }
34264
34265        /**
34266        * Sets to active the current menu and vertical nav items.
34267        */
34268        function activateMenuAndNav(anchor, index){
34269            activateMenuElement(anchor);
34270            activateNavDots(anchor, index);
34271        }
34272
34273        /**
34274        * Retuns `up` or `down` depending on the scrolling movement to reach its destination
34275        * from the current section.
34276        */
34277        function getYmovement(destiny){
34278            var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL);
34279            var toIndex = destiny.index(SECTION_SEL);
34280            if( fromIndex == toIndex){
34281                return 'none';
34282            }
34283            if(fromIndex > toIndex){
34284                return 'up';
34285            }
34286            return 'down';
34287        }
34288
34289        /**
34290        * Retuns `right` or `left` depending on the scrolling movement to reach its destination
34291        * from the current slide.
34292        */
34293        function getXmovement(fromIndex, toIndex){
34294            if( fromIndex == toIndex){
34295                return 'none';
34296            }
34297            if(fromIndex > toIndex){
34298                return 'left';
34299            }
34300            return 'right';
34301        }
34302
34303        /**
34304        * Checks if the element needs scrollbar and if the user wants to apply it.
34305        * If so it creates it.
34306        *
34307        * @param {Object} element   jQuery object of the section or slide
34308        */
34309        function createScrollBar(element){
34310            //User doesn't want scrollbar here? Sayonara baby!
34311            if(element.hasClass('fp-noscroll')) return;
34312
34313            //needed to make `scrollHeight` work under Opera 12
34314            element.css('overflow', 'hidden');
34315
34316            var scrollOverflowHandler = options.scrollOverflowHandler;
34317            var wrap = scrollOverflowHandler.wrapContent();
34318            //in case element is a slide
34319            var section = element.closest(SECTION_SEL);
34320            var scrollable = scrollOverflowHandler.scrollable(element);
34321            var contentHeight;
34322
34323            //if there was scroll, the contentHeight will be the one in the scrollable section
34324            if(scrollable.length){
34325                contentHeight = scrollOverflowHandler.scrollHeight(element);
34326            }else{
34327                contentHeight = element.get(0).scrollHeight;
34328                if(options.verticalCentered){
34329                    contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight;
34330                }
34331            }
34332
34333            var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top'));
34334
34335            //needs scroll?
34336            if ( contentHeight > scrollHeight) {
34337                //did we already have an scrollbar ? Updating it
34338                if(scrollable.length){
34339                    scrollOverflowHandler.update(element, scrollHeight);
34340                }
34341                //creating the scrolling
34342                else{
34343                    if(options.verticalCentered){
34344                        element.find(TABLE_CELL_SEL).wrapInner(wrap);
34345                    }else{
34346                        element.wrapInner(wrap);
34347                    }
34348                    scrollOverflowHandler.create(element, scrollHeight);
34349                }
34350            }
34351            //removing the scrolling when it is not necessary anymore
34352            else{
34353                scrollOverflowHandler.remove(element);
34354            }
34355
34356            //undo
34357            element.css('overflow', '');
34358        }
34359
34360        function addTableClass(element){
34361            //In case we are styling for the 2nd time as in with reponsiveSlides
34362            if(!element.hasClass(TABLE)){
34363                element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />');
34364            }
34365        }
34366
34367        function getTableHeight(element){
34368            var sectionHeight = windowsHeight;
34369
34370            if(options.paddingTop || options.paddingBottom){
34371                var section = element;
34372                if(!section.hasClass(SECTION)){
34373                    section = element.closest(SECTION_SEL);
34374                }
34375
34376                var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom'));
34377                sectionHeight = (windowsHeight - paddings);
34378            }
34379
34380            return sectionHeight;
34381        }
34382
34383        /**
34384        * Adds a css3 transform property to the container class with or without animation depending on the animated param.
34385        */
34386        function transformContainer(translate3d, animated){
34387            if(animated){
34388                addAnimation(container);
34389            }else{
34390                removeAnimation(container);
34391            }
34392
34393            container.css(getTransforms(translate3d));
34394
34395            //syncronously removing the class after the animation has been applied.
34396            setTimeout(function(){
34397                container.removeClass(NO_TRANSITION);
34398            },10);
34399        }
34400
34401        /**
34402        * Gets a section by its anchor / index
34403        */
34404        function getSectionByAnchor(sectionAnchor){
34405            if(!sectionAnchor) return [];
34406
34407            var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]');
34408            if(!section.length){
34409                section = $(SECTION_SEL).eq( sectionAnchor -1);
34410            }
34411
34412            return section;
34413        }
34414
34415        /**
34416        * Gets a slide inside a given section by its anchor / index
34417        */
34418        function getSlideByAnchor(slideAnchor, section){
34419            var slides = section.find(SLIDES_WRAPPER_SEL);
34420            var slide =  slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]');
34421
34422            if(!slide.length){
34423                slide = slides.find(SLIDE_SEL).eq(slideAnchor);
34424            }
34425
34426            return slide;
34427        }
34428
34429        /**
34430        * Scrolls to the given section and slide anchors
34431        */
34432        function scrollPageAndSlide(destiny, slide){
34433            var section = getSectionByAnchor(destiny);
34434
34435            //do nothing if there's no section with the given anchor name
34436            if(!section.length) return;
34437
34438            //default slide
34439            if (typeof slide === 'undefined') {
34440                slide = 0;
34441            }
34442
34443            //we need to scroll to the section and then to the slide
34444            if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){
34445                scrollPage(section, function(){
34446                    scrollSlider(section, slide);
34447                });
34448            }
34449            //if we were already in the section
34450            else{
34451                scrollSlider(section, slide);
34452            }
34453        }
34454
34455        /**
34456        * Scrolls the slider to the given slide destination for the given section
34457        */
34458        function scrollSlider(section, slideAnchor){
34459            if(typeof slideAnchor !== 'undefined'){
34460                var slides = section.find(SLIDES_WRAPPER_SEL);
34461                var destiny =  getSlideByAnchor(slideAnchor, section);
34462
34463                if(destiny.length){
34464                    landscapeScroll(slides, destiny);
34465                }
34466            }
34467        }
34468
34469        /**
34470        * Creates a landscape navigation bar with dots for horizontal sliders.
34471        */
34472        function addSlidesNavigation(section, numSlides){
34473            section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>');
34474            var nav = section.find(SLIDES_NAV_SEL);
34475
34476            //top or bottom
34477            nav.addClass(options.slidesNavPosition);
34478
34479            for(var i=0; i< numSlides; i++){
34480                nav.find('ul').append('<li><a href="#"><span></span></a></li>');
34481            }
34482
34483            //centering it
34484            nav.css('margin-left', '-' + (nav.width()/2) + 'px');
34485
34486            nav.find('li').first().find('a').addClass(ACTIVE);
34487        }
34488
34489
34490        /**
34491        * Sets the state of the website depending on the active section/slide.
34492        * It changes the URL hash when needed and updates the body class.
34493        */
34494        function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){
34495            var sectionHash = '';
34496
34497            if(options.anchors.length && !options.lockAnchors){
34498
34499                //isn't it the first slide?
34500                if(slideIndex){
34501                    if(typeof anchorLink !== 'undefined'){
34502                        sectionHash = anchorLink;
34503                    }
34504
34505                    //slide without anchor link? We take the index instead.
34506                    if(typeof slideAnchor === 'undefined'){
34507                        slideAnchor = slideIndex;
34508                    }
34509
34510                    lastScrolledSlide = slideAnchor;
34511                    setUrlHash(sectionHash + '/' + slideAnchor);
34512
34513                //first slide won't have slide anchor, just the section one
34514                }else if(typeof slideIndex !== 'undefined'){
34515                    lastScrolledSlide = slideAnchor;
34516                    setUrlHash(anchorLink);
34517                }
34518
34519                //section without slides
34520                else{
34521                    setUrlHash(anchorLink);
34522                }
34523            }
34524
34525            setBodyClass();
34526        }
34527
34528        /**
34529        * Sets the URL hash.
34530        */
34531        function setUrlHash(url){
34532            //Uncode addition
34533            if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer )
34534                return false;
34535
34536            if(options.recordHistory){
34537                location.hash = url;
34538            }else{
34539                //Uncode addition
34540                //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :)
34541                // if(isTouchDevice || isTouch){
34542                //     window.history.replaceState(undefined, undefined, '#' + url);
34543                // }else{
34544                //     var baseUrl = window.location.href.split('#')[0];
34545                //     window.location.replace( baseUrl + '#' + url );
34546                // }
34547                return false;
34548            }
34549        }
34550
34551        /**
34552        * Gets the anchor for the given slide / section. Its index will be used if there's none.
34553        */
34554        function getAnchor(element){
34555            var anchor = element.data('anchor');
34556            var index = element.index();
34557
34558            //Slide without anchor link? We take the index instead.
34559            if(typeof anchor === 'undefined'){
34560                anchor = index;
34561            }
34562
34563            return anchor;
34564        }
34565
34566        /**
34567        * Sets a class for the body of the page depending on the active section / slide
34568        */
34569        function setBodyClass(){
34570            var section = $(SECTION_ACTIVE_SEL);
34571            var slide = section.find(SLIDE_ACTIVE_SEL);
34572
34573            var sectionAnchor = getAnchor(section);
34574            var slideAnchor = getAnchor(slide);
34575
34576            var text = String(sectionAnchor);
34577
34578            if(slide.length){
34579                text = text + '-' + slideAnchor;
34580            }
34581
34582            //changing slash for dash to make it a valid CSS style
34583            text = text.replace('/', '-').replace('#','');
34584
34585            //removing previous anchor classes
34586            var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g");
34587            $body[0].className = $body[0].className.replace(classRe, '');
34588
34589            //adding the current anchor
34590            $body.addClass(VIEWING_PREFIX + '-' + text);
34591        }
34592
34593        /**
34594        * Checks for translate3d support
34595        * @return boolean
34596        * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support
34597        */
34598        function support3d() {
34599            var el = document.createElement('p'),
34600                has3d,
34601                transforms = {
34602                    'webkitTransform':'-webkit-transform',
34603                    'OTransform':'-o-transform',
34604                    'msTransform':'-ms-transform',
34605                    'MozTransform':'-moz-transform',
34606                    'transform':'transform'
34607                };
34608
34609            // Add it to the body to get the computed style.
34610            document.body.insertBefore(el, null);
34611
34612            for (var t in transforms) {
34613                if (el.style[t] !== undefined) {
34614                    el.style[t] = 'translate3d(1px,1px,1px)';
34615                    has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
34616                }
34617            }
34618
34619            document.body.removeChild(el);
34620
34621            return (has3d !== undefined && has3d.length > 0 && has3d !== 'none');
34622        }
34623
34624        /**
34625        * Removes the auto scrolling action fired by the mouse wheel and trackpad.
34626        * After this function is called, the mousewheel and trackpad movements won't scroll through sections.
34627        */
34628        function removeMouseWheelHandler(){
34629            if (document.addEventListener) {
34630                document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper
34631                document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox
34632                document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox
34633            } else {
34634                document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8
34635            }
34636        }
34637
34638        /**
34639        * Adds the auto scrolling action for the mouse wheel and trackpad.
34640        * After this function is called, the mousewheel and trackpad movements will scroll through sections
34641        * https://developer.mozilla.org/en-US/docs/Web/Events/wheel
34642        */
34643        function addMouseWheelHandler(){
34644            var prefix = '';
34645            var _addEventListener;
34646
34647            if (window.addEventListener){
34648                _addEventListener = "addEventListener";
34649            }else{
34650                _addEventListener = "attachEvent";
34651                prefix = 'on';
34652            }
34653
34654             // detect available wheel event
34655            var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel"
34656                      document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel"
34657                      'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox
34658            var passiveEvent = g_supportsPassive ? {passive: false }
34658: false;
34659
34660
34661            if(support == 'DOMMouseScroll'){
34662                document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent);
34663            }
34664
34665            //handle MozMousePixelScroll in older Firefox
34666            else{
34667                document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent);
34668            }
34669        }
34670
34671        /**
34672        * Binding the mousemove when the mouse's middle button is pressed
34673        */
34674        function addMiddleWheelHandler(){
34675            container
34676                .on('mousedown', mouseDownHandler)
34677                .on('mouseup', mouseUpHandler);
34678        }
34679
34680        /**
34681        * Unbinding the mousemove when the mouse's middle button is released
34682        */
34683        function removeMiddleWheelHandler(){
34684            container
34685                .off('mousedown', mouseDownHandler)
34686                .off('mouseup', mouseUpHandler);
34687        }
34688
34689        /**
34690        * Adds the possibility to auto scroll through sections on touch devices.
34691        */
34692        function addTouchHandler(){
34693            if(isTouchDevice || isTouch){
34694                if(options.autoScrolling){
34695                    $body.off(events.touchmove).on(events.touchmove, preventBouncing);
34696                }
34697
34698                $(WRAPPER_SEL)
34699                    .off(events.touchstart).on(events.touchstart, touchStartHandler)
34700                    .off(events.touchmove).on(events.touchmove, touchMoveHandler);
34701            }
34702        }
34703
34704        /**
34705        * Removes the auto scrolling for touch devices.
34706        */
34707        function removeTouchHandler(){
34708            if(isTouchDevice || isTouch){
34709                $(WRAPPER_SEL)
34710                    .off(events.touchstart)
34711                    .off(events.touchmove);
34712            }
34713        }
34714
34715        /*
34716        * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11)
34717        * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx
34718        */
34719        function getMSPointer(){
34720            var pointer;
34721
34722            //IE >= 11 & rest of browsers
34723            if(window.PointerEvent){
34724                pointer = { down: 'pointerdown', move: 'pointermove'};
34725            }
34726
34727            //IE < 11
34728            else{
34729                pointer = { down: 'MSPointerDown', move: 'MSPointerMove'};
34730            }
34731
34732            return pointer;
34733        }
34734
34735        /**
34736        * Gets the pageX and pageY properties depending on the browser.
34737        * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854
34738        */
34739        function getEventsPage(e){
34740            var events = [];
34741
34742            events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY);
34743            events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX);
34744
34745            //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008
34746            if(isTouch && isReallyTouch(e) && options.scrollBar){
34747                events.y = e.touches[0].pageY;
34748                events.x = e.touches[0].pageX;
34749            }
34750
34751            return events;
34752        }
34753
34754        /**
34755        * Slides silently (with no animation) the active slider to the given slide.
34756        * @param noCallback {bool} true or defined -> no callbacks
34757        */
34758        function silentLandscapeScroll(activeSlide, noCallbacks){
34759            setScrollingSpeed (0, 'internal');
34760
34761            if(typeof noCallbacks !== 'undefined'){
34762                //preventing firing callbacks afterSlideLoad etc.
34763                isResizing = true;
34764            }
34765
34766            landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide);
34767
34768            if(typeof noCallbacks !== 'undefined'){
34769                isResizing = false;
34770            }
34771
34772            setScrollingSpeed(originals.scrollingSpeed, 'internal');
34773        }
34774
34775        /**
34776        * Scrolls silently (with no animation) the page to the given Y position.
34777        */
34778        function silentScroll(top){
34779            // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
34780            // that's why we round it to 0.
34781            var roundedTop = Math.round(top);
34782
34783            if (options.css3 && options.autoScrolling && !options.scrollBar){
34784                var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)';
34785                transformContainer(translate3d, false);
34786            }
34787            else if(options.autoScrolling && !options.scrollBar){
34788                container.css('top', -roundedTop);
34789            }
34790            else{
34791                $htmlBody.scrollTop(roundedTop);
34792            }
34793        }
34794
34795        /**
34796        * Returns the cross-browser transform string.
34797        */
34798        function getTransforms(translate3d){
34799            return {
34800                '-webkit-transform': translate3d,
34801                '-moz-transform': translate3d,
34802                '-ms-transform':translate3d,
34803                'transform': translate3d
34804            };
34805        }
34806
34807        /**
34808        * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard)
34809        * @type  m (mouse) or k (keyboard)
34810        */
34811        function setIsScrollAllowed(value, direction, type){
34812            switch (direction){
34813                case 'up': isScrollAllowed[type].up = value; break;
34814                case 'down': isScrollAllowed[type].down = value; break;
34815                case 'left': isScrollAllowed[type].left = value; break;
34816                case 'right': isScrollAllowed[type].right = value; break;
34817                case 'all':
34818                    if(type == 'm'){
34819                        setAllowScrolling(value);
34820                    }else{
34821                        setKeyboardScrolling(value);
34822                    }
34823            }
34824        }
34825
34826        /*
34827        * Destroys fullpage.js plugin events and optinally its html markup and styles
34828        */
34829        function destroy(all){
34830            setAutoScrolling(false, 'internal');
34831            setAllowScrolling(false);
34832            setKeyboardScrolling(false);
34833            container.addClass(DESTROYED);
34834
34835            clearTimeout(afterSlideLoadsId);
34836            clearTimeout(afterSectionLoadsId);
34837            clearTimeout(resizeId);
34838            clearTimeout(scrollId);
34839            clearTimeout(scrollId2);
34840
34841            $window
34842                .off('scroll', scrollHandler)
34843                .off('hashchange', hashChangeHandler)
34844                .off('resize', resizeHandler);
34845
34846            $document
34847                .off('click touchstart', SECTION_NAV_SEL + ' a')
34848                .off('mouseenter', SECTION_NAV_SEL + ' li')
34849                .off('mouseleave', SECTION_NAV_SEL + ' li')
34850                .off('click touchstart', SLIDES_NAV_LINK_SEL)
34851                .off('mouseover', options.normalScrollElements)
34852                .off('mouseout', options.normalScrollElements);
34853
34854            $(SECTION_SEL)
34855                .off('click touchstart', SLIDES_ARROW_SEL);
34856
34857            clearTimeout(afterSlideLoadsId);
34858            clearTimeout(afterSectionLoadsId);
34859
34860            //lets make a mess!
34861            if(all){
34862                destroyStructure();
34863            }
34864        }
34865
34866        /*
34867        * Removes inline styles added by fullpage.js
34868        */
34869        function destroyStructure(){
34870            //reseting the `top` or `translate` properties to 0
34871            silentScroll(0);
34872
34873            //loading all the lazy load content
34874            container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){
34875                setSrc($(this), 'src');
34876            });
34877
34878            container.find('img[data-srcset]').each(function(){
34879                setSrc($(this), 'srcset');
34880            });
34881
34882            $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL +  ', ' + SLIDES_ARROW_SEL).remove();
34883
34884            //removing inline styles
34885            $(SECTION_SEL).css( {
34886                'height': '',
34887                'background-color' : '',
34888                'padding': ''
34889            });
34890
34891            $(SLIDE_SEL).css( {
34892                'width': ''
34893            });
34894
34895            container.css({
34896                'height': '',
34897                'position': '',
34898                '-ms-touch-action': '',
34899                'touch-action': ''
34900            });
34901
34902            $htmlBody.css({
34903                'overflow': '',
34904                'height': ''
34905            });
34906
34907            // remove .fp-enabled class
34908            $('html').removeClass(ENABLED);
34909
34910            // remove .fp-responsive class
34911            $body.removeClass(RESPONSIVE);
34912
34913            // remove all of the .fp-viewing- classes
34914            $.each($body.get(0).className.split(/\s+/), function (index, className) {
34915                if (className.indexOf(VIEWING_PREFIX) === 0) {
34916                    $body.removeClass(className);
34917                }
34918            });
34919
34920            //removing added classes
34921            $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){
34922                options.scrollOverflowHandler.remove($(this));
34923                $(this).removeClass(TABLE + ' ' + ACTIVE);
34924            });
34925
34926            removeAnimation(container);
34927
34928            //Unwrapping content
34929            container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){
34930                //unwrap not being use in case there's no child element inside and its just text
34931                $(this).replaceWith(this.childNodes);
34932            });
34933
34934            //removing the applied transition from the fullpage wrapper
34935            container.css({
34936                '-webkit-transition': 'none',
34937                'transition': 'none'
34938            });
34939
34940            //scrolling the page to the top with no animation
34941            $htmlBody.scrollTop(0);
34942
34943            //removing selectors
34944            var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER];
34945            $.each(usedSelectors, function(index, value){
34946                $('.' + value).removeClass(value);
34947            });
34948        }
34949
34950        /*
34951        * Sets the state for a variable with multiple states (original, and temporal)
34952        * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`.
34953        * This function is used to keep track of both states, the original and the temporal one.
34954        * If type is not 'internal', then we assume the user is globally changing the variable.
34955        */
34956        function setVariableState(variable, value, type){
34957            options[variable] = value;
34958            if(type !== 'internal'){
34959                originals[variable] = value;
34960            }
34961        }
34962
34963        /**
34964        * Displays warnings
34965        */
34966        function displayWarnings(){
34967            var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax'];
34968            //UNCODE.addition
34969            // if($('html').hasClass(ENABLED)){
34970            //     showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!');
34971            //     return;
34972            // }
34973
34974            // Disable mutually exclusive settings
34975            //UNCODE.addition
34976            // if (options.continuousVertical &&
34977            //     (options.loopTop || options.loopBottom)) {
34978            //     options.continuousVertical = false;
34979            //     showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
34980            // }
34981
34982            // if(options.scrollBar && options.scrollOverflow){
34983            //     showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox');
34984            // }
34985
34986            // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){
34987            //     options.continuousVertical = false;
34988            //     showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
34989            // }
34990
34991            //using extensions? Wrong file!
34992            $.each(extensions, function(index, extension){
34993                //is the option set to true?
34994                if(options[extension]){
34995                    showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension);
34996                }
34997            });
34998
34999            //anchors can not have the same value as any element ID or NAME
35000            $.each(options.anchors, function(index, name){
35001
35002                //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396)
35003                var nameAttr = $document.find('[name]').filter(function() {
35004                    return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase();
35005                });
35006
35007                var idAttr = $document.find('[id]').filter(function() {
35008                    return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase();
35009                });
35010
35011                if(idAttr.length || nameAttr.length ){
35012                    showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).');
35013                    idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property');
35014                    nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property');
35015                }
35016            });
35017        }
35018
35019        /**
35020        * Shows a message in the console of the given type.
35021        */
35022        function showError(type, text){
35023            console && console[type] && console[type]('fullPage: ' + text);
35024        }
35025
35026    }; //end of $.fn.fullpage
35027
35028    if(typeof IScroll !== 'undefined'){
35029        /*
35030        * Turns iScroll `mousewheel` option off dynamically
35031        * https://github.com/cubiq/iscroll/issues/1036
35032        */
35033        IScroll.prototype.wheelOn = function () {
35034            this.wrapper.addEventListener('wheel', this);
35035            this.wrapper.addEventListener('mousewheel', this);
35036            this.wrapper.addEventListener('DOMMouseScroll', this);
35037        };
35038
35039        /*
35040        * Turns iScroll `mousewheel` option on dynamically
35041        * https://github.com/cubiq/iscroll/issues/1036
35042        */
35043        IScroll.prototype.wheelOff = function () {
35044            this.wrapper.removeEventListener('wheel', this);
35045            this.wrapper.removeEventListener('mousewheel', this);
35046            this.wrapper.removeEventListener('DOMMouseScroll', this);
35047        };
35048    }
35049
35050    /**
35051     * An object to handle overflow scrolling.
35052     * This uses jquery.slimScroll to accomplish overflow scrolling.
35053     * It is possible to pass in an alternate scrollOverflowHandler
35054     * to the fullpage.js option that implements the same functions
35055     * as this handler.
35056     *
35057     * @type {Object}
35058     */
35059    var iscrollHandler = {
35060        refreshId: null,
35061        iScrollInstances: [],
35062
35063        // Enables or disables the mouse wheel for the active section or all slides in it
35064        toggleWheel: function(value){
35065            var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL);
35066            scrollable.each(function(){
35067                var iScrollInstance = $(this).data('iscrollInstance');
35068                if(typeof iScrollInstance !== 'undefined' && iScrollInstance){
35069                    if(value){
35070                        iScrollInstance.wheelOn();
35071                    }
35072                    else{
35073                        iScrollInstance.wheelOff();
35074                    }
35075                }
35076            });
35077        },
35078
35079        /**
35080        * Turns off iScroll for the destination section.
35081        * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
35082        * scroll the destination section/slide before the sections animations ends.
35083        */
35084        onLeave: function(){
35085            iscrollHandler.toggleWheel(false);
35086        },
35087
35088        // Turns off iScroll for the leaving section
35089        beforeLeave: function(){
35090            iscrollHandler.onLeave()
35091        },
35092
35093        // Turns on iScroll on section load
35094        afterLoad: function(){
35095            iscrollHandler.toggleWheel(true);
35096        },
35097
35098        /**
35099         * Called when overflow scrolling is needed for a section.
35100         *
35101         * @param  {Object} element      jQuery object containing current section
35102         * @param  {Number} scrollHeight Current window height in pixels
35103         */
35104        create: function(element, scrollHeight) {
35105            var scrollable = element.find(SCROLLABLE_SEL);
35106
35107            scrollable.height(scrollHeight);
35108            scrollable.each(function() {
35109                var $this = $(this);
35110                var iScrollInstance = $this.data('iscrollInstance');
35111                if (iScrollInstance) {
35112                    $.each(iscrollHandler.iScrollInstances, function(){
35113                        $(this).destroy();
35114                    });
35115                }
35116
35117                iScrollInstance = new IScroll($this.get(0), iscrollOptions);
35118                iscrollHandler.iScrollInstances.push(iScrollInstance);
35119
35120                //off by default until the section gets active
35121                iScrollInstance.wheelOff();
35122
35123                $this.data('iscrollInstance', iScrollInstance);
35124            });
35125        },
35126
35127        /**
35128         * Return a boolean depending on whether the scrollable element is a
35129         * the end or at the start of the scrolling depending on the given type.
35130         *
35131         * @param  {String}  type       Either 'top' or 'bottom'
35132         * @param  {Object}  scrollable jQuery object for the scrollable element
35133         * @return {Boolean}
35134         */
35135        isScrolled: function(type, scrollable) {
35136            var scroller = scrollable.data('iscrollInstance');
35137
35138            //no scroller?
35139            if (!scroller) {
35140                return true;
35141            }
35142
35143            //Uncode addition
35144            var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0;
35145            //End Uncode addition
35146
35147            if (type === 'top') {
35148                return scroller.y >= 0 && !scrollable.scrollTop();
35149            } else if (type === 'bottom') {
35150                //Uncode change
35151                // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight;
35152                return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight;
35153                //End Uncode change
35154            }
35155        },
35156
35157        /**
35158         * Returns the scrollable element for the given section.
35159         * If there are landscape slides, will only return a scrollable element
35160         * if it is in the active slide.
35161         *
35162         * @param  {Object}  activeSection jQuery object containing current section
35163         * @return {Boolean}
35164         */
35165        scrollable: function(activeSection){
35166            // if there are landscape slides, we check if the scrolling bar is in the current one or not
35167            if (activeSection.find(SLIDES_WRAPPER_SEL).length) {
35168                return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL);
35169            }
35170            return activeSection.find(SCROLLABLE_SEL);
35171        },
35172
35173        /**
35174         * Returns the scroll height of the wrapped content.
35175         * If this is larger than the window height minus section padding,
35176         * overflow scrolling is needed.
35177         *
35178         * @param  {Object} element jQuery object containing current section
35179         * @return {Number}
35180         */
35181        scrollHeight: function(element) {
35182            return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight;
35183        },
35184
35185        /**
35186         * Called when overflow scrolling is no longer needed for a section.
35187         *
35188         * @param  {Object}
vendor: 5,435 bytes, lines 35188-35339
35188 element      jQuery object containing current section
35189         */
35190        remove: function(element) {
35191            var scrollable = element.find(SCROLLABLE_SEL);
35192            if (scrollable.length) {
35193                var iScrollInstance = scrollable.data('iscrollInstance');
35194                iScrollInstance.destroy();
35195
35196                scrollable.data('iscrollInstance', null);
35197            }
35198            element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap();
35199        },
35200
35201        /**
35202         * Called when overflow scrolling has already been setup but the
35203         * window height has potentially changed.
35204         *
35205         * @param  {Object} element      jQuery object containing current section
35206         * @param  {Number} scrollHeight Current window height in pixels
35207         */
35208        update: function(element, scrollHeight) {
35209            //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a
35210            //short period of time.
35211            //it also comes on handy because iScroll requires the use of timeout when using `refresh`.
35212            clearTimeout(iscrollHandler.refreshId);
35213            iscrollHandler.refreshId = setTimeout(function(){
35214                $.each(iscrollHandler.iScrollInstances, function(){
35215                    $(this).get(0).refresh();
35216                });
35217            }, 150);
35218
35219            //updating the wrappers height
35220            element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px');
35221        },
35222
35223        /**
35224         * Called to get any additional elements needed to wrap the section
35225         * content in order to facilitate overflow scrolling.
35226         *
35227         * @return {String|Object} Can be a string containing HTML,
35228         *                         a DOM element, or jQuery object.
35229         */
35230        wrapContent: function() {
35231            return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>';
35232        }
35233    };
35234});
35235
35236(function (global, factory) {
35237	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
35238	typeof define === 'function' && define.amd ? define(['exports'], factory) :
35239	(global = global || self, factory(global.window = global.window || {}));
35240  }(this, (function (exports) { 'use strict';
35241  
35242	function _defineProperties(target, props) {
35243	  for (var i = 0; i < props.length; i++) {
35244		var descriptor = props[i];
35245		descriptor.enumerable = descriptor.enumerable || false;
35246		descriptor.configurable = true;
35247		if ("value" in descriptor) descriptor.writable = true;
35248		Object.defineProperty(target, descriptor.key, descriptor);
35249	  }
35250	}
35251  
35252	function _createClass(Constructor, protoProps, staticProps) {
35253	  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
35254	  if (staticProps) _defineProperties(Constructor, staticProps);
35255	  return Constructor;
35256	}
35257  
35258	/*!
35259	 * Observer 3.12.5
35260	 * https://gsap.com
35261	 *
35262	 * @license Copyright 2008-2024, GreenSock. All rights reserved.
35263	 * Subject to the terms at https://gsap.com/standard-license or for
35264	 * Club GSAP members, the agreement issued with that membership.
35265	 * @author: Jack Doyle, [email protected]
35266	*/
35267	var gsap,
35268		_coreInitted,
35269		_clamp,
35270		_win,
35271		_doc,
35272		_docEl,
35273		_body,
35274		_isTouch,
35275		_pointerType,
35276		ScrollTrigger,
35277		_root,
35278		_normalizer,
35279		_eventTypes,
35280		_context,
35281		_getGSAP = function _getGSAP() {
35282	  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;
35283	},
35284		_startup = 1,
35285		_observers = [],
35286		_scrollers = [],
35287		_proxies = [],
35288		_getTime = Date.now,
35289		_bridge = function _bridge(name, value) {
35290	  return value;
35291	},
35292		_integrate = function _integrate() {
35293	  var core = ScrollTrigger.core,
35294		  data = core.bridge || {},
35295		  scrollers = core._scrollers,
35296		  proxies = core._proxies;
35297	  scrollers.push.apply(scrollers, _scrollers);
35298	  proxies.push.apply(proxies, _proxies);
35299	  _scrollers = scrollers;
35300	  _proxies = proxies;
35301  
35302	  _bridge = function _bridge(name, value) {
35303		return data[name](value);
35304	  };
35305	},
35306		_getProxyProp = function _getProxyProp(element, property) {
35307	  return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property];
35308	},
35309		_isViewport = function _isViewport(el) {
35310	  return !!~_root.indexOf(el);
35311	},
35312		_addListener = function _addListener(element, type, func, passive, capture) {
35313	  return element.addEventListener(type, func, {
35314		passive: passive !== false,
35315		capture: !!capture
35316	  });
35317	},
35318		_removeListener = function _removeListener(element, type, func, capture) {
35319	  return element.removeEventListener(type, func, !!capture);
35320	},
35321		_scrollLeft = "scrollLeft",
35322		_scrollTop = "scrollTop",
35323		_onScroll = function _onScroll() {
35324	  return _normalizer && _normalizer.isPressed || _scrollers.cache++;
35325	},
35326		_scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) {
35327	  var cachingFunc = function cachingFunc(value) {
35328		if (value || value === 0) {
35329		  _startup && (_win.history.scrollRestoration = "manual");
35330		  var isNormalizing = _normalizer && _normalizer.isPressed;
35331		  value = cachingFunc.v = Math.round(value) || (_normalizer && _normalizer.iOS ? 1 : 0);
35332		  f(value);
35333		  cachingFunc.cacheID = _scrollers.cache;
35334		  isNormalizing && _bridge("ss", value);
35335		} else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge("ref")) {
35336		  cachingFunc.cacheID = _scrollers.cache;
35337		  cachingFunc.v = f();
35338		}
35339  
vendor: 13,754 bytes, lines 35340-35793
35340		return cachingFunc.v + cachingFunc.offset;
35341	  };
35342  
35343	  cachingFunc.offset = 0;
35344	  return f && cachingFunc;
35345	},
35346		_horizontal = {
35347	  s: _scrollLeft,
35348	  p: "left",
35349	  p2: "Left",
35350	  os: "right",
35351	  os2: "Right",
35352	  d: "width",
35353	  d2: "Width",
35354	  a: "x",
35355	  sc: _scrollCacheFunc(function (value) {
35356		return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0;
35357	  })
35358	},
35359		_vertical = {
35360	  s: _scrollTop,
35361	  p: "top",
35362	  p2: "Top",
35363	  os: "bottom",
35364	  os2: "Bottom",
35365	  d: "height",
35366	  d2: "Height",
35367	  a: "y",
35368	  op: _horizontal,
35369	  sc: _scrollCacheFunc(function (value) {
35370		return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0;
35371	  })
35372	},
35373		_getTarget = function _getTarget(t, self) {
35374	  return (self && self._ctx && self._ctx.selector || gsap.utils.toArray)(t)[0] || (typeof t === "string" && gsap.config().nullTargetWarn !== false ? console.warn("Element not found:", t) : null);
35375	},
35376		_getScrollFunc = function _getScrollFunc(element, _ref) {
35377	  var s = _ref.s,
35378		  sc = _ref.sc;
35379	  _isViewport(element) && (element = _doc.scrollingElement || _docEl);
35380  
35381	  var i = _scrollers.indexOf(element),
35382		  offset = sc === _vertical.sc ? 1 : 2;
35383  
35384	  !~i && (i = _scrollers.push(element) - 1);
35385	  _scrollers[i + offset] || _addListener(element, "scroll", _onScroll);
35386	  var prev = _scrollers[i + offset],
35387		  func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) {
35388		return arguments.length ? element[s] = value : element[s];
35389	  })));
35390	  func.target = element;
35391	  prev || (func.smooth = gsap.getProperty(element, "scrollBehavior") === "smooth");
35392	  return func;
35393	},
35394		_getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) {
35395	  var v1 = value,
35396		  v2 = value,
35397		  t1 = _getTime(),
35398		  t2 = t1,
35399		  min = minTimeRefresh || 50,
35400		  dropToZeroTime = Math.max(500, min * 3),
35401		  update = function update(value, force) {
35402		var t = _getTime();
35403  
35404		if (force || t - t1 > min) {
35405		  v2 = v1;
35406		  v1 = value;
35407		  t2 = t1;
35408		  t1 = t;
35409		} else if (useDelta) {
35410		  v1 += value;
35411		} else {
35412		  v1 = v2 + (value - v2) / (t - t2) * (t1 - t2);
35413		}
35414	  },
35415		  reset = function reset() {
35416		v2 = v1 = useDelta ? 0 : v1;
35417		t2 = t1 = 0;
35418	  },
35419		  getVelocity = function getVelocity(latestValue) {
35420		var tOld = t2,
35421			vOld = v2,
35422			t = _getTime();
35423  
35424		(latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue);
35425		return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000;
35426	  };
35427  
35428	  return {
35429		update: update,
35430		reset: reset,
35431		getVelocity: getVelocity
35432	  };
35433	},
35434		_getEvent = function _getEvent(e, preventDefault) {
35435	  preventDefault && !e._gsapAllow && e.preventDefault();
35436	  return e.changedTouches ? e.changedTouches[0] : e;
35437	},
35438		_getAbsoluteMax = function _getAbsoluteMax(a) {
35439	  var max = Math.max.apply(Math, a),
35440		  min = Math.min.apply(Math, a);
35441	  return Math.abs(max) >= Math.abs(min) ? max : min;
35442	},
35443		_setScrollTrigger = function _setScrollTrigger() {
35444	  ScrollTrigger = gsap.core.globals().ScrollTrigger;
35445	  ScrollTrigger && ScrollTrigger.core && _integrate();
35446	},
35447		_initCore = function _initCore(core) {
35448	  gsap = core || _getGSAP();
35449  
35450	  if (!_coreInitted && gsap && typeof document !== "undefined" && document.body) {
35451		_win = window;
35452		_doc = document;
35453		_docEl = _doc.documentElement;
35454		_body = _doc.body;
35455		_root = [_win, _doc, _docEl, _body];
35456		_clamp = gsap.utils.clamp;
35457  
35458		_context = gsap.core.context || function () {};
35459  
35460		_pointerType = "onpointerenter" in _body ? "pointer" : "mouse";
35461		_isTouch = Observer.isTouch = _win.matchMedia && _win.matchMedia("(hover: none), (pointer: coarse)").matches ? 1 : "ontouchstart" in _win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0;
35462		_eventTypes = Observer.eventTypes = ("ontouchstart" in _docEl ? "touchstart,touchmove,touchcancel,touchend" : !("onpointerdown" in _docEl) ? "mousedown,mousemove,mouseup,mouseup" : "pointerdown,pointermove,pointercancel,pointerup").split(",");
35463		setTimeout(function () {
35464		  return _startup = 0;
35465		}, 500);
35466  
35467		_setScrollTrigger();
35468  
35469		_coreInitted = 1;
35470	  }
35471  
35472	  return _coreInitted;
35473	};
35474  
35475	_horizontal.op = _vertical;
35476	_scrollers.cache = 0;
35477	var Observer = function () {
35478	  function Observer(vars) {
35479		this.init(vars);
35480	  }
35481  
35482	  var _proto = Observer.prototype;
35483  
35484	  _proto.init = function init(vars) {
35485		_coreInitted || _initCore(gsap) || console.warn("Please gsap.registerPlugin(Observer)");
35486		ScrollTrigger || _setScrollTrigger();
35487		var tolerance = vars.tolerance,
35488			dragMinimum = vars.dragMinimum,
35489			type = vars.type,
35490			target = vars.target,
35491			lineHeight = vars.lineHeight,
35492			debounce = vars.debounce,
35493			preventDefault = vars.preventDefault,
35494			onStop = vars.onStop,
35495			onStopDelay = vars.onStopDelay,
35496			ignore = vars.ignore,
35497			wheelSpeed = vars.wheelSpeed,
35498			event = vars.event,
35499			onDragStart = vars.onDragStart,
35500			onDragEnd = vars.onDragEnd,
35501			onDrag = vars.onDrag,
35502			onPress = vars.onPress,
35503			onRelease = vars.onRelease,
35504			onRight = vars.onRight,
35505			onLeft = vars.onLeft,
35506			onUp = vars.onUp,
35507			onDown = vars.onDown,
35508			onChangeX = vars.onChangeX,
35509			onChangeY = vars.onChangeY,
35510			onChange = vars.onChange,
35511			onToggleX = vars.onToggleX,
35512			onToggleY = vars.onToggleY,
35513			onHover = vars.onHover,
35514			onHoverEnd = vars.onHoverEnd,
35515			onMove = vars.onMove,
35516			ignoreCheck = vars.ignoreCheck,
35517			isNormalizer = vars.isNormalizer,
35518			onGestureStart = vars.onGestureStart,
35519			onGestureEnd = vars.onGestureEnd,
35520			onWheel = vars.onWheel,
35521			onEnable = vars.onEnable,
35522			onDisable = vars.onDisable,
35523			onClick = vars.onClick,
35524			scrollSpeed = vars.scrollSpeed,
35525			capture = vars.capture,
35526			allowClicks = vars.allowClicks,
35527			lockAxis = vars.lockAxis,
35528			onLockAxis = vars.onLockAxis;
35529		this.target = target = _getTarget(target) || _docEl;
35530		this.vars = vars;
35531		ignore && (ignore = gsap.utils.toArray(ignore));
35532		tolerance = tolerance || 1e-9;
35533		dragMinimum = dragMinimum || 0;
35534		wheelSpeed = wheelSpeed || 1;
35535		scrollSpeed = scrollSpeed || 1;
35536		type = type || "wheel,touch,pointer";
35537		debounce = debounce !== false;
35538		lineHeight || (lineHeight = parseFloat(_win.getComputedStyle(_body).lineHeight) || 22);
35539  
35540		var id,
35541			onStopDelayedCall,
35542			dragged,
35543			moved,
35544			wheeled,
35545			locked,
35546			axis,
35547			self = this,
35548			prevDeltaX = 0,
35549			prevDeltaY = 0,
35550			passive = vars.passive || !preventDefault,
35551			scrollFuncX = _getScrollFunc(target, _horizontal),
35552			scrollFuncY = _getScrollFunc(target, _vertical),
35553			scrollX = scrollFuncX(),
35554			scrollY = scrollFuncY(),
35555			limitToTouch = ~type.indexOf("touch") && !~type.indexOf("pointer") && _eventTypes[0] === "pointerdown",
35556			isViewport = _isViewport(target),
35557			ownerDoc = target.ownerDocument || _doc,
35558			deltaX = [0, 0, 0],
35559			deltaY = [0, 0, 0],
35560			onClickTime = 0,
35561			clickCapture = function clickCapture() {
35562		  return onClickTime = _getTime();
35563		},
35564			_ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) {
35565		  return (self.event = e) && ignore && ~ignore.indexOf(e.target) || isPointerOrTouch && limitToTouch && e.pointerType !== "touch" || ignoreCheck && ignoreCheck(e, isPointerOrTouch);
35566		},
35567			onStopFunc = function onStopFunc() {
35568		  self._vx.reset();
35569  
35570		  self._vy.reset();
35571  
35572		  onStopDelayedCall.pause();
35573		  onStop && onStop(self);
35574		},
35575			update = function update() {
35576		  var dx = self.deltaX = _getAbsoluteMax(deltaX),
35577			  dy = self.deltaY = _getAbsoluteMax(deltaY),
35578			  changedX = Math.abs(dx) >= tolerance,
35579			  changedY = Math.abs(dy) >= tolerance;
35580  
35581		  onChange && (changedX || changedY) && onChange(self, dx, dy, deltaX, deltaY);
35582  
35583		  if (changedX) {
35584			onRight && self.deltaX > 0 && onRight(self);
35585			onLeft && self.deltaX < 0 && onLeft(self);
35586			onChangeX && onChangeX(self);
35587			onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self);
35588			prevDeltaX = self.deltaX;
35589			deltaX[0] = deltaX[1] = deltaX[2] = 0;
35590		  }
35591  
35592		  if (changedY) {
35593			onDown && self.deltaY > 0 && onDown(self);
35594			onUp && self.deltaY < 0 && onUp(self);
35595			onChangeY && onChangeY(self);
35596			onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self);
35597			prevDeltaY = self.deltaY;
35598			deltaY[0] = deltaY[1] = deltaY[2] = 0;
35599		  }
35600  
35601		  if (moved || dragged) {
35602			onMove && onMove(self);
35603  
35604			if (dragged) {
35605			  onDrag(self);
35606			  dragged = false;
35607			}
35608  
35609			moved = false;
35610		  }
35611  
35612		  locked && !(locked = false) && onLockAxis && onLockAxis(self);
35613  
35614		  if (wheeled) {
35615			onWheel(self);
35616			wheeled = false;
35617		  }
35618  
35619		  id = 0;
35620		},
35621			onDelta = function onDelta(x, y, index) {
35622		  deltaX[index] += x;
35623		  deltaY[index] += y;
35624  
35625		  self._vx.update(x);
35626  
35627		  self._vy.update(y);
35628  
35629		  debounce ? id || (id = requestAnimationFrame(update)) : update();
35630		},
35631			onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) {
35632		  if (lockAxis && !axis) {
35633			self.axis = axis = Math.abs(x) > Math.abs(y) ? "x" : "y";
35634			locked = true;
35635		  }
35636  
35637		  if (axis !== "y") {
35638			deltaX[2] += x;
35639  
35640			self._vx.update(x, true);
35641		  }
35642  
35643		  if (axis !== "x") {
35644			deltaY[2] += y;
35645  
35646			self._vy.update(y, true);
35647		  }
35648  
35649		  debounce ? id || (id = requestAnimationFrame(update)) : update();
35650		},
35651			_onDrag = function _onDrag(e) {
35652		  if (_ignoreCheck(e, 1)) {
35653			return;
35654		  }
35655  
35656		  e = _getEvent(e, preventDefault);
35657		  var x = e.clientX,
35658			  y = e.clientY,
35659			  dx = x - self.x,
35660			  dy = y - self.y,
35661			  isDragging = self.isDragging;
35662		  self.x = x;
35663		  self.y = y;
35664  
35665		  if (isDragging || Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum) {
35666			onDrag && (dragged = true);
35667			isDragging || (self.isDragging = true);
35668			onTouchOrPointerDelta(dx, dy);
35669			isDragging || onDragStart && onDragStart(self);
35670		  }
35671		},
35672			_onPress = self.onPress = function (e) {
35673		  if (_ignoreCheck(e, 1) || e && e.button) {
35674			return;
35675		  }
35676  
35677		  self.axis = axis = null;
35678		  onStopDelayedCall.pause();
35679		  self.isPressed = true;
35680		  e = _getEvent(e);
35681		  prevDeltaX = prevDeltaY = 0;
35682		  self.startX = self.x = e.clientX;
35683		  self.startY = self.y = e.clientY;
35684  
35685		  self._vx.reset();
35686  
35687		  self._vy.reset();
35688  
35689		  _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, passive, true);
35690  
35691		  self.deltaX = self.deltaY = 0;
35692		  onPress && onPress(self);
35693		},
35694			_onRelease = self.onRelease = function (e) {
35695		  if (_ignoreCheck(e, 1)) {
35696			return;
35697		  }
35698  
35699		  _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);
35700  
35701		  var isTrackingDrag = !isNaN(self.y - self.startY),
35702			  wasDragging = self.isDragging,
35703			  isDragNotClick = wasDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3),
35704			  eventData = _getEvent(e);
35705  
35706		  if (!isDragNotClick && isTrackingDrag) {
35707			self._vx.reset();
35708  
35709			self._vy.reset();
35710  
35711			if (preventDefault && allowClicks) {
35712			  gsap.delayedCall(0.08, function () {
35713				if (_getTime() - onClickTime > 300 && !e.defaultPrevented) {
35714				  if (e.target.click) {
35715					e.target.click();
35716				  } else if (ownerDoc.createEvent) {
35717					var syntheticEvent = ownerDoc.createEvent("MouseEvents");
35718					syntheticEvent.initMouseEvent("click", true, true, _win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null);
35719					e.target.dispatchEvent(syntheticEvent);
35720				  }
35721				}
35722			  });
35723			}
35724		  }
35725  
35726		  self.isDragging = self.isGesturing = self.isPressed = false;
35727		  onStop && wasDragging && !isNormalizer && onStopDelayedCall.restart(true);
35728		  onDragEnd && wasDragging && onDragEnd(self);
35729		  onRelease && onRelease(self, isDragNotClick);
35730		},
35731			_onGestureStart = function _onGestureStart(e) {
35732		  return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging);
35733		},
35734			_onGestureEnd = function _onGestureEnd() {
35735		  return (self.isGesturing = false) || onGestureEnd(self);
35736		},
35737			onScroll = function onScroll(e) {
35738		  if (_ignoreCheck(e)) {
35739			return;
35740		  }
35741  
35742		  var x = scrollFuncX(),
35743			  y = scrollFuncY();
35744		  onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1);
35745		  scrollX = x;
35746		  scrollY = y;
35747		  onStop && onStopDelayedCall.restart(true);
35748		},
35749			_onWheel = function _onWheel(e) {
35750		  if (_ignoreCheck(e)) {
35751			return;
35752		  }
35753  
35754		  e = _getEvent(e, preventDefault);
35755		  onWheel && (wheeled = true);
35756		  var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? _win.innerHeight : 1) * wheelSpeed;
35757		  onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0);
35758		  onStop && !isNormalizer && onStopDelayedCall.restart(true);
35759		},
35760			_onMove = function _onMove(e) {
35761		  if (_ignoreCheck(e)) {
35762			return;
35763		  }
35764  
35765		  var x = e.clientX,
35766			  y = e.clientY,
35767			  dx = x - self.x,
35768			  dy = y - self.y;
35769		  self.x = x;
35770		  self.y = y;
35771		  moved = true;
35772		  onStop && onStopDelayedCall.restart(true);
35773		  (dx || dy) && onTouchOrPointerDelta(dx, dy);
35774		},
35775			_onHover = function _onHover(e) {
35776		  self.event = e;
35777		  onHover(self);
35778		},
35779			_onHoverEnd = function _onHoverEnd(e) {
35780		  self.event = e;
35781		  onHoverEnd(self);
35782		},
35783			_onClick = function _onClick(e) {
35784		  return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self);
35785		};
35786  
35787		onStopDelayedCall = self._dc = gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause();
35788		self.deltaX = self.deltaY = 0;
35789		self._vx = _getVelocityProp(0, 50, true);
35790		self._vy = _getVelocityProp(0, 50, true);
35791		self.scrollX = scrollFuncX;
35792		self.scrollY = scrollFuncY;
35793		self.isDragging = self.isGesturing = self.isPressed = false;
vendor: 7,173 bytes, lines 35794-36036
35794  
35795		_context(this);
35796  
35797		self.enable = function (e) {
35798		  if (!self.isEnabled) {
35799			_addListener(isViewport ? ownerDoc : target, "scroll", _onScroll);
35800  
35801			type.indexOf("scroll") >= 0 && _addListener(isViewport ? ownerDoc : target, "scroll", onScroll, passive, capture);
35802			type.indexOf("wheel") >= 0 && _addListener(target, "wheel", _onWheel, passive, capture);
35803  
35804			if (type.indexOf("touch") >= 0 && _isTouch || type.indexOf("pointer") >= 0) {
35805			  _addListener(target, _eventTypes[0], _onPress, passive, capture);
35806  
35807			  _addListener(ownerDoc, _eventTypes[2], _onRelease);
35808  
35809			  _addListener(ownerDoc, _eventTypes[3], _onRelease);
35810  
35811			  allowClicks && _addListener(target, "click", clickCapture, true, true);
35812			  onClick && _addListener(target, "click", _onClick);
35813			  onGestureStart && _addListener(ownerDoc, "gesturestart", _onGestureStart);
35814			  onGestureEnd && _addListener(ownerDoc, "gestureend", _onGestureEnd);
35815			  onHover && _addListener(target, _pointerType + "enter", _onHover);
35816			  onHoverEnd && _addListener(target, _pointerType + "leave", _onHoverEnd);
35817			  onMove && _addListener(target, _pointerType + "move", _onMove);
35818			}
35819  
35820			self.isEnabled = true;
35821			e && e.type && _onPress(e);
35822			onEnable && onEnable(self);
35823		  }
35824  
35825		  return self;
35826		};
35827  
35828		self.disable = function () {
35829		  if (self.isEnabled) {
35830			_observers.filter(function (o) {
35831			  return o !== self && _isViewport(o.target);
35832			}).length || _removeListener(isViewport ? ownerDoc : target, "scroll", _onScroll);
35833  
35834			if (self.isPressed) {
35835			  self._vx.reset();
35836  
35837			  self._vy.reset();
35838  
35839			  _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);
35840			}
35841  
35842			_removeListener(isViewport ? ownerDoc : target, "scroll", onScroll, capture);
35843  
35844			_removeListener(target, "wheel", _onWheel, capture);
35845  
35846			_removeListener(target, _eventTypes[0], _onPress, capture);
35847  
35848			_removeListener(ownerDoc, _eventTypes[2], _onRelease);
35849  
35850			_removeListener(ownerDoc, _eventTypes[3], _onRelease);
35851  
35852			_removeListener(target, "click", clickCapture, true);
35853  
35854			_removeListener(target, "click", _onClick);
35855  
35856			_removeListener(ownerDoc, "gesturestart", _onGestureStart);
35857  
35858			_removeListener(ownerDoc, "gestureend", _onGestureEnd);
35859  
35860			_removeListener(target, _pointerType + "enter", _onHover);
35861  
35862			_removeListener(target, _pointerType + "leave", _onHoverEnd);
35863  
35864			_removeListener(target, _pointerType + "move", _onMove);
35865  
35866			self.isEnabled = self.isPressed = self.isDragging = false;
35867			onDisable && onDisable(self);
35868		  }
35869		};
35870  
35871		self.kill = self.revert = function () {
35872		  self.disable();
35873  
35874		  var i = _observers.indexOf(self);
35875  
35876		  i >= 0 && _observers.splice(i, 1);
35877		  _normalizer === self && (_normalizer = 0);
35878		};
35879  
35880		_observers.push(self);
35881  
35882		isNormalizer && _isViewport(target) && (_normalizer = self);
35883		self.enable(event);
35884	  };
35885  
35886	  _createClass(Observer, [{
35887		key: "velocityX",
35888		get: function get() {
35889		  return this._vx.getVelocity();
35890		}
35891	  }, {
35892		key: "velocityY",
35893		get: function get() {
35894		  return this._vy.getVelocity();
35895		}
35896	  }]);
35897  
35898	  return Observer;
35899	}();
35900	Observer.version = "3.12.5";
35901  
35902	Observer.create = function (vars) {
35903	  return new Observer(vars);
35904	};
35905  
35906	Observer.register = _initCore;
35907  
35908	Observer.getAll = function () {
35909	  return _observers.slice();
35910	};
35911  
35912	Observer.getById = function (id) {
35913	  return _observers.filter(function (o) {
35914		return o.vars.id === id;
35915	  })[0];
35916	};
35917  
35918	_getGSAP() && gsap.registerPlugin(Observer);
35919  
35920	/*!
35921	 * ScrollTrigger 3.12.5
35922	 * https://gsap.com
35923	 *
35924	 * @license Copyright 2008-2024, GreenSock. All rights reserved.
35925	 * Subject to the terms at https://gsap.com/standard-license or for
35926	 * Club GSAP members, the agreement issued with that membership.
35927	 * @author: Jack Doyle, [email protected]
35928	*/
35929  
35930	var gsap$1,
35931		_coreInitted$1,
35932		_win$1,
35933		_doc$1,
35934		_docEl$1,
35935		_body$1,
35936		_root$1,
35937		_resizeDelay,
35938		_toArray,
35939		_clamp$1,
35940		_time2,
35941		_syncInterval,
35942		_refreshing,
35943		_pointerIsDown,
35944		_transformProp,
35945		_i,
35946		_prevWidth,
35947		_prevHeight,
35948		_autoRefresh,
35949		_sort,
35950		_suppressOverwrites,
35951		_ignoreResize,
35952		_normalizer$1,
35953		_ignoreMobileResize,
35954		_baseScreenHeight,
35955		_baseScreenWidth,
35956		_fixIOSBug,
35957		_context$1,
35958		_scrollRestoration,
35959		_div100vh,
35960		_100vh,
35961		_isReverted,
35962		_clampingMax,
35963		_limitCallbacks,
35964		_startup$1 = 1,
35965		_getTime$1 = Date.now,
35966		_time1 = _getTime$1(),
35967		_lastScrollTime = 0,
35968		_enabled = 0,
35969		_parseClamp = function _parseClamp(value, type, self) {
35970	  var clamp = _isString(value) && (value.substr(0, 6) === "clamp(" || value.indexOf("max") > -1);
35971	  self["_" + type + "Clamp"] = clamp;
35972	  return clamp ? value.substr(6, value.length - 7) : value;
35973	},
35974		_keepClamp = function _keepClamp(value, clamp) {
35975	  return clamp && (!_isString(value) || value.substr(0, 6) !== "clamp(") ? "clamp(" + value + ")" : value;
35976	},
35977		_rafBugFix = function _rafBugFix() {
35978	  return _enabled && requestAnimationFrame(_rafBugFix);
35979	},
35980		_pointerDownHandler = function _pointerDownHandler() {
35981	  return _pointerIsDown = 1;
35982	},
35983		_pointerUpHandler = function _pointerUpHandler() {
35984	  return _pointerIsDown = 0;
35985	},
35986		_passThrough = function _passThrough(v) {
35987	  return v;
35988	},
35989		_round = function _round(value) {
35990	  return Math.round(value * 100000) / 100000 || 0;
35991	},
35992		_windowExists = function _windowExists() {
35993	  return typeof window !== "undefined";
35994	},
35995		_getGSAP$1 = function _getGSAP() {
35996	  return gsap$1 || _windowExists() && (gsap$1 = window.gsap) && gsap$1.registerPlugin && gsap$1;
35997	},
35998		_isViewport$1 = function _isViewport(e) {
35999	  return !!~_root$1.indexOf(e);
36000	},
36001		_getViewportDimension = function _getViewportDimension(dimensionProperty) {
36002	  return (dimensionProperty === "Height" ? _100vh : _win$1["inner" + dimensionProperty]) || _docEl$1["client" + dimensionProperty] || _body$1["client" + dimensionProperty];
36003	},
36004		_getBoundsFunc = function _getBoundsFunc(element) {
36005	  return _getProxyProp(element, "getBoundingClientRect") || (_isViewport$1(element) ? function () {
36006		_winOffsets.width = _win$1.innerWidth;
36007		_winOffsets.height = _100vh;
36008		return _winOffsets;
36009	  } : function () {
36010		return _getBounds(element);
36011	  });
36012	},
36013		_getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref) {
36014	  var d = _ref.d,
36015		  d2 = _ref.d2,
36016		  a = _ref.a;
36017	  return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () {
36018		return a()[d];
36019	  } : function () {
36020		return (isViewport ? _getViewportDimension(d2) : scroller["client" + d2]) || 0;
36021	  };
36022	},
36023		_getOffsetsFunc = function _getOffsetsFunc(element, isViewport) {
36024	  return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () {
36025		return _winOffsets;
36026	  };
36027	},
36028		_maxScroll = function _maxScroll(element, _ref2) {
36029	  var s = _ref2.s,
36030		  d2 = _ref2.d2,
36031		  d = _ref2.d,
36032		  a = _ref2.a;
36033	  return Math.max(0, (s = "scroll" + d2) && (a = _getProxyProp(element, s)) ? a() - _getBoundsFunc(element)()[d] : _isViewport$1(element) ? (_docEl$1[s] || _body$1[s]) - _getViewportDimension(d2) : element[s] - element["offset" + d2]);
36034	},
36035		_iterateAutoRefresh = function _iterateAutoRefresh(func, events) {
36036	  for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 4,900 bytes, lines 36037-36218
36037		(!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]);
36038	  }
36039	},
36040		_isString = function _isString(value) {
36041	  return typeof value === "string";
36042	},
36043		_isFunction = function _isFunction(value) {
36044	  return typeof value === "function";
36045	},
36046		_isNumber = function _isNumber(value) {
36047	  return typeof value === "number";
36048	},
36049		_isObject = function _isObject(value) {
36050	  return typeof value === "object";
36051	},
36052		_endAnimation = function _endAnimation(animation, reversed, pause) {
36053	  return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause();
36054	},
36055		_callback = function _callback(self, func) {
36056	  if (self.enabled) {
36057		var result = self._ctx ? self._ctx.add(function () {
36058		  return func(self);
36059		}) : func(self);
36060		result && result.totalTime && (self.callbackAnimation = result);
36061	  }
36062	},
36063		_abs = Math.abs,
36064		_left = "left",
36065		_top = "top",
36066		_right = "right",
36067		_bottom = "bottom",
36068		_width = "width",
36069		_height = "height",
36070		_Right = "Right",
36071		_Left = "Left",
36072		_Top = "Top",
36073		_Bottom = "Bottom",
36074		_padding = "padding",
36075		_margin = "margin",
36076		_Width = "Width",
36077		_Height = "Height",
36078		_px = "px",
36079		_getComputedStyle = function _getComputedStyle(element) {
36080	  return _win$1.getComputedStyle(element);
36081	},
36082		_makePositionable = function _makePositionable(element) {
36083	  var position = _getComputedStyle(element).position;
36084  
36085	  element.style.position = position === "absolute" || position === "fixed" ? position : "relative";
36086	},
36087		_setDefaults = function _setDefaults(obj, defaults) {
36088	  for (var p in defaults) {
36089		p in obj || (obj[p] = defaults[p]);
36090	  }
36091  
36092	  return obj;
36093	},
36094		_getBounds = function _getBounds(element, withoutTransforms) {
36095	  var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap$1.to(element, {
36096		x: 0,
36097		y: 0,
36098		xPercent: 0,
36099		yPercent: 0,
36100		rotation: 0,
36101		rotationX: 0,
36102		rotationY: 0,
36103		scale: 1,
36104		skewX: 0,
36105		skewY: 0
36106	  }).progress(1),
36107		  bounds = element.getBoundingClientRect();
36108	  tween && tween.progress(0).kill();
36109	  return bounds;
36110	},
36111		_getSize = function _getSize(element, _ref3) {
36112	  var d2 = _ref3.d2;
36113	  return element["offset" + d2] || element["client" + d2] || 0;
36114	},
36115		_getLabelRatioArray = function _getLabelRatioArray(timeline) {
36116	  var a = [],
36117		  labels = timeline.labels,
36118		  duration = timeline.duration(),
36119		  p;
36120  
36121	  for (p in labels) {
36122		a.push(labels[p] / duration);
36123	  }
36124  
36125	  return a;
36126	},
36127		_getClosestLabel = function _getClosestLabel(animation) {
36128	  return function (value) {
36129		return gsap$1.utils.snap(_getLabelRatioArray(animation), value);
36130	  };
36131	},
36132		_snapDirectional = function _snapDirectional(snapIncrementOrArray) {
36133	  var snap = gsap$1.utils.snap(snapIncrementOrArray),
36134		  a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) {
36135		return a - b;
36136	  });
36137	  return a ? function (value, direction, threshold) {
36138		if (threshold === void 0) {
36139		  threshold = 1e-3;
36140		}
36141  
36142		var i;
36143  
36144		if (!direction) {
36145		  return snap(value);
36146		}
36147  
36148		if (direction > 0) {
36149		  value -= threshold;
36150  
36151		  for (i = 0; i < a.length; i++) {
36152			if (a[i] >= value) {
36153			  return a[i];
36154			}
36155		  }
36156  
36157		  return a[i - 1];
36158		} else {
36159		  i = a.length;
36160		  value += threshold;
36161  
36162		  while (i--) {
36163			if (a[i] <= value) {
36164			  return a[i];
36165			}
36166		  }
36167		}
36168  
36169		return a[0];
36170	  } : function (value, direction, threshold) {
36171		if (threshold === void 0) {
36172		  threshold = 1e-3;
36173		}
36174  
36175		var snapped = snap(value);
36176		return !direction || Math.abs(snapped - value) < threshold || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray);
36177	  };
36178	},
36179		_getLabelAtDirection = function _getLabelAtDirection(timeline) {
36180	  return function (value, st) {
36181		return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction);
36182	  };
36183	},
36184		_multiListener = function _multiListener(func, element, types, callback) {
36185	  return types.split(",").forEach(function (type) {
36186		return func(element, type, callback);
36187	  });
36188	},
36189		_addListener$1 = function _addListener(element, type, func, nonPassive, capture) {
36190	  return element.addEventListener(type, func, {
36191		passive: !nonPassive,
36192		capture: !!capture
36193	  });
36194	},
36195		_removeListener$1 = function _removeListener(element, type, func, capture) {
36196	  return element.removeEventListener(type, func, !!capture);
36197	},
36198		_wheelListener = function _wheelListener(func, el, scrollFunc) {
36199	  scrollFunc = scrollFunc && scrollFunc.wheelHandler;
36200  
36201	  if (scrollFunc) {
36202		func(el, "wheel", scrollFunc);
36203		func(el, "touchmove", scrollFunc);
36204	  }
36205	},
36206		_markerDefaults = {
36207	  startColor: "green",
36208	  endColor: "red",
36209	  indent: 0,
36210	  fontSize: "16px",
36211	  fontWeight: "normal"
36212	},
36213		_defaults = {
36214	  toggleActions: "play",
36215	  anticipatePin: 0
36216	},
36217		_keywords = {
36218	  top: 0,
vendor: 14,119 bytes, lines 36219-36659
36219	  left: 0,
36220	  center: 0.5,
36221	  bottom: 1,
36222	  right: 1
36223	},
36224		_offsetToPx = function _offsetToPx(value, size) {
36225	  if (_isString(value)) {
36226		var eqIndex = value.indexOf("="),
36227			relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0;
36228  
36229		if (~eqIndex) {
36230		  value.indexOf("%") > eqIndex && (relative *= size / 100);
36231		  value = value.substr(0, eqIndex - 1);
36232		}
36233  
36234		value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0);
36235	  }
36236  
36237	  return value;
36238	},
36239		_createMarker = function _createMarker(type, name, container, direction, _ref4, offset, matchWidthEl, containerAnimation) {
36240	  var startColor = _ref4.startColor,
36241		  endColor = _ref4.endColor,
36242		  fontSize = _ref4.fontSize,
36243		  indent = _ref4.indent,
36244		  fontWeight = _ref4.fontWeight;
36245  
36246	  var e = _doc$1.createElement("div"),
36247		  useFixedPosition = _isViewport$1(container) || _getProxyProp(container, "pinType") === "fixed",
36248		  isScroller = type.indexOf("scroller") !== -1,
36249		  parent = useFixedPosition ? _body$1 : container,
36250		  isStart = type.indexOf("start") !== -1,
36251		  color = isStart ? startColor : endColor,
36252		  css = "border-color:" + color + ";font-size:" + fontSize + ";color:" + color + ";font-weight:" + fontWeight + ";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;";
36253  
36254	  css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;");
36255	  (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;");
36256	  matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;");
36257	  e._isStart = isStart;
36258	  e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : ""));
36259	  e.style.cssText = css;
36260	  e.innerText = name || name === 0 ? type + "-" + name : type;
36261	  parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e);
36262	  e._offset = e["offset" + direction.op.d2];
36263  
36264	  _positionMarker(e, 0, direction, isStart);
36265  
36266	  return e;
36267	},
36268		_positionMarker = function _positionMarker(marker, start, direction, flipped) {
36269	  var vars = {
36270		display: "block"
36271	  },
36272		  side = direction[flipped ? "os2" : "p2"],
36273		  oppositeSide = direction[flipped ? "p2" : "os2"];
36274	  marker._isFlipped = flipped;
36275	  vars[direction.a + "Percent"] = flipped ? -100 : 0;
36276	  vars[direction.a] = flipped ? "1px" : 0;
36277	  vars["border" + side + _Width] = 1;
36278	  vars["border" + oppositeSide + _Width] = 0;
36279	  vars[direction.p] = start + "px";
36280	  gsap$1.set(marker, vars);
36281	},
36282		_triggers = [],
36283		_ids = {},
36284		_rafID,
36285		_sync = function _sync() {
36286	  return _getTime$1() - _lastScrollTime > 34 && (_rafID || (_rafID = requestAnimationFrame(_updateAll)));
36287	},
36288		_onScroll$1 = function _onScroll() {
36289	  if (!_normalizer$1 || !_normalizer$1.isPressed || _normalizer$1.startX > _body$1.clientWidth) {
36290		_scrollers.cache++;
36291  
36292		if (_normalizer$1) {
36293		  _rafID || (_rafID = requestAnimationFrame(_updateAll));
36294		} else {
36295		  _updateAll();
36296		}
36297  
36298		_lastScrollTime || _dispatch("scrollStart");
36299		_lastScrollTime = _getTime$1();
36300	  }
36301	},
36302		_setBaseDimensions = function _setBaseDimensions() {
36303	  _baseScreenWidth = _win$1.innerWidth;
36304	  _baseScreenHeight = _win$1.innerHeight;
36305	},
36306		_onResize = function _onResize() {
36307	  _scrollers.cache++;
36308	  !_refreshing && !_ignoreResize && !_doc$1.fullscreenElement && !_doc$1.webkitFullscreenElement && (!_ignoreMobileResize || _baseScreenWidth !== _win$1.innerWidth || Math.abs(_win$1.innerHeight - _baseScreenHeight) > _win$1.innerHeight * 0.25) && _resizeDelay.restart(true);
36309	},
36310		_listeners = {},
36311		_emptyArray = [],
36312		_softRefresh = function _softRefresh() {
36313	  return _removeListener$1(ScrollTrigger$1, "scrollEnd", _softRefresh) || _refreshAll(true);
36314	},
36315		_dispatch = function _dispatch(type) {
36316	  return _listeners[type] && _listeners[type].map(function (f) {
36317		return f();
36318	  }) || _emptyArray;
36319	},
36320		_savedStyles = [],
36321		_revertRecorded = function _revertRecorded(media) {
36322	  for (var i = 0; i < _savedStyles.length; i += 5) {
36323		if (!media || _savedStyles[i + 4] && _savedStyles[i + 4].query === media) {
36324		  _savedStyles[i].style.cssText = _savedStyles[i + 1];
36325		  _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || "");
36326		  _savedStyles[i + 3].uncache = 1;
36327		}
36328	  }
36329	},
36330		_revertAll = function _revertAll(kill, media) {
36331	  var trigger;
36332  
36333	  for (_i = 0; _i < _triggers.length; _i++) {
36334		trigger = _triggers[_i];
36335  
36336		if (trigger && (!media || trigger._ctx === media)) {
36337		  if (kill) {
36338			trigger.kill(1);
36339		  } else {
36340			trigger.revert(true, true);
36341		  }
36342		}
36343	  }
36344  
36345	  _isReverted = true;
36346	  media && _revertRecorded(media);
36347	  media || _dispatch("revert");
36348	},
36349		_clearScrollMemory = function _clearScrollMemory(scrollRestoration, force) {
36350	  _scrollers.cache++;
36351	  (force || !_refreshingAll) && _scrollers.forEach(function (obj) {
36352		return _isFunction(obj) && obj.cacheID++ && (obj.rec = 0);
36353	  });
36354	  _isString(scrollRestoration) && (_win$1.history.scrollRestoration = _scrollRestoration = scrollRestoration);
36355	},
36356		_refreshingAll,
36357		_refreshID = 0,
36358		_queueRefreshID,
36359		_queueRefreshAll = function _queueRefreshAll() {
36360	  if (_queueRefreshID !== _refreshID) {
36361		var id = _queueRefreshID = _refreshID;
36362		requestAnimationFrame(function () {
36363		  return id === _refreshID && _refreshAll(true);
36364		});
36365	  }
36366	},
36367		_refresh100vh = function _refresh100vh() {
36368	  _body$1.appendChild(_div100vh);
36369  
36370	  _100vh = !_normalizer$1 && _div100vh.offsetHeight || _win$1.innerHeight;
36371  
36372	  _body$1.removeChild(_div100vh);
36373	},
36374		_hideAllMarkers = function _hideAllMarkers(hide) {
36375	  return _toArray(".gsap-marker-start, .gsap-marker-end, .gsap-marker-scroller-start, .gsap-marker-scroller-end").forEach(function (el) {
36376		return el.style.display = hide ? "none" : "block";
36377	  });
36378	},
36379		_refreshAll = function _refreshAll(force, skipRevert) {
36380	  if (_lastScrollTime && !force && !_isReverted) {
36381		_addListener$1(ScrollTrigger$1, "scrollEnd", _softRefresh);
36382  
36383		return;
36384	  }
36385  
36386	  _refresh100vh();
36387  
36388	  _refreshingAll = ScrollTrigger$1.isRefreshing = true;
36389  
36390	  _scrollers.forEach(function (obj) {
36391		return _isFunction(obj) && ++obj.cacheID && (obj.rec = obj());
36392	  });
36393  
36394	  var refreshInits = _dispatch("refreshInit");
36395  
36396	  _sort && ScrollTrigger$1.sort();
36397	  skipRevert || _revertAll();
36398  
36399	  _scrollers.forEach(function (obj) {
36400		if (_isFunction(obj)) {
36401		  obj.smooth && (obj.target.style.scrollBehavior = "auto");
36402		  obj(0);
36403		}
36404	  });
36405  
36406	  _triggers.slice(0).forEach(function (t) {
36407		return t.refresh();
36408	  });
36409  
36410	  _isReverted = false;
36411  
36412	  _triggers.forEach(function (t) {
36413		if (t._subPinOffset && t.pin) {
36414		  var prop = t.vars.horizontal ? "offsetWidth" : "offsetHeight",
36415			  original = t.pin[prop];
36416		  t.revert(true, 1);
36417		  t.adjustPinSpacing(t.pin[prop] - original);
36418		  t.refresh();
36419		}
36420	  });
36421  
36422	  _clampingMax = 1;
36423  
36424	  _hideAllMarkers(true);
36425  
36426	  _triggers.forEach(function (t) {
36427		var max = _maxScroll(t.scroller, t._dir),
36428			endClamp = t.vars.end === "max" || t._endClamp && t.end > max,
36429			startClamp = t._startClamp && t.start >= max;
36430  
36431		(endClamp || startClamp) && t.setPositions(startClamp ? max - 1 : t.start, endClamp ? Math.max(startClamp ? max : t.start + 1, max) : t.end, true);
36432	  });
36433  
36434	  _hideAllMarkers(false);
36435  
36436	  _clampingMax = 0;
36437	  refreshInits.forEach(function (result) {
36438		return result && result.render && result.render(-1);
36439	  });
36440  
36441	  _scrollers.forEach(function (obj) {
36442		if (_isFunction(obj)) {
36443		  obj.smooth && requestAnimationFrame(function () {
36444			return obj.target.style.scrollBehavior = "smooth";
36445		  });
36446		  obj.rec && obj(obj.rec);
36447		}
36448	  });
36449  
36450	  _clearScrollMemory(_scrollRestoration, 1);
36451  
36452	  _resizeDelay.pause();
36453  
36454	  _refreshID++;
36455	  _refreshingAll = 2;
36456  
36457	  _updateAll(2);
36458  
36459	  _triggers.forEach(function (t) {
36460		return _isFunction(t.vars.onRefresh) && t.vars.onRefresh(t);
36461	  });
36462  
36463	  _refreshingAll = ScrollTrigger$1.isRefreshing = false;
36464  
36465	  _dispatch("refresh");
36466	},
36467		_lastScroll = 0,
36468		_direction = 1,
36469		_primary,
36470		_updateAll = function _updateAll(force) {
36471	  if (force === 2 || !_refreshingAll && !_isReverted) {
36472		ScrollTrigger$1.isUpdating = true;
36473		_primary && _primary.update(0);
36474  
36475		var l = _triggers.length,
36476			time = _getTime$1(),
36477			recordVelocity = time - _time1 >= 50,
36478			scroll = l && _triggers[0].scroll();
36479  
36480		_direction = _lastScroll > scroll ? -1 : 1;
36481		_refreshingAll || (_lastScroll = scroll);
36482  
36483		if (recordVelocity) {
36484		  if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) {
36485			_lastScrollTime = 0;
36486  
36487			_dispatch("scrollEnd");
36488		  }
36489  
36490		  _time2 = _time1;
36491		  _time1 = time;
36492		}
36493  
36494		if (_direction < 0) {
36495		  _i = l;
36496  
36497		  while (_i-- > 0) {
36498			_triggers[_i] && _triggers[_i].update(0, recordVelocity);
36499		  }
36500  
36501		  _direction = 1;
36502		} else {
36503		  for (_i = 0; _i < l; _i++) {
36504			_triggers[_i] && _triggers[_i].update(0, recordVelocity);
36505		  }
36506		}
36507  
36508		ScrollTrigger$1.isUpdating = false;
36509	  }
36510  
36511	  _rafID = 0;
36512	},
36513		_propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, "display", "flexShrink", "float", "zIndex", "gridColumnStart", "gridColumnEnd", "gridRowStart", "gridRowEnd", "gridArea", "justifySelf", "alignSelf", "placeSelf", "order"],
36514		_stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]),
36515		_swapPinOut = function _swapPinOut(pin, spacer, state) {
36516	  _setState(state);
36517  
36518	  var cache = pin._gsap;
36519  
36520	  if (cache.spacerIsNative) {
36521		_setState(cache.spacerState);
36522	  } else if (pin._gsap.swappedIn) {
36523		var parent = spacer.parentNode;
36524  
36525		if (parent) {
36526		  parent.insertBefore(pin, spacer);
36527		  parent.removeChild(spacer);
36528		}
36529	  }
36530  
36531	  pin._gsap.swappedIn = false;
36532	},
36533		_swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) {
36534	  if (!pin._gsap.swappedIn) {
36535		var i = _propNamesToCopy.length,
36536			spacerStyle = spacer.style,
36537			pinStyle = pin.style,
36538			p;
36539  
36540		while (i--) {
36541		  p = _propNamesToCopy[i];
36542		  spacerStyle[p] = cs[p];
36543		}
36544  
36545		spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative";
36546		cs.display === "inline" && (spacerStyle.display = "inline-block");
36547		pinStyle[_bottom] = pinStyle[_right] = "auto";
36548		spacerStyle.flexBasis = cs.flexBasis || "auto";
36549		spacerStyle.overflow = "visible";
36550		spacerStyle.boxSizing = "border-box";
36551		spacerStyle[_width] = _getSize(pin, _horizontal) + _px;
36552		spacerStyle[_height] = _getSize(pin, _vertical) + _px;
36553		spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0";
36554  
36555		_setState(spacerState);
36556  
36557		pinStyle[_width] = pinStyle["max" + _Width] = cs[_width];
36558		pinStyle[_height] = pinStyle["max" + _Height] = cs[_height];
36559		pinStyle[_padding] = cs[_padding];
36560  
36561		if (pin.parentNode !== spacer) {
36562		  pin.parentNode.insertBefore(spacer, pin);
36563		  spacer.appendChild(pin);
36564		}
36565  
36566		pin._gsap.swappedIn = true;
36567	  }
36568	},
36569		_capsExp = /([A-Z])/g,
36570		_setState = function _setState(state) {
36571	  if (state) {
36572		var style = state.t.style,
36573			l = state.length,
36574			i = 0,
36575			p,
36576			value;
36577		(state.t._gsap || gsap$1.core.getCache(state.t)).uncache = 1;
36578  
36579		for (; i < l; i += 2) {
36580		  value = state[i + 1];
36581		  p = state[i];
36582  
36583		  if (value) {
36584			style[p] = value;
36585		  } else if (style[p]) {
36586			style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());
36587		  }
36588		}
36589	  }
36590	},
36591		_getState = function _getState(element) {
36592	  var l = _stateProps.length,
36593		  style = element.style,
36594		  state = [],
36595		  i = 0;
36596  
36597	  for (; i < l; i++) {
36598		state.push(_stateProps[i], style[_stateProps[i]]);
36599	  }
36600  
36601	  state.t = element;
36602	  return state;
36603	},
36604		_copyState = function _copyState(state, override, omitOffsets) {
36605	  var result = [],
36606		  l = state.length,
36607		  i = omitOffsets ? 8 : 0,
36608		  p;
36609  
36610	  for (; i < l; i += 2) {
36611		p = state[i];
36612		result.push(p, p in override ? override[p] : state[i + 1]);
36613	  }
36614  
36615	  result.t = state.t;
36616	  return result;
36617	},
36618		_winOffsets = {
36619	  left: 0,
36620	  top: 0
36621	},
36622		_parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation, clampZeroProp) {
36623	  _isFunction(value) && (value = value(self));
36624  
36625	  if (_isString(value) && value.substr(0, 3) === "max") {
36626		value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0);
36627	  }
36628  
36629	  var time = containerAnimation ? containerAnimation.time() : 0,
36630		  p1,
36631		  p2,
36632		  element;
36633	  containerAnimation && containerAnimation.seek(0);
36634	  isNaN(value) || (value = +value);
36635  
36636	  if (!_isNumber(value)) {
36637		_isFunction(trigger) && (trigger = trigger(self));
36638		var offsets = (value || "0").split(" "),
36639			bounds,
36640			localOffset,
36641			globalOffset,
36642			display;
36643		element = _getTarget(trigger, self) || _body$1;
36644		bounds = _getBounds(element) || {};
36645  
36646		if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") {
36647		  display = element.style.display;
36648		  element.style.display = "block";
36649		  bounds = _getBounds(element);
36650		  display ? element.style.display = display : element.style.removeProperty("display");
36651		}
36652  
36653		localOffset = _offsetToPx(offsets[0], bounds[direction.d]);
36654		globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize);
36655		value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset;
36656		markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20);
36657		scrollerSize -= scrollerSize - globalOffset;
36658	  } else {
36659		containerAnimation && (value = gsap$1.utils.mapRange(containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, 0, scrollerMa
vendor: 4,541 bytes, lines 36659-36815
36659x, value));
36660		markerScroller && _positionMarker(markerScroller, scrollerSize, direction, true);
36661	  }
36662  
36663	  if (clampZeroProp) {
36664		self[clampZeroProp] = value || -0.001;
36665		value < 0 && (value = 0);
36666	  }
36667  
36668	  if (marker) {
36669		var position = value + scrollerSize,
36670			isStart = marker._isStart;
36671		p1 = "scroll" + direction.d2;
36672  
36673		_positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body$1[p1], _docEl$1[p1]) : marker.parentNode[p1]) <= position + 1);
36674  
36675		if (useFixedPosition) {
36676		  scrollerBounds = _getBounds(markerScroller);
36677		  useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px);
36678		}
36679	  }
36680  
36681	  if (containerAnimation && element) {
36682		p1 = _getBounds(element);
36683		containerAnimation.seek(scrollerMax);
36684		p2 = _getBounds(element);
36685		containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p];
36686		value = value / containerAnimation._caScrollDist * scrollerMax;
36687	  }
36688  
36689	  containerAnimation && containerAnimation.seek(time);
36690	  return containerAnimation ? value : Math.round(value);
36691	},
36692		_prefixExp = /(webkit|moz|length|cssText|inset)/i,
36693		_reparent = function _reparent(element, parent, top, left) {
36694	  if (element.parentNode !== parent) {
36695		var style = element.style,
36696			p,
36697			cs;
36698  
36699		if (parent === _body$1) {
36700		  element._stOrig = style.cssText;
36701		  cs = _getComputedStyle(element);
36702  
36703		  for (p in cs) {
36704			if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") {
36705			  style[p] = cs[p];
36706			}
36707		  }
36708  
36709		  style.top = top;
36710		  style.left = left;
36711		} else {
36712		  style.cssText = element._stOrig;
36713		}
36714  
36715		gsap$1.core.getCache(element).uncache = 1;
36716		parent.appendChild(element);
36717	  }
36718	},
36719		_interruptionTracker = function _interruptionTracker(getValueFunc, initialValue, onInterrupt) {
36720	  var last1 = initialValue,
36721		  last2 = last1;
36722	  return function (value) {
36723		var current = Math.round(getValueFunc());
36724  
36725		if (current !== last1 && current !== last2 && Math.abs(current - last1) > 3 && Math.abs(current - last2) > 3) {
36726		  value = current;
36727		  onInterrupt && onInterrupt();
36728		}
36729  
36730		last2 = last1;
36731		last1 = value;
36732		return value;
36733	  };
36734	},
36735		_shiftMarker = function _shiftMarker(marker, direction, value) {
36736	  var vars = {};
36737	  vars[direction.p] = "+=" + value;
36738	  gsap$1.set(marker, vars);
36739	},
36740		_getTweenCreator = function _getTweenCreator(scroller, direction) {
36741	  var getScroll = _getScrollFunc(scroller, direction),
36742		  prop = "_scroll" + direction.p2,
36743		  getTween = function getTween(scrollTo, vars, initialValue, change1, change2) {
36744		var tween = getTween.tween,
36745			onComplete = vars.onComplete,
36746			modifiers = {};
36747		initialValue = initialValue || getScroll();
36748  
36749		var checkForInterruption = _interruptionTracker(getScroll, initialValue, function () {
36750		  tween.kill();
36751		  getTween.tween = 0;
36752		});
36753  
36754		change2 = change1 && change2 || 0;
36755		change1 = change1 || scrollTo - initialValue;
36756		tween && tween.kill();
36757		vars[prop] = scrollTo;
36758		vars.inherit = false;
36759		vars.modifiers = modifiers;
36760  
36761		modifiers[prop] = function () {
36762		  return checkForInterruption(initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio);
36763		};
36764  
36765		vars.onUpdate = function () {
36766		  _scrollers.cache++;
36767		  getTween.tween && _updateAll();
36768		};
36769  
36770		vars.onComplete = function () {
36771		  getTween.tween = 0;
36772		  onComplete && onComplete.call(tween);
36773		};
36774  
36775		tween = getTween.tween = gsap$1.to(scroller, vars);
36776		return tween;
36777	  };
36778  
36779	  scroller[prop] = getScroll;
36780  
36781	  getScroll.wheelHandler = function () {
36782		return getTween.tween && getTween.tween.kill() && (getTween.tween = 0);
36783	  };
36784  
36785	  _addListener$1(scroller, "wheel", getScroll.wheelHandler);
36786  
36787	  ScrollTrigger$1.isTouch && _addListener$1(scroller, "touchmove", getScroll.wheelHandler);
36788	  return getTween;
36789	};
36790  
36791	var ScrollTrigger$1 = function () {
36792	  function ScrollTrigger(vars, animation) {
36793		_coreInitted$1 || ScrollTrigger.register(gsap$1) || console.warn("Please gsap.registerPlugin(ScrollTrigger)");
36794  
36795		_context$1(this);
36796  
36797		this.init(vars, animation);
36798	  }
36799  
36800	  var _proto = ScrollTrigger.prototype;
36801  
36802	  _proto.init = function init(vars, animation) {
36803		this.progress = this.start = 0;
36804		this.vars && this.kill(true, true);
36805  
36806		if (!_enabled) {
36807		  this.update = this.refresh = this.kill = _passThrough;
36808		  return;
36809		}
36810  
36811		vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? {
36812		  trigger: vars
36813		} : vars, _defaults);
36814  
36815		var _vars = vars,
vendor: 4,184 bytes, lines 36816-36956
36816			onUpdate = _vars.onUpdate,
36817			toggleClass = _vars.toggleClass,
36818			id = _vars.id,
36819			onToggle = _vars.onToggle,
36820			onRefresh = _vars.onRefresh,
36821			scrub = _vars.scrub,
36822			trigger = _vars.trigger,
36823			pin = _vars.pin,
36824			pinSpacing = _vars.pinSpacing,
36825			invalidateOnRefresh = _vars.invalidateOnRefresh,
36826			anticipatePin = _vars.anticipatePin,
36827			onScrubComplete = _vars.onScrubComplete,
36828			onSnapComplete = _vars.onSnapComplete,
36829			once = _vars.once,
36830			snap = _vars.snap,
36831			pinReparent = _vars.pinReparent,
36832			pinSpacer = _vars.pinSpacer,
36833			containerAnimation = _vars.containerAnimation,
36834			fastScrollEnd = _vars.fastScrollEnd,
36835			preventOverlaps = _vars.preventOverlaps,
36836			direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical,
36837			isToggle = !scrub && scrub !== 0,
36838			scroller = _getTarget(vars.scroller || _win$1),
36839			scrollerCache = gsap$1.core.getCache(scroller),
36840			isViewport = _isViewport$1(scroller),
36841			useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed",
36842			callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack],
36843			toggleActions = isToggle && vars.toggleActions.split(" "),
36844			markers = "markers" in vars ? vars.markers : _defaults.markers,
36845			borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0,
36846			self = this,
36847			onRefreshInit = vars.onRefreshInit && function () {
36848		  return vars.onRefreshInit(self);
36849		},
36850			getScrollerSize = _getSizeFunc(scroller, isViewport, direction),
36851			getScrollerOffsets = _getOffsetsFunc(scroller, isViewport),
36852			lastSnap = 0,
36853			lastRefresh = 0,
36854			prevProgress = 0,
36855			scrollFunc = _getScrollFunc(scroller, direction),
36856			tweenTo,
36857			pinCache,
36858			snapFunc,
36859			scroll1,
36860			scroll2,
36861			start,
36862			end,
36863			markerStart,
36864			markerEnd,
36865			markerStartTrigger,
36866			markerEndTrigger,
36867			markerVars,
36868			executingOnRefresh,
36869			change,
36870			pinOriginalState,
36871			pinActiveState,
36872			pinState,
36873			spacer,
36874			offset,
36875			pinGetter,
36876			pinSetter,
36877			pinStart,
36878			pinChange,
36879			spacingStart,
36880			spacerState,
36881			markerStartSetter,
36882			pinMoves,
36883			markerEndSetter,
36884			cs,
36885			snap1,
36886			snap2,
36887			scrubTween,
36888			scrubSmooth,
36889			snapDurClamp,
36890			snapDelayedCall,
36891			prevScroll,
36892			prevAnimProgress,
36893			caMarkerSetter,
36894			customRevertReturn;
36895  
36896		self._startClamp = self._endClamp = false;
36897		self._dir = direction;
36898		anticipatePin *= 45;
36899		self.scroller = scroller;
36900		self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc;
36901		scroll1 = scrollFunc();
36902		self.vars = vars;
36903		animation = animation || vars.animation;
36904  
36905		if ("refreshPriority" in vars) {
36906		  _sort = 1;
36907		  vars.refreshPriority === -9999 && (_primary = self);
36908		}
36909  
36910		scrollerCache.tweenScroll = scrollerCache.tweenScroll || {
36911		  top: _getTweenCreator(scroller, _vertical),
36912		  left: _getTweenCreator(scroller, _horizontal)
36913		};
36914		self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p];
36915  
36916		self.scrubDuration = function (value) {
36917		  scrubSmooth = _isNumber(value) && value;
36918  
36919		  if (!scrubSmooth) {
36920			scrubTween && scrubTween.progress(1).kill();
36921			scrubTween = 0;
36922		  } else {
36923			scrubTween ? scrubTween.duration(value) : scrubTween = gsap$1.to(animation, {
36924			  ease: "expo",
36925			  totalProgress: "+=0",
36926			  inherit: false,
36927			  duration: scrubSmooth,
36928			  paused: true,
36929			  onComplete: function onComplete() {
36930				return onScrubComplete && onScrubComplete(self);
36931			  }
36932			});
36933		  }
36934		};
36935  
36936		if (animation) {
36937		  animation.vars.lazy = false;
36938		  animation._initted && !self.isReverted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.duration() && animation.render(0, true, true);
36939		  self.animation = animation.pause();
36940		  animation.scrollTrigger = self;
36941		  self.scrubDuration(scrub);
36942		  snap1 = 0;
36943		  id || (id = animation.vars.id);
36944		}
36945  
36946		if (snap) {
36947		  if (!_isObject(snap) || snap.push) {
36948			snap = {
36949			  snapTo: snap
36950			};
36951		  }
36952  
36953		  "scrollBehavior" in _body$1.style && gsap$1.set(isViewport ? [_body$1, _docEl$1] : scroller, {
36954			scrollBehavior: "auto"
36955		  });
36956  
vendor: 4,259 bytes, lines 36957-37052
36957		  _scrollers.forEach(function (o) {
36958			return _isFunction(o) && o.target === (isViewport ? _doc$1.scrollingElement || _docEl$1 : scroller) && (o.smooth = false);
36959		  });
36960  
36961		  snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) {
36962			return _snapDirectional(snap.snapTo)(value, _getTime$1() - lastRefresh < 500 ? 0 : st.direction);
36963		  } : gsap$1.utils.snap(snap.snapTo);
36964		  snapDurClamp = snap.duration || {
36965			min: 0.1,
36966			max: 2
36967		  };
36968		  snapDurClamp = _isObject(snapDurClamp) ? _clamp$1(snapDurClamp.min, snapDurClamp.max) : _clamp$1(snapDurClamp, snapDurClamp);
36969		  snapDelayedCall = gsap$1.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () {
36970			var scroll = scrollFunc(),
36971				refreshedRecently = _getTime$1() - lastRefresh < 500,
36972				tween = tweenTo.tween;
36973  
36974			if ((refreshedRecently || Math.abs(self.getVelocity()) < 10) && !tween && !_pointerIsDown && lastSnap !== scroll) {
36975			  var progress = (scroll - start) / change,
36976				  totalProgress = animation && !isToggle ? animation.totalProgress() : progress,
36977				  velocity = refreshedRecently ? 0 : (totalProgress - snap2) / (_getTime$1() - _time2) * 1000 || 0,
36978				  change1 = gsap$1.utils.clamp(-progress, 1 - progress, _abs(velocity / 2) * velocity / 0.185),
36979				  naturalEnd = progress + (snap.inertia === false ? 0 : change1),
36980				  endValue,
36981				  endScroll,
36982				  _snap = snap,
36983				  onStart = _snap.onStart,
36984				  _onInterrupt = _snap.onInterrupt,
36985				  _onComplete = _snap.onComplete;
36986			  endValue = snapFunc(naturalEnd, self);
36987			  _isNumber(endValue) || (endValue = naturalEnd);
36988			  endScroll = Math.round(start + endValue * change);
36989  
36990			  if (scroll <= end && scroll >= start && endScroll !== scroll) {
36991				if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) {
36992				  return;
36993				}
36994  
36995				if (snap.inertia === false) {
36996				  change1 = endValue - progress;
36997				}
36998  
36999				tweenTo(endScroll, {
37000				  duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)),
37001				  ease: snap.ease || "power3",
37002				  data: _abs(endScroll - scroll),
37003				  onInterrupt: function onInterrupt() {
37004					return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self);
37005				  },
37006				  onComplete: function onComplete() {
37007					self.update();
37008					lastSnap = scrollFunc();
37009  
37010					if (animation) {
37011					  scrubTween ? scrubTween.resetTo("totalProgress", endValue, animation._tTime / animation._tDur) : animation.progress(endValue);
37012					}
37013  
37014					snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress;
37015					onSnapComplete && onSnapComplete(self);
37016					_onComplete && _onComplete(self);
37017				  }
37018				}, scroll, change1 * change, endScroll - scroll - change1 * change);
37019				onStart && onStart(self, tweenTo.tween);
37020			  }
37021			} else if (self.isActive && lastSnap !== scroll) {
37022			  snapDelayedCall.restart(true);
37023			}
37024		  }).pause();
37025		}
37026  
37027		id && (_ids[id] = self);
37028		trigger = self.trigger = _getTarget(trigger || pin !== true && pin);
37029		customRevertReturn = trigger && trigger._gsap && trigger._gsap.stRevert;
37030		customRevertReturn && (customRevertReturn = customRevertReturn(self));
37031		pin = pin === true ? trigger : _getTarget(pin);
37032		_isString(toggleClass) && (toggleClass = {
37033		  targets: trigger,
37034		  className: toggleClass
37035		});
37036  
37037		if (pin) {
37038		  pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && pin.parentNode && pin.parentNode.style && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding);
37039		  self.pin = pin;
37040		  pinCache = gsap$1.core.getCache(pin);
37041  
37042		  if (!pinCache.spacer) {
37043			if (pinSpacer) {
37044			  pinSpacer = _getTarget(pinSpacer);
37045			  pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement);
37046			  pinCache.spacerIsNative = !!pinSpacer;
37047			  pinSpacer && (pinCache.spacerState = _getState(pinSpacer));
37048			}
37049  
37050			pinCache.spacer = spacer = pinSpacer || _doc$1.createElement("div");
37051			spacer.classList.add("pin-spacer");
37052			id && spacer.classList.add("pin-spacer-" + id);
vendor: 4,987 bytes, lines 37053-37207
37053			pinCache.pinState = pinOriginalState = _getState(pin);
37054		  } else {
37055			pinOriginalState = pinCache.pinState;
37056		  }
37057  
37058		  vars.force3D !== false && gsap$1.set(pin, {
37059			force3D: true
37060		  });
37061		  self.spacer = spacer = pinCache.spacer;
37062		  cs = _getComputedStyle(pin);
37063		  spacingStart = cs[pinSpacing + direction.os2];
37064		  pinGetter = gsap$1.getProperty(pin);
37065		  pinSetter = gsap$1.quickSetter(pin, direction.a, _px);
37066  
37067		  _swapPinIn(pin, spacer, cs);
37068  
37069		  pinState = _getState(pin);
37070		}
37071  
37072		if (markers) {
37073		  markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults;
37074		  markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0);
37075		  markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger);
37076		  offset = markerStartTrigger["offset" + direction.op.d2];
37077  
37078		  var content = _getTarget(_getProxyProp(scroller, "content") || scroller);
37079  
37080		  markerStart = this.markerStart = _createMarker("start", id, content, direction, markerVars, offset, 0, containerAnimation);
37081		  markerEnd = this.markerEnd = _createMarker("end", id, content, direction, markerVars, offset, 0, containerAnimation);
37082		  containerAnimation && (caMarkerSetter = gsap$1.quickSetter([markerStart, markerEnd], direction.a, _px));
37083  
37084		  if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) {
37085			_makePositionable(isViewport ? _body$1 : scroller);
37086  
37087			gsap$1.set([markerStartTrigger, markerEndTrigger], {
37088			  force3D: true
37089			});
37090			markerStartSetter = gsap$1.quickSetter(markerStartTrigger, direction.a, _px);
37091			markerEndSetter = gsap$1.quickSetter(markerEndTrigger, direction.a, _px);
37092		  }
37093		}
37094  
37095		if (containerAnimation) {
37096		  var oldOnUpdate = containerAnimation.vars.onUpdate,
37097			  oldParams = containerAnimation.vars.onUpdateParams;
37098		  containerAnimation.eventCallback("onUpdate", function () {
37099			self.update(0, 0, 1);
37100			oldOnUpdate && oldOnUpdate.apply(containerAnimation, oldParams || []);
37101		  });
37102		}
37103  
37104		self.previous = function () {
37105		  return _triggers[_triggers.indexOf(self) - 1];
37106		};
37107  
37108		self.next = function () {
37109		  return _triggers[_triggers.indexOf(self) + 1];
37110		};
37111  
37112		self.revert = function (revert, temp) {
37113		  if (!temp) {
37114			return self.kill(true);
37115		  }
37116  
37117		  var r = revert !== false || !self.enabled,
37118			  prevRefreshing = _refreshing;
37119  
37120		  if (r !== self.isReverted) {
37121			if (r) {
37122			  prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0);
37123			  prevProgress = self.progress;
37124			  prevAnimProgress = animation && animation.progress();
37125			}
37126  
37127			markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {
37128			  return m.style.display = r ? "none" : "block";
37129			});
37130  
37131			if (r) {
37132			  _refreshing = self;
37133			  self.update(r);
37134			}
37135  
37136			if (pin && (!pinReparent || !self.isActive)) {
37137			  if (r) {
37138				_swapPinOut(pin, spacer, pinOriginalState);
37139			  } else {
37140				_swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState);
37141			  }
37142			}
37143  
37144			r || self.update(r);
37145			_refreshing = prevRefreshing;
37146			self.isReverted = r;
37147		  }
37148		};
37149  
37150		self.refresh = function (soft, force, position, pinOffset) {
37151		  if ((_refreshing || !self.enabled) && !force) {
37152			return;
37153		  }
37154  
37155		  if (pin && soft && _lastScrollTime) {
37156			_addListener$1(ScrollTrigger, "scrollEnd", _softRefresh);
37157  
37158			return;
37159		  }
37160  
37161		  !_refreshingAll && onRefreshInit && onRefreshInit(self);
37162		  _refreshing = self;
37163  
37164		  if (tweenTo.tween && !position) {
37165			tweenTo.tween.kill();
37166			tweenTo.tween = 0;
37167		  }
37168  
37169		  scrubTween && scrubTween.pause();
37170		  invalidateOnRefresh && animation && animation.revert({
37171			kill: false
37172		  }).invalidate();
37173		  self.isReverted || self.revert(true, true);
37174		  self._subPinOffset = false;
37175  
37176		  var size = getScrollerSize(),
37177			  scrollerBounds = getScrollerOffsets(),
37178			  max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction),
37179			  isFirstRefresh = change <= 0.01,
37180			  offset = 0,
37181			  otherPinOffset = pinOffset || 0,
37182			  parsedEnd = _isObject(position) ? position.end : vars.end,
37183			  parsedEndTrigger = vars.endTrigger || trigger,
37184			  parsedStart = _isObject(position) ? position.start : vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"),
37185			  pinnedContainer = self.pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer, self),
37186			  triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0,
37187			  i = triggerIndex,
37188			  cs,
37189			  bounds,
37190			  scroll,
37191			  isVertical,
37192			  override,
37193			  curTrigger,
37194			  curPin,
37195			  oppositeScroll,
37196			  initted,
37197			  revertedPins,
37198			  forcedOverflow,
37199			  markerStartOffset,
37200			  markerEndOffset;
37201  
37202		  if (markers && _isObject(position)) {
37203			markerStartOffset = gsap$1.getProperty(markerStartTrigger, direction.p);
37204			markerEndOffset = gsap$1.getProperty(markerEndTrigger, direction.p);
37205		  }
37206  
37207		  while (i--) {
vendor: 4,360 bytes, lines 37208-37319
37208			curTrigger = _triggers[i];
37209			curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = self);
37210			curPin = curTrigger.pin;
37211  
37212			if (curPin && (curPin === trigger || curPin === pin || curPin === pinnedContainer) && !curTrigger.isReverted) {
37213			  revertedPins || (revertedPins = []);
37214			  revertedPins.unshift(curTrigger);
37215			  curTrigger.revert(true, true);
37216			}
37217  
37218			if (curTrigger !== _triggers[i]) {
37219			  triggerIndex--;
37220			  i--;
37221			}
37222		  }
37223  
37224		  _isFunction(parsedStart) && (parsedStart = parsedStart(self));
37225		  parsedStart = _parseClamp(parsedStart, "start", self);
37226		  start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._startClamp && "_startClamp") || (pin ? -0.001 : 0);
37227		  _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self));
37228  
37229		  if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) {
37230			if (~parsedEnd.indexOf(" ")) {
37231			  parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd;
37232			} else {
37233			  offset = _offsetToPx(parsedEnd.substr(2), size);
37234			  parsedEnd = _isString(parsedStart) ? parsedStart : (containerAnimation ? gsap$1.utils.mapRange(0, containerAnimation.duration(), containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, start) : start) + offset;
37235			  parsedEndTrigger = trigger;
37236			}
37237		  }
37238  
37239		  parsedEnd = _parseClamp(parsedEnd, "end", self);
37240		  end = Math.max(start, _parsePosition(parsedEnd || (parsedEndTrigger ? "100% 0" : max), parsedEndTrigger, size, direction, scrollFunc() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._endClamp && "_endClamp")) || -0.001;
37241		  offset = 0;
37242		  i = triggerIndex;
37243  
37244		  while (i--) {
37245			curTrigger = _triggers[i];
37246			curPin = curTrigger.pin;
37247  
37248			if (curPin && curTrigger.start - curTrigger._pinPush <= start && !containerAnimation && curTrigger.end > 0) {
37249			  cs = curTrigger.end - (self._startClamp ? Math.max(0, curTrigger.start) : curTrigger.start);
37250  
37251			  if ((curPin === trigger && curTrigger.start - curTrigger._pinPush < start || curPin === pinnedContainer) && isNaN(parsedStart)) {
37252				offset += cs * (1 - curTrigger.progress);
37253			  }
37254  
37255			  curPin === pin && (otherPinOffset += cs);
37256			}
37257		  }
37258  
37259		  start += offset;
37260		  end += offset;
37261		  self._startClamp && (self._startClamp += offset);
37262  
37263		  if (self._endClamp && !_refreshingAll) {
37264			self._endClamp = end || -0.001;
37265			end = Math.min(end, _maxScroll(scroller, direction));
37266		  }
37267  
37268		  change = end - start || (start -= 0.01) && 0.001;
37269  
37270		  if (isFirstRefresh) {
37271			prevProgress = gsap$1.utils.clamp(0, 1, gsap$1.utils.normalize(start, end, prevScroll));
37272		  }
37273  
37274		  self._pinPush = otherPinOffset;
37275  
37276		  if (markerStart && offset) {
37277			cs = {};
37278			cs[direction.a] = "+=" + offset;
37279			pinnedContainer && (cs[direction.p] = "-=" + scrollFunc());
37280			gsap$1.set([markerStart, markerEnd], cs);
37281		  }
37282  
37283		  if (pin && !(_clampingMax && self.end >= _maxScroll(scroller, direction))) {
37284			cs = _getComputedStyle(pin);
37285			isVertical = direction === _vertical;
37286			scroll = scrollFunc();
37287			pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset;
37288  
37289			if (!max && end > 1) {
37290			  forcedOverflow = (isViewport ? _doc$1.scrollingElement || _docEl$1 : scroller).style;
37291			  forcedOverflow = {
37292				style: forcedOverflow,
37293				value: forcedOverflow["overflow" + direction.a.toUpperCase()]
37294			  };
37295  
37296			  if (isViewport && _getComputedStyle(_body$1)["overflow" + direction.a.toUpperCase()] !== "scroll") {
37297				forcedOverflow.style["overflow" + direction.a.toUpperCase()] = "scroll";
37298			  }
37299			}
37300  
37301			_swapPinIn(pin, spacer, cs);
37302  
37303			pinState = _getState(pin);
37304			bounds = _getBounds(pin, true);
37305			oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)();
37306  
37307			if (pinSpacing) {
37308			  spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px];
37309			  spacerState.t = spacer;
37310			  i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0;
37311  
37312			  if (i) {
37313				spacerState.push(direction.d, i + _px);
37314				spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px);
37315			  }
37316  
37317			  _setState(spacerState);
37318  
37319			  if (pinnedContainer) {
vendor: 28,838 bytes, lines 37320-38210
37320				_triggers.forEach(function (t) {
37321				  if (t.pin === pinnedContainer && t.vars.pinSpacing !== false) {
37322					t._subPinOffset = true;
37323				  }
37324				});
37325			  }
37326  
37327			  useFixedPosition && scrollFunc(prevScroll);
37328			} else {
37329			  i = _getSize(pin, direction);
37330			  i && spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px);
37331			}
37332  
37333			if (useFixedPosition) {
37334			  override = {
37335				top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px,
37336				left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px,
37337				boxSizing: "border-box",
37338				position: "fixed"
37339			  };
37340			  override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px;
37341			  override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px;
37342			  override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0";
37343			  override[_padding] = cs[_padding];
37344			  override[_padding + _Top] = cs[_padding + _Top];
37345			  override[_padding + _Right] = cs[_padding + _Right];
37346			  override[_padding + _Bottom] = cs[_padding + _Bottom];
37347			  override[_padding + _Left] = cs[_padding + _Left];
37348			  pinActiveState = _copyState(pinOriginalState, override, pinReparent);
37349			  _refreshingAll && scrollFunc(0);
37350			}
37351  
37352			if (animation) {
37353			  initted = animation._initted;
37354  
37355			  _suppressOverwrites(1);
37356  
37357			  animation.render(animation.duration(), true, true);
37358			  pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset;
37359			  pinMoves = Math.abs(change - pinChange) > 1;
37360			  useFixedPosition && pinMoves && pinActiveState.splice(pinActiveState.length - 2, 2);
37361			  animation.render(0, true, true);
37362			  initted || animation.invalidate(true);
37363			  animation.parent || animation.totalTime(animation.totalTime());
37364  
37365			  _suppressOverwrites(0);
37366			} else {
37367			  pinChange = change;
37368			}
37369  
37370			forcedOverflow && (forcedOverflow.value ? forcedOverflow.style["overflow" + direction.a.toUpperCase()] = forcedOverflow.value : forcedOverflow.style.removeProperty("overflow-" + direction.a));
37371		  } else if (trigger && scrollFunc() && !containerAnimation) {
37372			bounds = trigger.parentNode;
37373  
37374			while (bounds && bounds !== _body$1) {
37375			  if (bounds._pinOffset) {
37376				start -= bounds._pinOffset;
37377				end -= bounds._pinOffset;
37378			  }
37379  
37380			  bounds = bounds.parentNode;
37381			}
37382		  }
37383  
37384		  revertedPins && revertedPins.forEach(function (t) {
37385			return t.revert(false, true);
37386		  });
37387		  self.start = start;
37388		  self.end = end;
37389		  scroll1 = scroll2 = _refreshingAll ? prevScroll : scrollFunc();
37390  
37391		  if (!containerAnimation && !_refreshingAll) {
37392			scroll1 < prevScroll && scrollFunc(prevScroll);
37393			self.scroll.rec = 0;
37394		  }
37395  
37396		  self.revert(false, true);
37397		  lastRefresh = _getTime$1();
37398  
37399		  if (snapDelayedCall) {
37400			lastSnap = -1;
37401			snapDelayedCall.restart(true);
37402		  }
37403  
37404		  _refreshing = 0;
37405		  animation && isToggle && (animation._initted || prevAnimProgress) && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress || 0, true).render(animation.time(), true, true);
37406  
37407		  if (isFirstRefresh || prevProgress !== self.progress || containerAnimation || invalidateOnRefresh) {
37408			animation && !isToggle && animation.totalProgress(containerAnimation && start < -0.001 && !prevProgress ? gsap$1.utils.normalize(start, end, 0) : prevProgress, true);
37409			self.progress = isFirstRefresh || (scroll1 - start) / change === prevProgress ? 0 : prevProgress;
37410		  }
37411  
37412		  pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange));
37413		  scrubTween && scrubTween.invalidate();
37414  
37415		  if (!isNaN(markerStartOffset)) {
37416			markerStartOffset -= gsap$1.getProperty(markerStartTrigger, direction.p);
37417			markerEndOffset -= gsap$1.getProperty(markerEndTrigger, direction.p);
37418  
37419			_shiftMarker(markerStartTrigger, direction, markerStartOffset);
37420  
37421			_shiftMarker(markerStart, direction, markerStartOffset - (pinOffset || 0));
37422  
37423			_shiftMarker(markerEndTrigger, direction, markerEndOffset);
37424  
37425			_shiftMarker(markerEnd, direction, markerEndOffset - (pinOffset || 0));
37426		  }
37427  
37428		  isFirstRefresh && !_refreshingAll && self.update();
37429  
37430		  if (onRefresh && !_refreshingAll && !executingOnRefresh) {
37431			executingOnRefresh = true;
37432			onRefresh(self);
37433			executingOnRefresh = false;
37434		  }
37435		};
37436  
37437		self.getVelocity = function () {
37438		  return (scrollFunc() - scroll2) / (_getTime$1() - _time2) * 1000 || 0;
37439		};
37440  
37441		self.endAnimation = function () {
37442		  _endAnimation(self.callbackAnimation);
37443  
37444		  if (animation) {
37445			scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1);
37446		  }
37447		};
37448  
37449		self.labelToScroll = function (label) {
37450		  return animation && animation.labels && (start || self.refresh() || start) + animation.labels[label] / animation.duration() * change || 0;
37451		};
37452  
37453		self.getTrailing = function (name) {
37454		  var i = _triggers.indexOf(self),
37455			  a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1);
37456  
37457		  return (_isString(name) ? a.filter(function (t) {
37458			return t.vars.preventOverlaps === name;
37459		  }) : a).filter(function (t) {
37460			return self.direction > 0 ? t.end <= start : t.start >= end;
37461		  });
37462		};
37463  
37464		self.update = function (reset, recordVelocity, forceFake) {
37465		  if (containerAnimation && !forceFake && !reset) {
37466			return;
37467		  }
37468  
37469		  var scroll = _refreshingAll === true ? prevScroll : self.scroll(),
37470			  p = reset ? 0 : (scroll - start) / change,
37471			  clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0,
37472			  prevProgress = self.progress,
37473			  isActive,
37474			  wasActive,
37475			  toggleState,
37476			  action,
37477			  stateChanged,
37478			  toggled,
37479			  isAtMax,
37480			  isTakingAction;
37481  
37482		  if (recordVelocity) {
37483			scroll2 = scroll1;
37484			scroll1 = containerAnimation ? scrollFunc() : scroll;
37485  
37486			if (snap) {
37487			  snap2 = snap1;
37488			  snap1 = animation && !isToggle ? animation.totalProgress() : clipped;
37489			}
37490		  }
37491  
37492		  if (anticipatePin && pin && !_refreshing && !_startup$1 && _lastScrollTime) {
37493			if (!clipped && start < scroll + (scroll - scroll2) / (_getTime$1() - _time2) * anticipatePin) {
37494			  clipped = 0.0001;
37495			} else if (clipped === 1 && end > scroll + (scroll - scroll2) / (_getTime$1() - _time2) * anticipatePin) {
37496			  clipped = 0.9999;
37497			}
37498		  }
37499  
37500		  if (clipped !== prevProgress && self.enabled) {
37501			isActive = self.isActive = !!clipped && clipped < 1;
37502			wasActive = !!prevProgress && prevProgress < 1;
37503			toggled = isActive !== wasActive;
37504			stateChanged = toggled || !!clipped !== !!prevProgress;
37505			self.direction = clipped > prevProgress ? 1 : -1;
37506			self.progress = clipped;
37507  
37508			if (stateChanged && !_refreshing) {
37509			  toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3;
37510  
37511			  if (isToggle) {
37512				action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState];
37513				isTakingAction = animation && (action === "complete" || action === "reset" || action in animation);
37514			  }
37515			}
37516  
37517			preventOverlaps && (toggled || isTakingAction) && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) {
37518			  return t.endAnimation();
37519			}));
37520  
37521			if (!isToggle) {
37522			  if (scrubTween && !_refreshing && !_startup$1) {
37523				scrubTween._dp._time - scrubTween._start !== scrubTween._time && scrubTween.render(scrubTween._dp._time - scrubTween._start);
37524  
37525				if (scrubTween.resetTo) {
37526				  scrubTween.resetTo("totalProgress", clipped, animation._tTime / animation._tDur);
37527				} else {
37528				  scrubTween.vars.totalProgress = clipped;
37529				  scrubTween.invalidate().restart();
37530				}
37531			  } else if (animation) {
37532				animation.totalProgress(clipped, !!(_refreshing && (lastRefresh || reset)));
37533			  }
37534			}
37535  
37536			if (pin) {
37537			  reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart);
37538  
37539			  if (!useFixedPosition) {
37540				pinSetter(_round(pinStart + pinChange * clipped));
37541			  } else if (stateChanged) {
37542				isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction);
37543  
37544				if (pinReparent) {
37545				  if (!reset && (isActive || isAtMax)) {
37546					var bounds = _getBounds(pin, true),
37547						_offset = scroll - start;
37548  
37549					_reparent(pin, _body$1, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px);
37550				  } else {
37551					_reparent(pin, spacer);
37552				  }
37553				}
37554  
37555				_setState(isActive || isAtMax ? pinActiveState : pinState);
37556  
37557				pinMoves && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0));
37558			  }
37559			}
37560  
37561			snap && !tweenTo.tween && !_refreshing && !_startup$1 && snapDelayedCall.restart(true);
37562			toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) {
37563			  return el.classList[isActive || once ? "add" : "remove"](toggleClass.className);
37564			});
37565			onUpdate && !isToggle && !reset && onUpdate(self);
37566  
37567			if (stateChanged && !_refreshing) {
37568			  if (isToggle) {
37569				if (isTakingAction) {
37570				  if (action === "complete") {
37571					animation.pause().totalProgress(1);
37572				  } else if (action === "reset") {
37573					animation.restart(true).pause();
37574				  } else if (action === "restart") {
37575					animation.restart(true);
37576				  } else {
37577					animation[action]();
37578				  }
37579				}
37580  
37581				onUpdate && onUpdate(self);
37582			  }
37583  
37584			  if (toggled || !_limitCallbacks) {
37585				onToggle && toggled && _callback(self, onToggle);
37586				callbacks[toggleState] && _callback(self, callbacks[toggleState]);
37587				once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0);
37588  
37589				if (!toggled) {
37590				  toggleState = clipped === 1 ? 1 : 3;
37591				  callbacks[toggleState] && _callback(self, callbacks[toggleState]);
37592				}
37593			  }
37594  
37595			  if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) {
37596				_endAnimation(self.callbackAnimation);
37597  
37598				scrubTween ? scrubTween.progress(1) : _endAnimation(animation, action === "reverse" ? 1 : !clipped, 1);
37599			  }
37600			} else if (isToggle && onUpdate && !_refreshing) {
37601			  onUpdate(self);
37602			}
37603		  }
37604  
37605		  if (markerEndSetter) {
37606			var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll;
37607			markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0));
37608			markerEndSetter(n);
37609		  }
37610  
37611		  caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0));
37612		};
37613  
37614		self.enable = function (reset, refresh) {
37615		  if (!self.enabled) {
37616			self.enabled = true;
37617  
37618			_addListener$1(scroller, "resize", _onResize);
37619  
37620			isViewport || _addListener$1(scroller, "scroll", _onScroll$1);
37621			onRefreshInit && _addListener$1(ScrollTrigger, "refreshInit", onRefreshInit);
37622  
37623			if (reset !== false) {
37624			  self.progress = prevProgress = 0;
37625			  scroll1 = scroll2 = lastSnap = scrollFunc();
37626			}
37627  
37628			refresh !== false && self.refresh();
37629		  }
37630		};
37631  
37632		self.getTween = function (snap) {
37633		  return snap && tweenTo ? tweenTo.tween : scrubTween;
37634		};
37635  
37636		self.setPositions = function (newStart, newEnd, keepClamp, pinOffset) {
37637		  if (containerAnimation) {
37638			var st = containerAnimation.scrollTrigger,
37639				duration = containerAnimation.duration(),
37640				_change = st.end - st.start;
37641  
37642			newStart = st.start + _change * newStart / duration;
37643			newEnd = st.start + _change * newEnd / duration;
37644		  }
37645  
37646		  self.refresh(false, false, {
37647			start: _keepClamp(newStart, keepClamp && !!self._startClamp),
37648			end: _keepClamp(newEnd, keepClamp && !!self._endClamp)
37649		  }, pinOffset);
37650		  self.update();
37651		};
37652  
37653		self.adjustPinSpacing = function (amount) {
37654		  if (spacerState && amount) {
37655			var i = spacerState.indexOf(direction.d) + 1;
37656			spacerState[i] = parseFloat(spacerState[i]) + amount + _px;
37657			spacerState[1] = parseFloat(spacerState[1]) + amount + _px;
37658  
37659			_setState(spacerState);
37660		  }
37661		};
37662  
37663		self.disable = function (reset, allowAnimation) {
37664		  if (self.enabled) {
37665			reset !== false && self.revert(true, true);
37666			self.enabled = self.isActive = false;
37667			allowAnimation || scrubTween && scrubTween.pause();
37668			prevScroll = 0;
37669			pinCache && (pinCache.uncache = 1);
37670			onRefreshInit && _removeListener$1(ScrollTrigger, "refreshInit", onRefreshInit);
37671  
37672			if (snapDelayedCall) {
37673			  snapDelayedCall.pause();
37674			  tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0);
37675			}
37676  
37677			if (!isViewport) {
37678			  var i = _triggers.length;
37679  
37680			  while (i--) {
37681				if (_triggers[i].scroller === scroller && _triggers[i] !== self) {
37682				  return;
37683				}
37684			  }
37685  
37686			  _removeListener$1(scroller, "resize", _onResize);
37687  
37688			  isViewport || _removeListener$1(scroller, "scroll", _onScroll$1);
37689			}
37690		  }
37691		};
37692  
37693		self.kill = function (revert, allowAnimation) {
37694		  self.disable(revert, allowAnimation);
37695		  scrubTween && !allowAnimation && scrubTween.kill();
37696		  id && delete _ids[id];
37697  
37698		  var i = _triggers.indexOf(self);
37699  
37700		  i >= 0 && _triggers.splice(i, 1);
37701		  i === _i && _direction > 0 && _i--;
37702		  i = 0;
37703  
37704		  _triggers.forEach(function (t) {
37705			return t.scroller === self.scroller && (i = 1);
37706		  });
37707  
37708		  i || _refreshingAll || (self.scroll.rec = 0);
37709  
37710		  if (animation) {
37711			animation.scrollTrigger = null;
37712			revert && animation.revert({
37713			  kill: false
37714			});
37715			allowAnimation || animation.kill();
37716		  }
37717  
37718		  markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {
37719			return m.parentNode && m.parentNode.removeChild(m);
37720		  });
37721		  _primary === self && (_primary = 0);
37722  
37723		  if (pin) {
37724			pinCache && (pinCache.uncache = 1);
37725			i = 0;
37726  
37727			_triggers.forEach(function (t) {
37728			  return t.pin === pin && i++;
37729			});
37730  
37731			i || (pinCache.spacer = 0);
37732		  }
37733  
37734		  vars.onKill && vars.onKill(self);
37735		};
37736  
37737		_triggers.push(self);
37738  
37739		self.enable(false, false);
37740		customRevertReturn && customRevertReturn(self);
37741  
37742		if (animation && animation.add && !change) {
37743		  var updateFunc = self.update;
37744  
37745		  self.update = function () {
37746			self.update = updateFunc;
37747			start || end || self.refresh();
37748		  };
37749  
37750		  gsap$1.delayedCall(0.01, self.update);
37751		  change = 0.01;
37752		  start = end = 0;
37753		} else {
37754		  self.refresh();
37755		}
37756  
37757		pin && _queueRefreshAll();
37758	  };
37759  
37760	  ScrollTrigger.register = function register(core) {
37761		if (!_coreInitted$1) {
37762		  gsap$1 = core || _getGSAP$1();
37763		  _windowExists() && window.document && ScrollTrigger.enable();
37764		  _coreInitted$1 = _enabled;
37765		}
37766  
37767		return _coreInitted$1;
37768	  };
37769  
37770	  ScrollTrigger.defaults = function defaults(config) {
37771		if (config) {
37772		  for (var p in config) {
37773			_defaults[p] = config[p];
37774		  }
37775		}
37776  
37777		return _defaults;
37778	  };
37779  
37780	  ScrollTrigger.disable = function disable(reset, kill) {
37781		_enabled = 0;
37782  
37783		_triggers.forEach(function (trigger) {
37784		  return trigger[kill ? "kill" : "disable"](reset);
37785		});
37786  
37787		_removeListener$1(_win$1, "wheel", _onScroll$1);
37788  
37789		_removeListener$1(_doc$1, "scroll", _onScroll$1);
37790  
37791		clearInterval(_syncInterval);
37792  
37793		_removeListener$1(_doc$1, "touchcancel", _passThrough);
37794  
37795		_removeListener$1(_body$1, "touchstart", _passThrough);
37796  
37797		_multiListener(_removeListener$1, _doc$1, "pointerdown,touchstart,mousedown", _pointerDownHandler);
37798  
37799		_multiListener(_removeListener$1, _doc$1, "pointerup,touchend,mouseup", _pointerUpHandler);
37800  
37801		_resizeDelay.kill();
37802  
37803		_iterateAutoRefresh(_removeListener$1);
37804  
37805		for (var i = 0; i < _scrollers.length; i += 3) {
37806		  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 1]);
37807  
37808		  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 2]);
37809		}
37810	  };
37811  
37812	  ScrollTrigger.enable = function enable() {
37813		_win$1 = window;
37814		_doc$1 = document;
37815		_docEl$1 = _doc$1.documentElement;
37816		_body$1 = _doc$1.body;
37817  
37818		if (gsap$1) {
37819		  _toArray = gsap$1.utils.toArray;
37820		  _clamp$1 = gsap$1.utils.clamp;
37821		  _context$1 = gsap$1.core.context || _passThrough;
37822		  _suppressOverwrites = gsap$1.core.suppressOverwrites || _passThrough;
37823		  _scrollRestoration = _win$1.history.scrollRestoration || "auto";
37824		  _lastScroll = _win$1.pageYOffset;
37825		  gsap$1.core.globals("ScrollTrigger", ScrollTrigger);
37826  
37827		  if (_body$1) {
37828			_enabled = 1;
37829			_div100vh = document.createElement("div");
37830			_div100vh.style.height = "100vh";
37831			_div100vh.style.position = "absolute";
37832  
37833			_refresh100vh();
37834  
37835			_rafBugFix();
37836  
37837			Observer.register(gsap$1);
37838			ScrollTrigger.isTouch = Observer.isTouch;
37839			_fixIOSBug = Observer.isTouch && /(iPad|iPhone|iPod|Mac)/g.test(navigator.userAgent);
37840			_ignoreMobileResize = Observer.isTouch === 1;
37841  
37842			_addListener$1(_win$1, "wheel", _onScroll$1);
37843  
37844			_root$1 = [_win$1, _doc$1, _docEl$1, _body$1];
37845  
37846			if (gsap$1.matchMedia) {
37847			  ScrollTrigger.matchMedia = function (vars) {
37848				var mm = gsap$1.matchMedia(),
37849					p;
37850  
37851				for (p in vars) {
37852				  mm.add(p, vars[p]);
37853				}
37854  
37855				return mm;
37856			  };
37857  
37858			  gsap$1.addEventListener("matchMediaInit", function () {
37859				return _revertAll();
37860			  });
37861			  gsap$1.addEventListener("matchMediaRevert", function () {
37862				return _revertRecorded();
37863			  });
37864			  gsap$1.addEventListener("matchMedia", function () {
37865				_refreshAll(0, 1);
37866  
37867				_dispatch("matchMedia");
37868			  });
37869			  gsap$1.matchMedia("(orientation: portrait)", function () {
37870				_setBaseDimensions();
37871  
37872				return _setBaseDimensions;
37873			  });
37874			} else {
37875			  console.warn("Requires GSAP 3.11.0 or later");
37876			}
37877  
37878			_setBaseDimensions();
37879  
37880			_addListener$1(_doc$1, "scroll", _onScroll$1);
37881  
37882			var bodyStyle = _body$1.style,
37883				border = bodyStyle.borderTopStyle,
37884				AnimationProto = gsap$1.core.Animation.prototype,
37885				bounds,
37886				i;
37887			AnimationProto.revert || Object.defineProperty(AnimationProto, "revert", {
37888			  value: function value() {
37889				return this.time(-0.01, true);
37890			  }
37891			});
37892			bodyStyle.borderTopStyle = "solid";
37893			bounds = _getBounds(_body$1);
37894			_vertical.m = Math.round(bounds.top + _vertical.sc()) || 0;
37895			_horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0;
37896			border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style");
37897			_syncInterval = setInterval(_sync, 250);
37898			gsap$1.delayedCall(0.5, function () {
37899			  return _startup$1 = 0;
37900			});
37901  
37902			_addListener$1(_doc$1, "touchcancel", _passThrough);
37903  
37904			_addListener$1(_body$1, "touchstart", _passThrough);
37905  
37906			_multiListener(_addListener$1, _doc$1, "pointerdown,touchstart,mousedown", _pointerDownHandler);
37907  
37908			_multiListener(_addListener$1, _doc$1, "pointerup,touchend,mouseup", _pointerUpHandler);
37909  
37910			_transformProp = gsap$1.utils.checkPrefix("transform");
37911  
37912			_stateProps.push(_transformProp);
37913  
37914			_coreInitted$1 = _getTime$1();
37915			_resizeDelay = gsap$1.delayedCall(0.2, _refreshAll).pause();
37916			_autoRefresh = [_doc$1, "visibilitychange", function () {
37917			  var w = _win$1.innerWidth,
37918				  h = _win$1.innerHeight;
37919  
37920			  if (_doc$1.hidden) {
37921				_prevWidth = w;
37922				_prevHeight = h;
37923			  } else if (_prevWidth !== w || _prevHeight !== h) {
37924				_onResize();
37925			  }
37926			}, _doc$1, "DOMContentLoaded", _refreshAll, _win$1, "load", _refreshAll, _win$1, "resize", _onResize];
37927  
37928			_iterateAutoRefresh(_addListener$1);
37929  
37930			_triggers.forEach(function (trigger) {
37931			  return trigger.enable(0, 1);
37932			});
37933  
37934			for (i = 0; i < _scrollers.length; i += 3) {
37935			  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 1]);
37936  
37937			  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 2]);
37938			}
37939		  }
37940		}
37941	  };
37942  
37943	  ScrollTrigger.config = function config(vars) {
37944		"limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks);
37945		var ms = vars.syncInterval;
37946		ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms);
37947		"ignoreMobileResize" in vars && (_ignoreMobileResize = ScrollTrigger.isTouch === 1 && vars.ignoreMobileResize);
37948  
37949		if ("autoRefreshEvents" in vars) {
37950		  _iterateAutoRefresh(_removeListener$1) || _iterateAutoRefresh(_addListener$1, vars.autoRefreshEvents || "none");
37951		  _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1;
37952		}
37953	  };
37954  
37955	  ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) {
37956		var t = _getTarget(target),
37957			i = _scrollers.indexOf(t),
37958			isViewport = _isViewport$1(t);
37959  
37960		if (~i) {
37961		  _scrollers.splice(i, isViewport ? 6 : 2);
37962		}
37963  
37964		if (vars) {
37965		  isViewport ? _proxies.unshift(_win$1, vars, _body$1, vars, _docEl$1, vars) : _proxies.unshift(t, vars);
37966		}
37967	  };
37968  
37969	  ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) {
37970		_triggers.forEach(function (t) {
37971		  return t._ctx && t._ctx.query === query && t._ctx.kill(true, true);
37972		});
37973	  };
37974  
37975	  ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) {
37976		var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(),
37977			offset = bounds[horizontal ? _width : _height] * ratio || 0;
37978		return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win$1.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win$1.innerHeight;
37979	  };
37980  
37981	  ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) {
37982		_isString(element) && (element = _getTarget(element));
37983		var bounds = element.getBoundingClientRect(),
37984			size = bounds[horizontal ? _width : _height],
37985			offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0;
37986		return horizontal ? (bounds.left + offset) / _win$1.innerWidth : (bounds.top + offset) / _win$1.innerHeight;
37987	  };
37988  
37989	  ScrollTrigger.killAll = function killAll(allowListeners) {
37990		_triggers.slice(0).forEach(function (t) {
37991		  return t.vars.id !== "ScrollSmoother" && t.kill();
37992		});
37993  
37994		if (allowListeners !== true) {
37995		  var listeners = _listeners.killAll || [];
37996		  _listeners = {};
37997		  listeners.forEach(function (f) {
37998			return f();
37999		  });
38000		}
38001	  };
38002  
38003	  return ScrollTrigger;
38004	}();
38005	ScrollTrigger$1.version = "3.12.5";
38006  
38007	ScrollTrigger$1.saveStyles = function (targets) {
38008	  return targets ? _toArray(targets).forEach(function (target) {
38009		if (target && target.style) {
38010		  var i = _savedStyles.indexOf(target);
38011  
38012		  i >= 0 && _savedStyles.splice(i, 5);
38013  
38014		  _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap$1.core.getCache(target), _context$1());
38015		}
38016	  }) : _savedStyles;
38017	};
38018  
38019	ScrollTrigger$1.revert = function (soft, media) {
38020	  return _revertAll(!soft, media);
38021	};
38022  
38023	ScrollTrigger$1.create = function (vars, animation) {
38024	  return new ScrollTrigger$1(vars, animation);
38025	};
38026  
38027	ScrollTrigger$1.refresh = function (safe) {
38028	  return safe ? _onResize() : (_coreInitted$1 || ScrollTrigger$1.register()) && _refreshAll(true);
38029	};
38030  
38031	ScrollTrigger$1.update = function (force) {
38032	  return ++_scrollers.cache && _updateAll(force === true ? 2 : 0);
38033	};
38034  
38035	ScrollTrigger$1.clearScrollMemory = _clearScrollMemory;
38036  
38037	ScrollTrigger$1.maxScroll = function (element, horizontal) {
38038	  return _maxScroll(element, horizontal ? _horizontal : _vertical);
38039	};
38040  
38041	ScrollTrigger$1.getScrollFunc = function (element, horizontal) {
38042	  return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical);
38043	};
38044  
38045	ScrollTrigger$1.getById = function (id) {
38046	  return _ids[id];
38047	};
38048  
38049	ScrollTrigger$1.getAll = function () {
38050	  return _triggers.filter(function (t) {
38051		return t.vars.id !== "ScrollSmoother";
38052	  });
38053	};
38054  
38055	ScrollTrigger$1.isScrolling = function () {
38056	  return !!_lastScrollTime;
38057	};
38058  
38059	ScrollTrigger$1.snapDirectional = _snapDirectional;
38060  
38061	ScrollTrigger$1.addEventListener = function (type, callback) {
38062	  var a = _listeners[type] || (_listeners[type] = []);
38063	  ~a.indexOf(callback) || a.push(callback);
38064	};
38065  
38066	ScrollTrigger$1.removeEventListener = function (type, callback) {
38067	  var a = _listeners[type],
38068		  i = a && a.indexOf(callback);
38069	  i >= 0 && a.splice(i, 1);
38070	};
38071  
38072	ScrollTrigger$1.batch = function (targets, vars) {
38073	  var result = [],
38074		  varsCopy = {},
38075		  interval = vars.interval || 0.016,
38076		  batchMax = vars.batchMax || 1e9,
38077		  proxyCallback = function proxyCallback(type, callback) {
38078		var elements = [],
38079			triggers = [],
38080			delay = gsap$1.delayedCall(interval, function () {
38081		  callback(elements, triggers);
38082		  elements = [];
38083		  triggers = [];
38084		}).pause();
38085		return function (self) {
38086		  elements.length || delay.restart(true);
38087		  elements.push(self.trigger);
38088		  triggers.push(self);
38089		  batchMax <= elements.length && delay.progress(1);
38090		};
38091	  },
38092		  p;
38093  
38094	  for (p in vars) {
38095		varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p];
38096	  }
38097  
38098	  if (_isFunction(batchMax)) {
38099		batchMax = batchMax();
38100  
38101		_addListener$1(ScrollTrigger$1, "refresh", function () {
38102		  return batchMax = vars.batchMax();
38103		});
38104	  }
38105  
38106	  _toArray(targets).forEach(function (target) {
38107		var config = {};
38108  
38109		for (p in varsCopy) {
38110		  config[p] = varsCopy[p];
38111		}
38112  
38113		config.trigger = target;
38114		result.push(ScrollTrigger$1.create(config));
38115	  });
38116  
38117	  return result;
38118	};
38119  
38120	var _clampScrollAndGetDurationMultiplier = function _clampScrollAndGetDurationMultiplier(scrollFunc, current, end, max) {
38121	  current > max ? scrollFunc(max) : current < 0 && scrollFunc(0);
38122	  return end > max ? (max - current) / (end - current) : end < 0 ? current / (current - end) : 1;
38123	},
38124		_allowNativePanning = function _allowNativePanning(target, direction) {
38125	  if (direction === true) {
38126		target.style.removeProperty("touch-action");
38127	  } else {
38128		target.style.touchAction = direction === true ? "auto" : direction ? "pan-" + direction + (Observer.isTouch ? " pinch-zoom" : "") : "none";
38129	  }
38130  
38131	  target === _docEl$1 && _allowNativePanning(_body$1, direction);
38132	},
38133		_overflow = {
38134	  auto: 1,
38135	  scroll: 1
38136	},
38137		_nestedScroll = function _nestedScroll(_ref5) {
38138	  var event = _ref5.event,
38139		  target = _ref5.target,
38140		  axis = _ref5.axis;
38141  
38142	  var node = (event.changedTouches ? event.changedTouches[0] : event).target,
38143		  cache = node._gsap || gsap$1.core.getCache(node),
38144		  time = _getTime$1(),
38145		  cs;
38146  
38147	  if (!cache._isScrollT || time - cache._isScrollT > 2000) {
38148		while (node && node !== _body$1 && (node.scrollHeight <= node.clientHeight && node.scrollWidth <= node.clientWidth || !(_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]))) {
38149		  node = node.parentNode;
38150		}
38151  
38152		cache._isScroll = node && node !== target && !_isViewport$1(node) && (_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]);
38153		cache._isScrollT = time;
38154	  }
38155  
38156	  if (cache._isScroll || axis === "x") {
38157		event.stopPropagation();
38158		event._gsapAllow = true;
38159	  }
38160	},
38161		_inputObserver = function _inputObserver(target, type, inputs, nested) {
38162	  return Observer.create({
38163		target: target,
38164		capture: true,
38165		debounce: false,
38166		lockAxis: true,
38167		type: type,
38168		onWheel: nested = nested && _nestedScroll,
38169		onPress: nested,
38170		onDrag: nested,
38171		onScroll: nested,
38172		onEnable: function onEnable() {
38173		  return inputs && _addListener$1(_doc$1, Observer.eventTypes[0], _captureInputs, false, true);
38174		},
38175		onDisable: function onDisable() {
38176		  return _removeListener$1(_doc$1, Observer.eventTypes[0], _captureInputs, true);
38177		}
38178	  });
38179	},
38180		_inputExp = /(input|label|select|textarea)/i,
38181		_inputIsFocused,
38182		_captureInputs = function _captureInputs(e) {
38183	  var isInput = _inputExp.test(e.target.tagName);
38184  
38185	  if (isInput || _inputIsFocused) {
38186		e._gsapAllow = true;
38187		_inputIsFocused = isInput;
38188	  }
38189	},
38190		_getScrollNormalizer = function _getScrollNormalizer(vars) {
38191	  _isObject(vars) || (vars = {});
38192	  vars.preventDefault = vars.isNormalizer = vars.allowClicks = true;
38193	  vars.type || (vars.type = "wheel,touch");
38194	  vars.debounce = !!vars.debounce;
38195	  vars.id = vars.id || "normalizer";
38196  
38197	  var _vars2 = vars,
38198		  normalizeScrollX = _vars2.normalizeScrollX,
38199		  momentum = _vars2.momentum,
38200		  allowNestedScroll = _vars2.allowNestedScroll,
38201		  onRelease = _vars2.onRelease,
38202		  self,
38203		  maxY,
38204		  target = _getTarget(vars.target) || _docEl$1,
38205		  smoother = gsap$1.core.globals().ScrollSmoother,
38206		  smootherInstance = smoother && smoother.get(),
38207		  content = _fixIOSBug && (vars.content && _getTarget(vars.content) || smootherInstance && vars.content !== false && !smootherInstance.smooth() && smootherInstance.content()),
38208		  scrollFuncY = _getScrollFunc(target, _vertical),
38209		  scrollFuncX = _getScrollFunc(target, _horizontal),
38210		  scale = 1,
vendor: 4,132 bytes, lines 38211-38332
38211		  initialScale = (Observer.isTouch && _win$1.visualViewport ? _win$1.visualViewport.scale * _win$1.visualViewport.width : _win$1.outerWidth) / _win$1.innerWidth,
38212		  wheelRefresh = 0,
38213		  resolveMomentumDuration = _isFunction(momentum) ? function () {
38214		return momentum(self);
38215	  } : function () {
38216		return momentum || 2.8;
38217	  },
38218		  lastRefreshID,
38219		  skipTouchMove,
38220		  inputObserver = _inputObserver(target, vars.type, true, allowNestedScroll),
38221		  resumeTouchMove = function resumeTouchMove() {
38222		return skipTouchMove = false;
38223	  },
38224		  scrollClampX = _passThrough,
38225		  scrollClampY = _passThrough,
38226		  updateClamps = function updateClamps() {
38227		maxY = _maxScroll(target, _vertical);
38228		scrollClampY = _clamp$1(_fixIOSBug ? 1 : 0, maxY);
38229		normalizeScrollX && (scrollClampX = _clamp$1(0, _maxScroll(target, _horizontal)));
38230		lastRefreshID = _refreshID;
38231	  },
38232		  removeContentOffset = function removeContentOffset() {
38233		content._gsap.y = _round(parseFloat(content._gsap.y) + scrollFuncY.offset) + "px";
38234		content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + parseFloat(content._gsap.y) + ", 0, 1)";
38235		scrollFuncY.offset = scrollFuncY.cacheID = 0;
38236	  },
38237		  ignoreDrag = function ignoreDrag() {
38238		if (skipTouchMove) {
38239		  requestAnimationFrame(resumeTouchMove);
38240  
38241		  var offset = _round(self.deltaY / 2),
38242			  scroll = scrollClampY(scrollFuncY.v - offset);
38243  
38244		  if (content && scroll !== scrollFuncY.v + scrollFuncY.offset) {
38245			scrollFuncY.offset = scroll - scrollFuncY.v;
38246  
38247			var y = _round((parseFloat(content && content._gsap.y) || 0) - scrollFuncY.offset);
38248  
38249			content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + y + ", 0, 1)";
38250			content._gsap.y = y + "px";
38251			scrollFuncY.cacheID = _scrollers.cache;
38252  
38253			_updateAll();
38254		  }
38255  
38256		  return true;
38257		}
38258  
38259		scrollFuncY.offset && removeContentOffset();
38260		skipTouchMove = true;
38261	  },
38262		  tween,
38263		  startScrollX,
38264		  startScrollY,
38265		  onStopDelayedCall,
38266		  onResize = function onResize() {
38267		updateClamps();
38268  
38269		if (tween.isActive() && tween.vars.scrollY > maxY) {
38270		  scrollFuncY() > maxY ? tween.progress(1) && scrollFuncY(maxY) : tween.resetTo("scrollY", maxY);
38271		}
38272	  };
38273  
38274	  content && gsap$1.set(content, {
38275		y: "+=0"
38276	  });
38277  
38278	  vars.ignoreCheck = function (e) {
38279		return _fixIOSBug && e.type === "touchmove" && ignoreDrag() || scale > 1.05 && e.type !== "touchstart" || self.isGesturing || e.touches && e.touches.length > 1;
38280	  };
38281  
38282	  vars.onPress = function () {
38283		skipTouchMove = false;
38284		var prevScale = scale;
38285		scale = _round((_win$1.visualViewport && _win$1.visualViewport.scale || 1) / initialScale);
38286		tween.pause();
38287		prevScale !== scale && _allowNativePanning(target, scale > 1.01 ? true : normalizeScrollX ? false : "x");
38288		startScrollX = scrollFuncX();
38289		startScrollY = scrollFuncY();
38290		updateClamps();
38291		lastRefreshID = _refreshID;
38292	  };
38293  
38294	  vars.onRelease = vars.onGestureStart = function (self, wasDragging) {
38295		scrollFuncY.offset && removeContentOffset();
38296  
38297		if (!wasDragging) {
38298		  onStopDelayedCall.restart(true);
38299		} else {
38300		  _scrollers.cache++;
38301		  var dur = resolveMomentumDuration(),
38302			  currentScroll,
38303			  endScroll;
38304  
38305		  if (normalizeScrollX) {
38306			currentScroll = scrollFuncX();
38307			endScroll = currentScroll + dur * 0.05 * -self.velocityX / 0.227;
38308			dur *= _clampScrollAndGetDurationMultiplier(scrollFuncX, currentScroll, endScroll, _maxScroll(target, _horizontal));
38309			tween.vars.scrollX = scrollClampX(endScroll);
38310		  }
38311  
38312		  currentScroll = scrollFuncY();
38313		  endScroll = currentScroll + dur * 0.05 * -self.velocityY / 0.227;
38314		  dur *= _clampScrollAndGetDurationMultiplier(scrollFuncY, currentScroll, endScroll, _maxScroll(target, _vertical));
38315		  tween.vars.scrollY = scrollClampY(endScroll);
38316		  tween.invalidate().duration(dur).play(0.01);
38317  
38318		  if (_fixIOSBug && tween.vars.scrollY >= maxY || currentScroll >= maxY - 1) {
38319			gsap$1.to({}, {
38320			  onUpdate: onResize,
38321			  duration: dur
38322			});
38323		  }
38324		}
38325  
38326		onRelease && onRelease(self);
38327	  };
38328  
38329	  vars.onWheel = function () {
38330		tween._ts && tween.pause();
38331  
38332		if (_getTime$1() - wheelRefresh > 1000) {
vendor: 28,617 bytes, lines 38333-39387
38333		  lastRefreshID = 0;
38334		  wheelRefresh = _getTime$1();
38335		}
38336	  };
38337  
38338	  vars.onChange = function (self, dx, dy, xArray, yArray) {
38339		_refreshID !== lastRefreshID && updateClamps();
38340		dx && normalizeScrollX && scrollFuncX(scrollClampX(xArray[2] === dx ? startScrollX + (self.startX - self.x) : scrollFuncX() + dx - xArray[1]));
38341  
38342		if (dy) {
38343		  scrollFuncY.offset && removeContentOffset();
38344		  var isTouch = yArray[2] === dy,
38345			  y = isTouch ? startScrollY + self.startY - self.y : scrollFuncY() + dy - yArray[1],
38346			  yClamped = scrollClampY(y);
38347		  isTouch && y !== yClamped && (startScrollY += yClamped - y);
38348		  scrollFuncY(yClamped);
38349		}
38350  
38351		(dy || dx) && _updateAll();
38352	  };
38353  
38354	  vars.onEnable = function () {
38355		_allowNativePanning(target, normalizeScrollX ? false : "x");
38356  
38357		ScrollTrigger$1.addEventListener("refresh", onResize);
38358  
38359		_addListener$1(_win$1, "resize", onResize);
38360  
38361		if (scrollFuncY.smooth) {
38362		  scrollFuncY.target.style.scrollBehavior = "auto";
38363		  scrollFuncY.smooth = scrollFuncX.smooth = false;
38364		}
38365  
38366		inputObserver.enable();
38367	  };
38368  
38369	  vars.onDisable = function () {
38370		_allowNativePanning(target, true);
38371  
38372		_removeListener$1(_win$1, "resize", onResize);
38373  
38374		ScrollTrigger$1.removeEventListener("refresh", onResize);
38375		inputObserver.kill();
38376	  };
38377  
38378	  vars.lockAxis = vars.lockAxis !== false;
38379	  self = new Observer(vars);
38380	  self.iOS = _fixIOSBug;
38381	  _fixIOSBug && !scrollFuncY() && scrollFuncY(1);
38382	  _fixIOSBug && gsap$1.ticker.add(_passThrough);
38383	  onStopDelayedCall = self._dc;
38384	  tween = gsap$1.to(self, {
38385		ease: "power4",
38386		paused: true,
38387		inherit: false,
38388		scrollX: normalizeScrollX ? "+=0.1" : "+=0",
38389		scrollY: "+=0.1",
38390		modifiers: {
38391		  scrollY: _interruptionTracker(scrollFuncY, scrollFuncY(), function () {
38392			return tween.pause();
38393		  })
38394		},
38395		onUpdate: _updateAll,
38396		onComplete: onStopDelayedCall.vars.onComplete
38397	  });
38398	  return self;
38399	};
38400  
38401	ScrollTrigger$1.sort = function (func) {
38402	  return _triggers.sort(func || function (a, b) {
38403		return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6);
38404	  });
38405	};
38406  
38407	ScrollTrigger$1.observe = function (vars) {
38408	  return new Observer(vars);
38409	};
38410  
38411	ScrollTrigger$1.normalizeScroll = function (vars) {
38412	  if (typeof vars === "undefined") {
38413		return _normalizer$1;
38414	  }
38415  
38416	  if (vars === true && _normalizer$1) {
38417		return _normalizer$1.enable();
38418	  }
38419  
38420	  if (vars === false) {
38421		_normalizer$1 && _normalizer$1.kill();
38422		_normalizer$1 = vars;
38423		return;
38424	  }
38425  
38426	  var normalizer = vars instanceof Observer ? vars : _getScrollNormalizer(vars);
38427	  _normalizer$1 && _normalizer$1.target === normalizer.target && _normalizer$1.kill();
38428	  _isViewport$1(normalizer.target) && (_normalizer$1 = normalizer);
38429	  return normalizer;
38430	};
38431  
38432	ScrollTrigger$1.core = {
38433	  _getVelocityProp: _getVelocityProp,
38434	  _inputObserver: _inputObserver,
38435	  _scrollers: _scrollers,
38436	  _proxies: _proxies,
38437	  bridge: {
38438		ss: function ss() {
38439		  _lastScrollTime || _dispatch("scrollStart");
38440		  _lastScrollTime = _getTime$1();
38441		},
38442		ref: function ref() {
38443		  return _refreshing;
38444		}
38445	  }
38446	};
38447	_getGSAP$1() && gsap$1.registerPlugin(ScrollTrigger$1);
38448  
38449	exports.ScrollTrigger = ScrollTrigger$1;
38450	exports.default = ScrollTrigger$1;
38451  
38452	if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;}
38453  
38454  })));
38455
38456/*!
38457 * CustomEase 3.12.7
38458 * https://gsap.com
38459 * 
38460 * @license Copyright 2025, GreenSock. All rights reserved.
38461 * Subject to the terms at https://gsap.com/standard-license or for Club GSAP members, the agreement issued with that membership.
38462 * @author: Jack Doyle, [email protected]
38463 */
38464
38465  (function (global, factory) {
38466	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
38467	typeof define === 'function' && define.amd ? define(['exports'], factory) :
38468	(global = global || self, factory(global.window = global.window || {}));
38469}(this, (function (exports) { 'use strict';
38470
38471	var _svgPathExp = /[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
38472	    _scientific = /[\+\-]?\d*\.?\d+e[\+\-]?\d+/ig,
38473	    _DEG2RAD = Math.PI / 180,
38474	    _sin = Math.sin,
38475	    _cos = Math.cos,
38476	    _abs = Math.abs,
38477	    _sqrt = Math.sqrt,
38478	    _isNumber = function _isNumber(value) {
38479	  return typeof value === "number";
38480	},
38481	    _roundingNum = 1e5,
38482	    _round = function _round(value) {
38483	  return Math.round(value * _roundingNum) / _roundingNum || 0;
38484	};
38485	function transformRawPath(rawPath, a, b, c, d, tx, ty) {
38486	  var j = rawPath.length,
38487	      segment,
38488	      l,
38489	      i,
38490	      x,
38491	      y;
38492
38493	  while (--j > -1) {
38494	    segment = rawPath[j];
38495	    l = segment.length;
38496
38497	    for (i = 0; i < l; i += 2) {
38498	      x = segment[i];
38499	      y = segment[i + 1];
38500	      segment[i] = x * a + y * c + tx;
38501	      segment[i + 1] = x * b + y * d + ty;
38502	    }
38503	  }
38504
38505	  rawPath._dirty = 1;
38506	  return rawPath;
38507	}
38508
38509	function arcToSegment(lastX, lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y) {
38510	  if (lastX === x && lastY === y) {
38511	    return;
38512	  }
38513
38514	  rx = _abs(rx);
38515	  ry = _abs(ry);
38516
38517	  var angleRad = angle % 360 * _DEG2RAD,
38518	      cosAngle = _cos(angleRad),
38519	      sinAngle = _sin(angleRad),
38520	      PI = Math.PI,
38521	      TWOPI = PI * 2,
38522	      dx2 = (lastX - x) / 2,
38523	      dy2 = (lastY - y) / 2,
38524	      x1 = cosAngle * dx2 + sinAngle * dy2,
38525	      y1 = -sinAngle * dx2 + cosAngle * dy2,
38526	      x1_sq = x1 * x1,
38527	      y1_sq = y1 * y1,
38528	      radiiCheck = x1_sq / (rx * rx) + y1_sq / (ry * ry);
38529
38530	  if (radiiCheck > 1) {
38531	    rx = _sqrt(radiiCheck) * rx;
38532	    ry = _sqrt(radiiCheck) * ry;
38533	  }
38534
38535	  var rx_sq = rx * rx,
38536	      ry_sq = ry * ry,
38537	      sq = (rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq) / (rx_sq * y1_sq + ry_sq * x1_sq);
38538
38539	  if (sq < 0) {
38540	    sq = 0;
38541	  }
38542
38543	  var coef = (largeArcFlag === sweepFlag ? -1 : 1) * _sqrt(sq),
38544	      cx1 = coef * (rx * y1 / ry),
38545	      cy1 = coef * -(ry * x1 / rx),
38546	      sx2 = (lastX + x) / 2,
38547	      sy2 = (lastY + y) / 2,
38548	      cx = sx2 + (cosAngle * cx1 - sinAngle * cy1),
38549	      cy = sy2 + (sinAngle * cx1 + cosAngle * cy1),
38550	      ux = (x1 - cx1) / rx,
38551	      uy = (y1 - cy1) / ry,
38552	      vx = (-x1 - cx1) / rx,
38553	      vy = (-y1 - cy1) / ry,
38554	      temp = ux * ux + uy * uy,
38555	      angleStart = (uy < 0 ? -1 : 1) * Math.acos(ux / _sqrt(temp)),
38556	      angleExtent = (ux * vy - uy * vx < 0 ? -1 : 1) * Math.acos((ux * vx + uy * vy) / _sqrt(temp * (vx * vx + vy * vy)));
38557
38558	  isNaN(angleExtent) && (angleExtent = PI);
38559
38560	  if (!sweepFlag && angleExtent > 0) {
38561	    angleExtent -= TWOPI;
38562	  } else if (sweepFlag && angleExtent < 0) {
38563	    angleExtent += TWOPI;
38564	  }
38565
38566	  angleStart %= TWOPI;
38567	  angleExtent %= TWOPI;
38568
38569	  var segments = Math.ceil(_abs(angleExtent) / (TWOPI / 4)),
38570	      rawPath = [],
38571	      angleIncrement = angleExtent / segments,
38572	      controlLength = 4 / 3 * _sin(angleIncrement / 2) / (1 + _cos(angleIncrement / 2)),
38573	      ma = cosAngle * rx,
38574	      mb = sinAngle * rx,
38575	      mc = sinAngle * -ry,
38576	      md = cosAngle * ry,
38577	      i;
38578
38579	  for (i = 0; i < segments; i++) {
38580	    angle = angleStart + i * angleIncrement;
38581	    x1 = _cos(angle);
38582	    y1 = _sin(angle);
38583	    ux = _cos(angle += angleIncrement);
38584	    uy = _sin(angle);
38585	    rawPath.push(x1 - controlLength * y1, y1 + controlLength * x1, ux + controlLength * uy, uy - controlLength * ux, ux, uy);
38586	  }
38587
38588	  for (i = 0; i < rawPath.length; i += 2) {
38589	    x1 = rawPath[i];
38590	    y1 = rawPath[i + 1];
38591	    rawPath[i] = x1 * ma + y1 * mc + cx;
38592	    rawPath[i + 1] = x1 * mb + y1 * md + cy;
38593	  }
38594
38595	  rawPath[i - 2] = x;
38596	  rawPath[i - 1] = y;
38597	  return rawPath;
38598	}
38599
38600	function stringToRawPath(d) {
38601	  var a = (d + "").replace(_scientific, function (m) {
38602	    var n = +m;
38603	    return n < 0.0001 && n > -0.0001 ? 0 : n;
38604	  }).match(_svgPathExp) || [],
38605	      path = [],
38606	      relativeX = 0,
38607	      relativeY = 0,
38608	      twoThirds = 2 / 3,
38609	      elements = a.length,
38610	      points = 0,
38611	      errorMessage = "ERROR: malformed path: " + d,
38612	      i,
38613	      j,
38614	      x,
38615	      y,
38616	      command,
38617	      isRelative,
38618	      segment,
38619	      startX,
38620	      startY,
38621	      difX,
38622	      difY,
38623	      beziers,
38624	      prevCommand,
38625	      flag1,
38626	      flag2,
38627	      line = function line(sx, sy, ex, ey) {
38628	    difX = (ex - sx) / 3;
38629	    difY = (ey - sy) / 3;
38630	    segment.push(sx + difX, sy + difY, ex - difX, ey - difY, ex, ey);
38631	  };
38632
38633	  if (!d || !isNaN(a[0]) || isNaN(a[1])) {
38634	    console.log(errorMessage);
38635	    return path;
38636	  }
38637
38638	  for (i = 0; i < elements; i++) {
38639	    prevCommand = command;
38640
38641	    if (isNaN(a[i])) {
38642	      command = a[i].toUpperCase();
38643	      isRelative = command !== a[i];
38644	    } else {
38645	      i--;
38646	    }
38647
38648	    x = +a[i + 1];
38649	    y = +a[i + 2];
38650
38651	    if (isRelative) {
38652	      x += relativeX;
38653	      y += relativeY;
38654	    }
38655
38656	    if (!i) {
38657	      startX = x;
38658	      startY = y;
38659	    }
38660
38661	    if (command === "M") {
38662	      if (segment) {
38663	        if (segment.length < 8) {
38664	          path.length -= 1;
38665	        } else {
38666	          points += segment.length;
38667	        }
38668	      }
38669
38670	      relativeX = startX = x;
38671	      relativeY = startY = y;
38672	      segment = [x, y];
38673	      path.push(segment);
38674	      i += 2;
38675	      command = "L";
38676	    } else if (command === "C") {
38677	      if (!segment) {
38678	        segment = [0, 0];
38679	      }
38680
38681	      if (!isRelative) {
38682	        relativeX = relativeY = 0;
38683	      }
38684
38685	      segment.push(x, y, relativeX + a[i + 3] * 1, relativeY + a[i + 4] * 1, relativeX += a[i + 5] * 1, relativeY += a[i + 6] * 1);
38686	      i += 6;
38687	    } else if (command === "S") {
38688	      difX = relativeX;
38689	      difY = relativeY;
38690
38691	      if (prevCommand === "C" || prevCommand === "S") {
38692	        difX += relativeX - segment[segment.length - 4];
38693	        difY += relativeY - segment[segment.length - 3];
38694	      }
38695
38696	      if (!isRelative) {
38697	        relativeX = relativeY = 0;
38698	      }
38699
38700	      segment.push(difX, difY, x, y, relativeX += a[i + 3] * 1, relativeY += a[i + 4] * 1);
38701	      i += 4;
38702	    } else if (command === "Q") {
38703	      difX = relativeX + (x - relativeX) * twoThirds;
38704	      difY = relativeY + (y - relativeY) * twoThirds;
38705
38706	      if (!isRelative) {
38707	        relativeX = relativeY = 0;
38708	      }
38709
38710	      relativeX += a[i + 3] * 1;
38711	      relativeY += a[i + 4] * 1;
38712	      segment.push(difX, difY, relativeX + (x - relativeX) * twoThirds, relativeY + (y - relativeY) * twoThirds, relativeX, relativeY);
38713	      i += 4;
38714	    } else if (command === "T") {
38715	      difX = relativeX - segment[segment.length - 4];
38716	      difY = relativeY - segment[segment.length - 3];
38717	      segment.push(relativeX + difX, relativeY + difY, x + (relativeX + difX * 1.5 - x) * twoThirds, y + (relativeY + difY * 1.5 - y) * twoThirds, relativeX = x, relativeY = y);
38718	      i += 2;
38719	    } else if (command === "H") {
38720	      line(relativeX, relativeY, relativeX = x, relativeY);
38721	      i += 1;
38722	    } else if (command === "V") {
38723	      line(relativeX, relativeY, relativeX, relativeY = x + (isRelative ? relativeY - relativeX : 0));
38724	      i += 1;
38725	    } else if (command === "L" || command === "Z") {
38726	      if (command === "Z") {
38727	        x = startX;
38728	        y = startY;
38729	        segment.closed = true;
38730	      }
38731
38732	      if (command === "L" || _abs(relativeX - x) > 0.5 || _abs(relativeY - y) > 0.5) {
38733	        line(relativeX, relativeY, x, y);
38734
38735	        if (command === "L") {
38736	          i += 2;
38737	        }
38738	      }
38739
38740	      relativeX = x;
38741	      relativeY = y;
38742	    } else if (command === "A") {
38743	      flag1 = a[i + 4];
38744	      flag2 = a[i + 5];
38745	      difX = a[i + 6];
38746	      difY = a[i + 7];
38747	      j = 7;
38748
38749	      if (flag1.length > 1) {
38750	        if (flag1.length < 3) {
38751	          difY = difX;
38752	          difX = flag2;
38753	          j--;
38754	        } else {
38755	          difY = flag2;
38756	          difX = flag1.substr(2);
38757	          j -= 2;
38758	        }
38759
38760	        flag2 = flag1.charAt(1);
38761	        flag1 = flag1.charAt(0);
38762	      }
38763
38764	      beziers = arcToSegment(relativeX, relativeY, +a[i + 1], +a[i + 2], +a[i + 3], +flag1, +flag2, (isRelative ? relativeX : 0) + difX * 1, (isRelative ? relativeY : 0) + difY * 1);
38765	      i += j;
38766
38767	      if (beziers) {
38768	        for (j = 0; j < beziers.length; j++) {
38769	          segment.push(beziers[j]);
38770	        }
38771	      }
38772
38773	      relativeX = segment[segment.length - 2];
38774	      relativeY = segment[segment.length - 1];
38775	    } else {
38776	      console.log(errorMessage);
38777	    }
38778	  }
38779
38780	  i = segment.length;
38781
38782	  if (i < 6) {
38783	    path.pop();
38784	    i = 0;
38785	  } else if (segment[0] === segment[i - 2] && segment[1] === segment[i - 1]) {
38786	    segment.closed = true;
38787	  }
38788
38789	  path.totalPoints = points + i;
38790	  return path;
38791	}
38792	function rawPathToString(rawPath) {
38793	  if (_isNumber(rawPath[0])) {
38794	    rawPath = [rawPath];
38795	  }
38796
38797	  var result = "",
38798	      l = rawPath.length,
38799	      sl,
38800	      s,
38801	      i,
38802	      segment;
38803
38804	  for (s = 0; s < l; s++) {
38805	    segment = rawPath[s];
38806	    result += "M" + _round(segment[0]) + "," + _round(segment[1]) + " C";
38807	    sl = segment.length;
38808
38809	    for (i = 2; i < sl; i++) {
38810	      result += _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i]) + " ";
38811	    }
38812
38813	    if (segment.closed) {
38814	      result += "z";
38815	    }
38816	  }
38817
38818	  return result;
38819	}
38820
38821	/*!
38822	 * CustomEase 3.12.7
38823	 * https://gsap.com
38824	 *
38825	 * @license Copyright 2008-2025, GreenSock. All rights reserved.
38826	 * Subject to the terms at https://gsap.com/standard-license or for
38827	 * Club GSAP members, the agreement issued with that membership.
38828	 * @author: Jack Doyle, [email protected]
38829	*/
38830
38831	var gsap,
38832	    _coreInitted,
38833	    _getGSAP = function _getGSAP() {
38834	  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;
38835	},
38836	    _initCore = function _initCore() {
38837	  gsap = _getGSAP();
38838
38839	  if (gsap) {
38840	    gsap.registerEase("_CE", CustomEase.create);
38841	    _coreInitted = 1;
38842	  } else {
38843	    console.warn("Please gsap.registerPlugin(CustomEase)");
38844	  }
38845	},
38846	    _bigNum = 1e20,
38847	    _round$1 = function _round(value) {
38848	  return ~~(value * 1000 + (value < 0 ? -.5 : .5)) / 1000;
38849	},
38850	    _numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/gi,
38851	    _needsParsingExp = /[cLlsSaAhHvVtTqQ]/g,
38852	    _findMinimum = function _findMinimum(values) {
38853	  var l = values.length,
38854	      min = _bigNum,
38855	      i;
38856
38857	  for (i = 1; i < l; i += 6) {
38858	    +values[i] < min && (min = +values[i]);
38859	  }
38860
38861	  return min;
38862	},
38863	    _normalize = function _normalize(values, height, originY) {
38864	  if (!originY && originY !== 0) {
38865	    originY = Math.max(+values[values.length - 1], +values[1]);
38866	  }
38867
38868	  var tx = +values[0] * -1,
38869	      ty = -originY,
38870	      l = values.length,
38871	      sx = 1 / (+values[l - 2] + tx),
38872	      sy = -height || (Math.abs(+values[l - 1] - +values[1]) < 0.01 * (+values[l - 2] - +values[0]) ? _findMinimum(values) + ty : +values[l - 1] + ty),
38873	      i;
38874
38875	  if (sy) {
38876	    sy = 1 / sy;
38877	  } else {
38878	    sy = -sx;
38879	  }
38880
38881	  for (i = 0; i < l; i += 2) {
38882	    values[i] = (+values[i] + tx) * sx;
38883	    values[i + 1] = (+values[i + 1] + ty) * sy;
38884	  }
38885	},
38886	    _bezierToPoints = function _bezierToPoints(x1, y1, x2, y2, x3, y3, x4, y4, threshold, points, index) {
38887	  var x12 = (x1 + x2) / 2,
38888	      y12 = (y1 + y2) / 2,
38889	      x23 = (x2 + x3) / 2,
38890	      y23 = (y2 + y3) / 2,
38891	      x34 = (x3 + x4) / 2,
38892	      y34 = (y3 + y4) / 2,
38893	      x123 = (x12 + x23) / 2,
38894	      y123 = (y12 + y23) / 2,
38895	      x234 = (x23 + x34) / 2,
38896	      y234 = (y23 + y34) / 2,
38897	      x1234 = (x123 + x234) / 2,
38898	      y1234 = (y123 + y234) / 2,
38899	      dx = x4 - x1,
38900	      dy = y4 - y1,
38901	      d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx),
38902	      d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx),
38903	      length;
38904
38905	  if (!points) {
38906	    points = [{
38907	      x: x1,
38908	      y: y1
38909	    }, {
38910	      x: x4,
38911	      y: y4
38912	    }];
38913	    index = 1;
38914	  }
38915
38916	  points.splice(index || points.length - 1, 0, {
38917	    x: x1234,
38918	    y: y1234
38919	  });
38920
38921	  if ((d2 + d3) * (d2 + d3) > threshold * (dx * dx + dy * dy)) {
38922	    length = points.length;
38923
38924	    _bezierToPoints(x1, y1, x12, y12, x123, y123, x1234, y1234, threshold, points, index);
38925
38926	    _bezierToPoints(x1234, y1234, x234, y234, x34, y34, x4, y4, threshold, points, index + 1 + (points.length - length));
38927	  }
38928
38929	  return points;
38930	};
38931
38932	var CustomEase = function () {
38933	  function CustomEase(id, data, config) {
38934	    _coreInitted || _initCore();
38935	    this.id = id;
38936	     this.setData(data, config);
38937	  }
38938
38939	  var _proto = CustomEase.prototype;
38940
38941	  _proto.setData = function setData(data, config) {
38942	    config = config || {};
38943	    data = data || "0,0,1,1";
38944	    var values = data.match(_numExp),
38945	        closest = 1,
38946	        points = [],
38947	        lookup = [],
38948	        precision = config.precision || 1,
38949	        fast = precision <= 1,
38950	        l,
38951	        a1,
38952	        a2,
38953	        i,
38954	        inc,
38955	        j,
38956	        point,
38957	        prevPoint,
38958	        p;
38959	    this.data = data;
38960
38961	    if (_needsParsingExp.test(data) || ~data.indexOf("M") && data.indexOf("C") < 0) {
38962	      values = stringToRawPath(data)[0];
38963	    }
38964
38965	    l = values.length;
38966
38967	    if (l === 4) {
38968	      values.unshift(0, 0);
38969	      values.push(1, 1);
38970	      l = 8;
38971	    } else if ((l - 2) % 6) {
38972	      throw "Invalid CustomEase";
38973	    }
38974
38975	    if (+values[0] !== 0 || +values[l - 2] !== 1) {
38976	      _normalize(values, config.height, config.originY);
38977	    }
38978
38979	    this.segment = values;
38980
38981	    for (i = 2; i < l; i += 6) {
38982	      a1 = {
38983	        x: +values[i - 2],
38984	        y: +values[i - 1]
38985	      };
38986	      a2 = {
38987	        x: +values[i + 4],
38988	        y: +values[i + 5]
38989	      };
38990	      points.push(a1, a2);
38991
38992	      _bezierToPoints(a1.x, a1.y, +values[i], +values[i + 1], +values[i + 2], +values[i + 3], a2.x, a2.y, 1 / (precision * 200000), points, points.length - 1);
38993	    }
38994
38995	    l = points.length;
38996
38997	    for (i = 0; i < l; i++) {
38998	      point = points[i];
38999	      prevPoint = points[i - 1] || point;
39000
39001	      if ((point.x > prevPoint.x || prevPoint.y !== point.y && prevPoint.x === point.x || point === prevPoint) && point.x <= 1) {
39002	        prevPoint.cx = point.x - prevPoint.x;
39003	        prevPoint.cy = point.y - prevPoint.y;
39004	        prevPoint.n = point;
39005	        prevPoint.nx = point.x;
39006
39007	        if (fast && i > 1 && Math.abs(prevPoint.cy / prevPoint.cx - points[i - 2].cy / points[i - 2].cx) > 2) {
39008	          fast = 0;
39009	        }
39010
39011	        if (prevPoint.cx < closest) {
39012	          if (!prevPoint.cx) {
39013	            prevPoint.cx = 0.001;
39014
39015	            if (i === l - 1) {
39016	              prevPoint.x -= 0.001;
39017	              closest = Math.min(closest, 0.001);
39018	              fast = 0;
39019	            }
39020	          } else {
39021	            closest = prevPoint.cx;
39022	          }
39023	        }
39024	      } else {
39025	        points.splice(i--, 1);
39026	        l--;
39027	      }
39028	    }
39029
39030	    l = 1 / closest + 1 | 0;
39031	    inc = 1 / l;
39032	    j = 0;
39033	    point = points[0];
39034
39035	    if (fast) {
39036	      for (i = 0; i < l; i++) {
39037	        p = i * inc;
39038
39039	        if (point.nx < p) {
39040	          point = points[++j];
39041	        }
39042
39043	        a1 = point.y + (p - point.x) / point.cx * point.cy;
39044	        lookup[i] = {
39045	          x: p,
39046	          cx: inc,
39047	          y: a1,
39048	          cy: 0,
39049	          nx: 9
39050	        };
39051
39052	        if (i) {
39053	          lookup[i - 1].cy = a1 - lookup[i - 1].y;
39054	        }
39055	      }
39056
39057	      j = points[points.length - 1];
39058	      lookup[l - 1].cy = j.y - a1;
39059	      lookup[l - 1].cx = j.x - lookup[lookup.length - 1].x;
39060	    } else {
39061	      for (i = 0; i < l; i++) {
39062	        if (point.nx < i * inc) {
39063	          point = points[++j];
39064	        }
39065
39066	        lookup[i] = point;
39067	      }
39068
39069	      if (j < points.length - 1) {
39070	        lookup[i - 1] = points[points.length - 2];
39071	      }
39072	    }
39073
39074	    this.ease = function (p) {
39075	      var point = lookup[p * l | 0] || lookup[l - 1];
39076
39077	      if (point.nx < p) {
39078	        point = point.n;
39079	      }
39080
39081	      return point.y + (p - point.x) / point.cx * point.cy;
39082	    };
39083
39084	    this.ease.custom = this;
39085	    this.id && gsap && gsap.registerEase(this.id, this.ease);
39086	    return this;
39087	  };
39088
39089	  _proto.getSVGData = function getSVGData(config) {
39090	    return CustomEase.getSVGData(this, config);
39091	  };
39092
39093	  CustomEase.create = function create(id, data, config) {
39094	    return new CustomEase(id, data, config).ease;
39095	  };
39096
39097	  CustomEase.register = function register(core) {
39098	    gsap = core;
39099
39100	    _initCore();
39101	  };
39102
39103	  CustomEase.get = function get(id) {
39104	    return gsap.parseEase(id);
39105	  };
39106
39107	  CustomEase.getSVGData = function getSVGData(ease, config) {
39108	    config = config || {};
39109	    var width = config.width || 100,
39110	        height = config.height || 100,
39111	        x = config.x || 0,
39112	        y = (config.y || 0) + height,
39113	        e = gsap.utils.toArray(config.path)[0],
39114	        a,
39115	        slope,
39116	        i,
39117	        inc,
39118	        tx,
39119	        ty,
39120	        precision,
39121	        threshold,
39122	        prevX,
39123	        prevY;
39124
39125	    if (config.invert) {
39126	      height = -height;
39127	      y = 0;
39128	    }
39129
39130	    if (typeof ease === "string") {
39131	      ease = gsap.parseEase(ease);
39132	    }
39133
39134	    if (ease.custom) {
39135	      ease = ease.custom;
39136	    }
39137
39138	    if (ease instanceof CustomEase) {
39139	      a = rawPathToString(transformRawPath([ease.segment], width, 0, 0, -height, x, y));
39140	    } else {
39141	      a = [x, y];
39142	      precision = Math.max(5, (config.precision || 1) * 200);
39143	      inc = 1 / precision;
39144	      precision += 2;
39145	      threshold = 5 / precision;
39146	      prevX = _round$1(x + inc * width);
39147	      prevY = _round$1(y + ease(inc) * -height);
39148	      slope = (prevY - y) / (prevX - x);
39149
39150	      for (i = 2; i < precision; i++) {
39151	        tx = _round$1(x + i * inc * width);
39152	        ty = _round$1(y + ease(i * inc) * -height);
39153
39154	        if (Math.abs((ty - prevY) / (tx - prevX) - slope) > threshold || i === precision - 1) {
39155	          a.push(prevX, prevY);
39156	          slope = (ty - prevY) / (tx - prevX);
39157	        }
39158
39159	        prevX = tx;
39160	        prevY = ty;
39161	      }
39162
39163	      a = "M" + a.join(",");
39164	    }
39165
39166	    e && e.setAttribute("d", a);
39167	    return a;
39168	  };
39169
39170	  return CustomEase;
39171	}();
39172	CustomEase.version = "3.12.7";
39173	CustomEase.headless = true;
39174	_getGSAP() && gsap.registerPlugin(CustomEase);
39175
39176	exports.CustomEase = CustomEase;
39177	exports.default = CustomEase;
39178
39179	Object.defineProperty(exports, '__esModule', { value: true });
39180
39181})));
39182(function (global, factory) {
39183  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
39184  typeof define === 'function' && define.amd ? define(['exports'], factory) :
39185  (global = global || self, factory(global.window = global.window || {}));
39186}(this, (function (exports) { 'use strict';
39187
39188  function _inheritsLoose(subClass, superClass) {
39189    subClass.prototype = Object.create(superClass.prototype);
39190    subClass.prototype.constructor = subClass;
39191    subClass.__proto__ = superClass;
39192  }
39193
39194  function _assertThisInitialized(self) {
39195    if (self === void 0) {
39196      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
39197    }
39198
39199    return self;
39200  }
39201
39202  var _doc,
39203      _win,
39204      _docElement,
39205      _body,
39206      _divContainer,
39207      _svgContainer,
39208      _identityMatrix,
39209      _gEl,
39210      _transformProp = "transform",
39211      _transformOriginProp = _transformProp + "Origin",
39212      _hasOffsetBug,
39213      _setDoc = function _setDoc(element) {
39214    var doc = element.ownerDocument || element;
39215
39216    if (!(_transformProp in element.style) && "msTransform" in element.style) {
39217      _transformProp = "msTransform";
39218      _transformOriginProp = _transformProp + "Origin";
39219    }
39220
39221    while (doc.parentNode && (doc = doc.parentNode)) {}
39222
39223    _win = window;
39224    _identityMatrix = new Matrix2D();
39225
39226    if (doc) {
39227      _doc = doc;
39228      _docElement = doc.documentElement;
39229      _body = doc.body;
39230      _gEl = _doc.createElementNS("http://www.w3.org/2000/svg", "g");
39231      _gEl.style.transform = "none";
39232      var d1 = doc.createElement("div"),
39233          d2 = doc.createElement("div"),
39234          root = doc && (doc.body || doc.firstElementChild);
39235
39236      if (root && root.appendChild) {
39237        root.appendChild(d1);
39238        d1.appendChild(d2);
39239        d1.setAttribute("style", "position:static;transform:translate3d(0,0,1px)");
39240        _hasOffsetBug = d2.offsetParent !== d1;
39241        root.removeChild(d1);
39242      }
39243    }
39244
39245    return doc;
39246  },
39247      _forceNonZeroScale = function _forceNonZeroScale(e) {
39248    var a, cache;
39249
39250    while (e && e !== _body) {
39251      cache = e._gsap;
39252      cache && cache.uncache && cache.get(e, "x");
39253
39254      if (cache && !cache.scaleX && !cache.scaleY && cache.renderTransform) {
39255        cache.scaleX = cache.scaleY = 1e-4;
39256        cache.renderTransform(1, cache);
39257        a ? a.push(cache) : a = [cache];
39258      }
39259
39260      e = e.parentNode;
39261    }
39262
39263    return a;
39264  },
39265      _svgTemps = [],
39266      _divTemps = [],
39267      _getDocScrollTop = function _getDocScrollTop() {
39268    return _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0;
39269  },
39270      _getDocScrollLeft = function _getDocScrollLeft() {
39271    return _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0;
39272  },
39273      _svgOwner = function _svgOwner(element) {
39274    return element.ownerSVGElement || ((element.tagName + "").toLowerCase() === "svg" ? element : null);
39275  },
39276      _isFixed = function _isFixed(element) {
39277    if (_win.getComputedStyle(element).position === "fixed") {
39278      return true;
39279    }
39280
39281    element = element.parentNode;
39282
39283    if (element && element.nodeType === 1) {
39284      return _isFixed(element);
39285    }
39286  },
39287      _createSibling = function _createSibling(element, i) {
39288    if (element.parentNode && (_doc || _setDoc(element))) {
39289      var svg = _svgOwner(element),
39290          ns = svg ? svg.getAttribute("xmlns") || "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml",
39291          type = svg ? i ? "rect" : "g" : "div",
39292          x = i !== 2 ? 0 : 100,
39293          y = i === 3 ? 100 : 0,
39294          css = "position:absolute;display:block;pointer-events:none;margin:0;padding:0;",
39295          e = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, "http"), type) : _doc.createElement(type);
39296
39297      if (i) {
39298        if (!svg) {
39299          if (!_divContainer) {
39300            _divContainer = _createSibling(element);
39301            _divContainer.style.cssText = css;
39302          }
39303
39304          e.style.cssText = css + "width:0.1px;height:0.1px;top:" + y + "px;left:" + x + "px";
39305
39306          _divContainer.appendChild(e);
39307        } else {
39308          _svgContainer || (_svgContainer = _createSibling(element));
39309          e.setAttribute("width", 0.01);
39310          e.setAttribute("height", 0.01);
39311          e.setAttribute("transform", "translate(" + x + "," + y + ")");
39312
39313          _svgContainer.appendChild(e);
39314        }
39315      }
39316
39317      return e;
39318    }
39319
39320    throw "Need document and parent.";
39321  },
39322      _consolidate = function _consolidate(m) {
39323    var c = new Matrix2D(),
39324        i = 0;
39325
39326    for (; i < m.numberOfItems; i++) {
39327      c.multiply(m.getItem(i).matrix);
39328    }
39329
39330    return c;
39331  },
39332      _getCTM = function _getCTM(svg) {
39333    var m = svg.getCTM(),
39334        transform;
39335
39336    if (!m) {
39337      transform = svg.style[_transformProp];
39338      svg.style[_transformProp] = "none";
39339      svg.appendChild(_gEl);
39340      m = _gEl.getCTM();
39341      svg.removeChild(_gEl);
39342      transform ? svg.style[_transformProp] = transform : svg.style.removeProperty(_transformProp.replace(/([A-Z])/g, "-$1").toLowerCase());
39343    }
39344
39345    return m || _identityMatrix.clone();
39346  },
39347      _placeSiblings = function _placeSiblings(element, adjustGOffset) {
39348    var svg = _svgOwner(element),
39349        isRootSVG = element === svg,
39350        siblings = svg ? _svgTemps : _divTemps,
39351        parent = element.parentNode,
39352        container,
39353        m,
39354        b,
39355        x,
39356        y,
39357        cs;
39358
39359    if (element === _win) {
39360      return element;
39361    }
39362
39363    siblings.length || siblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3));
39364    container = svg ? _svgContainer : _divContainer;
39365
39366    if (svg) {
39367      if (isRootSVG) {
39368        b = _getCTM(element);
39369        x = -b.e / b.a;
39370        y = -b.f / b.d;
39371        m = _identityMatrix;
39372      } else if (element.getBBox) {
39373        b = element.getBBox();
39374        m = element.transform ? element.transform.baseVal : {};
39375        m = !m.numberOfItems ? _identityMatrix : m.numberOfItems > 1 ? _consolidate(m) : m.getItem(0).matrix;
39376        x = m.a * b.x + m.c * b.y;
39377        y = m.b * b.x + m.d * b.y;
39378      } else {
39379        m = new Matrix2D();
39380        x = y = 0;
39381      }
39382
39383      if (adjustGOffset && element.tagName.toLowerCase() === "g") {
39384        x = y = 0;
39385      }
39386
39387      (isRootSVG ? svg : parent).appendChild(container);
vendor: 1,139 bytes, lines 39388-39423
39388      container.setAttribute("transform", "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + (m.e + x) + "," + (m.f + y) + ")");
39389    } else {
39390      x = y = 0;
39391
39392      if (_hasOffsetBug) {
39393        m = element.offsetParent;
39394        b = element;
39395
39396        while (b && (b = b.parentNode) && b !== m && b.parentNode) {
39397          if ((_win.getComputedStyle(b)[_transformProp] + "").length > 4) {
39398            x = b.offsetLeft;
39399            y = b.offsetTop;
39400            b = 0;
39401          }
39402        }
39403      }
39404
39405      cs = _win.getComputedStyle(element);
39406
39407      if (cs.position !== "absolute" && cs.position !== "fixed") {
39408        m = element.offsetParent;
39409
39410        while (parent && parent !== m) {
39411          x += parent.scrollLeft || 0;
39412          y += parent.scrollTop || 0;
39413          parent = parent.parentNode;
39414        }
39415      }
39416
39417      b = container.style;
39418      b.top = element.offsetTop - y + "px";
39419      b.left = element.offsetLeft - x + "px";
39420      b[_transformProp] = cs[_transformProp];
39421      b[_transformOriginProp] = cs[_transformOriginProp];
39422      b.position = cs.position === "fixed" ? "fixed" : "absolute";
39423      element.parentNode
vendor: 37,456 bytes, lines 39423-40678
39423.appendChild(container);
39424    }
39425
39426    return container;
39427  },
39428      _setMatrix = function _setMatrix(m, a, b, c, d, e, f) {
39429    m.a = a;
39430    m.b = b;
39431    m.c = c;
39432    m.d = d;
39433    m.e = e;
39434    m.f = f;
39435    return m;
39436  };
39437
39438  var Matrix2D = function () {
39439    function Matrix2D(a, b, c, d, e, f) {
39440      if (a === void 0) {
39441        a = 1;
39442      }
39443
39444      if (b === void 0) {
39445        b = 0;
39446      }
39447
39448      if (c === void 0) {
39449        c = 0;
39450      }
39451
39452      if (d === void 0) {
39453        d = 1;
39454      }
39455
39456      if (e === void 0) {
39457        e = 0;
39458      }
39459
39460      if (f === void 0) {
39461        f = 0;
39462      }
39463
39464      _setMatrix(this, a, b, c, d, e, f);
39465    }
39466
39467    var _proto = Matrix2D.prototype;
39468
39469    _proto.inverse = function inverse() {
39470      var a = this.a,
39471          b = this.b,
39472          c = this.c,
39473          d = this.d,
39474          e = this.e,
39475          f = this.f,
39476          determinant = a * d - b * c || 1e-10;
39477      return _setMatrix(this, d / determinant, -b / determinant, -c / determinant, a / determinant, (c * f - d * e) / determinant, -(a * f - b * e) / determinant);
39478    };
39479
39480    _proto.multiply = function multiply(matrix) {
39481      var a = this.a,
39482          b = this.b,
39483          c = this.c,
39484          d = this.d,
39485          e = this.e,
39486          f = this.f,
39487          a2 = matrix.a,
39488          b2 = matrix.c,
39489          c2 = matrix.b,
39490          d2 = matrix.d,
39491          e2 = matrix.e,
39492          f2 = matrix.f;
39493      return _setMatrix(this, a2 * a + c2 * c, a2 * b + c2 * d, b2 * a + d2 * c, b2 * b + d2 * d, e + e2 * a + f2 * c, f + e2 * b + f2 * d);
39494    };
39495
39496    _proto.clone = function clone() {
39497      return new Matrix2D(this.a, this.b, this.c, this.d, this.e, this.f);
39498    };
39499
39500    _proto.equals = function equals(matrix) {
39501      var a = this.a,
39502          b = this.b,
39503          c = this.c,
39504          d = this.d,
39505          e = this.e,
39506          f = this.f;
39507      return a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f;
39508    };
39509
39510    _proto.apply = function apply(point, decoratee) {
39511      if (decoratee === void 0) {
39512        decoratee = {};
39513      }
39514
39515      var x = point.x,
39516          y = point.y,
39517          a = this.a,
39518          b = this.b,
39519          c = this.c,
39520          d = this.d,
39521          e = this.e,
39522          f = this.f;
39523      decoratee.x = x * a + y * c + e || 0;
39524      decoratee.y = x * b + y * d + f || 0;
39525      return decoratee;
39526    };
39527
39528    return Matrix2D;
39529  }();
39530  function getGlobalMatrix(element, inverse, adjustGOffset, includeScrollInFixed) {
39531    if (!element || !element.parentNode || (_doc || _setDoc(element)).documentElement === element) {
39532      return new Matrix2D();
39533    }
39534
39535    var zeroScales = _forceNonZeroScale(element),
39536        svg = _svgOwner(element),
39537        temps = svg ? _svgTemps : _divTemps,
39538        container = _placeSiblings(element, adjustGOffset),
39539        b1 = temps[0].getBoundingClientRect(),
39540        b2 = temps[1].getBoundingClientRect(),
39541        b3 = temps[2].getBoundingClientRect(),
39542        parent = container.parentNode,
39543        isFixed = !includeScrollInFixed && _isFixed(element),
39544        m = new Matrix2D((b2.left - b1.left) / 100, (b2.top - b1.top) / 100, (b3.left - b1.left) / 100, (b3.top - b1.top) / 100, b1.left + (isFixed ? 0 : _getDocScrollLeft()), b1.top + (isFixed ? 0 : _getDocScrollTop()));
39545
39546    parent.removeChild(container);
39547
39548    if (zeroScales) {
39549      b1 = zeroScales.length;
39550
39551      while (b1--) {
39552        b2 = zeroScales[b1];
39553        b2.scaleX = b2.scaleY = 0;
39554        b2.renderTransform(1, b2);
39555      }
39556    }
39557
39558    return inverse ? m.inverse() : m;
39559  }
39560
39561  var gsap,
39562      _win$1,
39563      _doc$1,
39564      _docElement$1,
39565      _body$1,
39566      _tempDiv,
39567      _placeholderDiv,
39568      _coreInitted,
39569      _checkPrefix,
39570      _toArray,
39571      _supportsPassive,
39572      _isTouchDevice,
39573      _touchEventLookup,
39574      _isMultiTouching,
39575      _isAndroid,
39576      InertiaPlugin,
39577      _defaultCursor,
39578      _supportsPointer,
39579      _context,
39580      _getStyleSaver,
39581      _dragCount = 0,
39582      _windowExists = function _windowExists() {
39583    return typeof window !== "undefined";
39584  },
39585      _getGSAP = function _getGSAP() {
39586    return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap;
39587  },
39588      _isFunction = function _isFunction(value) {
39589    return typeof value === "function";
39590  },
39591      _isObject = function _isObject(value) {
39592    return typeof value === "object";
39593  },
39594      _isUndefined = function _isUndefined(value) {
39595    return typeof value === "undefined";
39596  },
39597      _emptyFunc = function _emptyFunc() {
39598    return false;
39599  },
39600      _transformProp$1 = "transform",
39601      _transformOriginProp$1 = "transformOrigin",
39602      _round = function _round(value) {
39603    return Math.round(value * 10000) / 10000;
39604  },
39605      _isArray = Array.isArray,
39606      _createElement = function _createElement(type, ns) {
39607    var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type);
39608    return e.style ? e : _doc$1.createElement(type);
39609  },
39610      _RAD2DEG = 180 / Math.PI,
39611      _bigNum = 1e20,
39612      _identityMatrix$1 = new Matrix2D(),
39613      _getTime = Date.now || function () {
39614    return new Date().getTime();
39615  },
39616      _renderQueue = [],
39617      _lookup = {},
39618      _lookupCount = 0,
39619      _clickableTagExp = /^(?:a|input|textarea|button|select)$/i,
39620      _lastDragTime = 0,
39621      _temp1 = {},
39622      _windowProxy = {},
39623      _copy = function _copy(obj, factor) {
39624    var copy = {},
39625        p;
39626
39627    for (p in obj) {
39628      copy[p] = factor ? obj[p] * factor : obj[p];
39629    }
39630
39631    return copy;
39632  },
39633      _extend = function _extend(obj, defaults) {
39634    for (var p in defaults) {
39635      if (!(p in obj)) {
39636        obj[p] = defaults[p];
39637      }
39638    }
39639
39640    return obj;
39641  },
39642      _setTouchActionForAllDescendants = function _setTouchActionForAllDescendants(elements, value) {
39643    var i = elements.length,
39644        children;
39645
39646    while (i--) {
39647      value ? elements[i].style.touchAction = value : elements[i].style.removeProperty("touch-action");
39648      children = elements[i].children;
39649      children && children.length && _setTouchActionForAllDescendants(children, value);
39650    }
39651  },
39652      _renderQueueTick = function _renderQueueTick() {
39653    return _renderQueue.forEach(function (func) {
39654      return func();
39655    });
39656  },
39657      _addToRenderQueue = function _addToRenderQueue(func) {
39658    _renderQueue.push(func);
39659
39660    if (_renderQueue.length === 1) {
39661      gsap.ticker.add(_renderQueueTick);
39662    }
39663  },
39664      _renderQueueTimeout = function _renderQueueTimeout() {
39665    return !_renderQueue.length && gsap.ticker.remove(_renderQueueTick);
39666  },
39667      _removeFromRenderQueue = function _removeFromRenderQueue(func) {
39668    var i = _renderQueue.length;
39669
39670    while (i--) {
39671      if (_renderQueue[i] === func) {
39672        _renderQueue.splice(i, 1);
39673      }
39674    }
39675
39676    gsap.to(_renderQueueTimeout, {
39677      overwrite: true,
39678      delay: 15,
39679      duration: 0,
39680      onComplete: _renderQueueTimeout,
39681      data: "_draggable"
39682    });
39683  },
39684      _setDefaults = function _setDefaults(obj, defaults) {
39685    for (var p in defaults) {
39686      if (!(p in obj)) {
39687        obj[p] = defaults[p];
39688      }
39689    }
39690
39691    return obj;
39692  },
39693      _addListener = function _addListener(element, type, func, capture) {
39694    if (element.addEventListener) {
39695      var touchType = _touchEventLookup[type];
39696      capture = capture || (_supportsPassive ? {
39697        passive: false
39698      } : null);
39699      element.addEventListener(touchType || type, func, capture);
39700      touchType && type !== touchType && element.addEventListener(type, func, capture);
39701    }
39702  },
39703      _removeListener = function _removeListener(element, type, func, capture) {
39704    if (element.removeEventListener) {
39705      var touchType = _touchEventLookup[type];
39706      element.removeEventListener(touchType || type, func, capture);
39707      touchType && type !== touchType && element.removeEventListener(type, func, capture);
39708    }
39709  },
39710      _preventDefault = function _preventDefault(event) {
39711    event.preventDefault && event.preventDefault();
39712    event.preventManipulation && event.preventManipulation();
39713  },
39714      _hasTouchID = function _hasTouchID(list, ID) {
39715    var i = list.length;
39716
39717    while (i--) {
39718      if (list[i].identifier === ID) {
39719        return true;
39720      }
39721    }
39722  },
39723      _onMultiTouchDocumentEnd = function _onMultiTouchDocumentEnd(event) {
39724    _isMultiTouching = event.touches && _dragCount < event.touches.length;
39725
39726    _removeListener(event.target, "touchend", _onMultiTouchDocumentEnd);
39727  },
39728      _onMultiTouchDocument = function _onMultiTouchDocument(event) {
39729    _isMultiTouching = event.touches && _dragCount < event.touches.length;
39730
39731    _addListener(event.target, "touchend", _onMultiTouchDocumentEnd);
39732  },
39733      _getDocScrollTop$1 = function _getDocScrollTop(doc) {
39734    return _win$1.pageYOffset || doc.scrollTop || doc.documentElement.scrollTop || doc.body.scrollTop || 0;
39735  },
39736      _getDocScrollLeft$1 = function _getDocScrollLeft(doc) {
39737    return _win$1.pageXOffset || doc.scrollLeft || doc.documentElement.scrollLeft || doc.body.scrollLeft || 0;
39738  },
39739      _addScrollListener = function _addScrollListener(e, callback) {
39740    _addListener(e, "scroll", callback);
39741
39742    if (!_isRoot(e.parentNode)) {
39743      _addScrollListener(e.parentNode, callback);
39744    }
39745  },
39746      _removeScrollListener = function _removeScrollListener(e, callback) {
39747    _removeListener(e, "scroll", callback);
39748
39749    if (!_isRoot(e.parentNode)) {
39750      _removeScrollListener(e.parentNode, callback);
39751    }
39752  },
39753      _isRoot = function _isRoot(e) {
39754    return !!(!e || e === _docElement$1 || e.nodeType === 9 || e === _doc$1.body || e === _win$1 || !e.nodeType || !e.parentNode);
39755  },
39756      _getMaxScroll = function _getMaxScroll(element, axis) {
39757    var dim = axis === "x" ? "Width" : "Height",
39758        scroll = "scroll" + dim,
39759        client = "client" + dim;
39760    return Math.max(0, _isRoot(element) ? Math.max(_docElement$1[scroll], _body$1[scroll]) - (_win$1["inner" + dim] || _docElement$1[client] || _body$1[client]) : element[scroll] - element[client]);
39761  },
39762      _recordMaxScrolls = function _recordMaxScrolls(e, skipCurrent) {
39763    var x = _getMaxScroll(e, "x"),
39764        y = _getMaxScroll(e, "y");
39765
39766    if (_isRoot(e)) {
39767      e = _windowProxy;
39768    } else {
39769      _recordMaxScrolls(e.parentNode, skipCurrent);
39770    }
39771
39772    e._gsMaxScrollX = x;
39773    e._gsMaxScrollY = y;
39774
39775    if (!skipCurrent) {
39776      e._gsScrollX = e.scrollLeft || 0;
39777      e._gsScrollY = e.scrollTop || 0;
39778    }
39779  },
39780      _setStyle = function _setStyle(element, property, value) {
39781    var style = element.style;
39782
39783    if (!style) {
39784      return;
39785    }
39786
39787    if (_isUndefined(style[property])) {
39788      property = _checkPrefix(property, element) || property;
39789    }
39790
39791    if (value == null) {
39792      style.removeProperty && style.removeProperty(property.replace(/([A-Z])/g, "-$1").toLowerCase());
39793    } else {
39794      style[property] = value;
39795    }
39796  },
39797      _getComputedStyle = function _getComputedStyle(element) {
39798    return _win$1.getComputedStyle(element instanceof Element ? element : element.host || (element.parentNode || {}).host || element);
39799  },
39800      _tempRect = {},
39801      _parseRect = function _parseRect(e) {
39802    if (e === _win$1) {
39803      _tempRect.left = _tempRect.top = 0;
39804      _tempRect.width = _tempRect.right = _docElement$1.clientWidth || e.innerWidth || _body$1.clientWidth || 0;
39805      _tempRect.height = _tempRect.bottom = (e.innerHeight || 0) - 20 < _docElement$1.clientHeight ? _docElement$1.clientHeight : e.innerHeight || _body$1.clientHeight || 0;
39806      return _tempRect;
39807    }
39808
39809    var doc = e.ownerDocument || _doc$1,
39810        r = !_isUndefined(e.pageX) ? {
39811      left: e.pageX - _getDocScrollLeft$1(doc),
39812      top: e.pageY - _getDocScrollTop$1(doc),
39813      right: e.pageX - _getDocScrollLeft$1(doc) + 1,
39814      bottom: e.pageY - _getDocScrollTop$1(doc) + 1
39815    } : !e.nodeType && !_isUndefined(e.left) && !_isUndefined(e.top) ? e : _toArray(e)[0].getBoundingClientRect();
39816
39817    if (_isUndefined(r.right) && !_isUndefined(r.width)) {
39818      r.right = r.left + r.width;
39819      r.bottom = r.top + r.height;
39820    } else if (_isUndefined(r.width)) {
39821      r = {
39822        width: r.right - r.left,
39823        height: r.bottom - r.top,
39824        right: r.right,
39825        left: r.left,
39826        bottom: r.bottom,
39827        top: r.top
39828      };
39829    }
39830
39831    return r;
39832  },
39833      _dispatchEvent = function _dispatchEvent(target, type, callbackName) {
39834    var vars = target.vars,
39835        callback = vars[callbackName],
39836        listeners = target._listeners[type],
39837        result;
39838
39839    if (_isFunction(callback)) {
39840      result = callback.apply(vars.callbackScope || target, vars[callbackName + "Params"] || [target.pointerEvent]);
39841    }
39842
39843    if (listeners && target.dispatchEvent(type) === false) {
39844      result = false;
39845    }
39846
39847    return result;
39848  },
39849      _getBounds = function _getBounds(target, context) {
39850    var e = _toArray(target)[0],
39851        top,
39852        left,
39853        offset;
39854
39855    if (!e.nodeType && e !== _win$1) {
39856      if (!_isUndefined(target.left)) {
39857        offset = {
39858          x: 0,
39859          y: 0
39860        };
39861        return {
39862          left: target.left - offset.x,
39863          top: target.top - offset.y,
39864          width: target.width,
39865          height: target.height
39866        };
39867      }
39868
39869      left = target.min || target.minX || target.minRotation || 0;
39870      top = target.min || target.minY || 0;
39871      return {
39872        left: left,
39873        top: top,
39874        width: (target.max || target.maxX || target.maxRotation || 0) - left,
39875        height: (target.max || target.maxY || 0) - top
39876      };
39877    }
39878
39879    return _getElementBounds(e, context);
39880  },
39881      _point1 = {},
39882      _getElementBounds = function _getElementBounds(element, context) {
39883    context = _toArray(context)[0];
39884    var isSVG = element.getBBox && element.ownerSVGElement,
39885        doc = element.ownerDocument || _doc$1,
39886        left,
39887        right,
39888        top,
39889        bottom,
39890        matrix,
39891        p1,
39892        p2,
39893        p3,
39894        p4,
39895        bbox,
39896        width,
39897        height,
39898        cs;
39899
39900    if (element === _win$1) {
39901      top = _getDocScrollTop$1(doc);
39902      left = _getDocScrollLeft$1(doc);
39903      right = left + (doc.documentElement.clientWidth || element.innerWidth || doc.body.clientWidth || 0);
39904      bottom = top + ((element.innerHeight || 0) - 20 < doc.documentElement.clientHeight ? doc.documentElement.clientHeight : element.innerHeight || doc.body.clientHeight || 0);
39905    } else if (context === _win$1 || _isUndefined(context)) {
39906      return element.getBoundingClientRect();
39907    } else {
39908      left = top = 0;
39909
39910      if (isSVG) {
39911        bbox = element.getBBox();
39912        width = bbox.width;
39913        height = bbox.height;
39914      } else {
39915        if (element.viewBox && (bbox = element.viewBox.baseVal)) {
39916          left = bbox.x || 0;
39917          top = bbox.y || 0;
39918          width = bbox.width;
39919          height = bbox.height;
39920        }
39921
39922        if (!width) {
39923          cs = _getComputedStyle(element);
39924          bbox = cs.boxSizing === "border-box";
39925          width = (parseFloat(cs.width) || element.clientWidth || 0) + (bbox ? 0 : parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth));
39926          height = (parseFloat(cs.height) || element.clientHeight || 0) + (bbox ? 0 : parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth));
39927        }
39928      }
39929
39930      right = width;
39931      bottom = height;
39932    }
39933
39934    if (element === context) {
39935      return {
39936        left: left,
39937        top: top,
39938        width: right - left,
39939        height: bottom - top
39940      };
39941    }
39942
39943    matrix = getGlobalMatrix(context, true).multiply(getGlobalMatrix(element));
39944    p1 = matrix.apply({
39945      x: left,
39946      y: top
39947    });
39948    p2 = matrix.apply({
39949      x: right,
39950      y: top
39951    });
39952    p3 = matrix.apply({
39953      x: right,
39954      y: bottom
39955    });
39956    p4 = matrix.apply({
39957      x: left,
39958      y: bottom
39959    });
39960    left = Math.min(p1.x, p2.x, p3.x, p4.x);
39961    top = Math.min(p1.y, p2.y, p3.y, p4.y);
39962    return {
39963      left: left,
39964      top: top,
39965      width: Math.max(p1.x, p2.x, p3.x, p4.x) - left,
39966      height: Math.max(p1.y, p2.y, p3.y, p4.y) - top
39967    };
39968  },
39969      _parseInertia = function _parseInertia(draggable, snap, max, min, factor, forceZeroVelocity) {
39970    var vars = {},
39971        a,
39972        i,
39973        l;
39974
39975    if (snap) {
39976      if (factor !== 1 && snap instanceof Array) {
39977        vars.end = a = [];
39978        l = snap.length;
39979
39980        if (_isObject(snap[0])) {
39981          for (i = 0; i < l; i++) {
39982            a[i] = _copy(snap[i], factor);
39983          }
39984        } else {
39985          for (i = 0; i < l; i++) {
39986            a[i] = snap[i] * factor;
39987          }
39988        }
39989
39990        max += 1.1;
39991        min -= 1.1;
39992      } else if (_isFunction(snap)) {
39993        vars.end = function (value) {
39994          var result = snap.call(draggable, value),
39995              copy,
39996              p;
39997
39998          if (factor !== 1) {
39999            if (_isObject(result)) {
40000              copy = {};
40001
40002              for (p in result) {
40003                copy[p] = result[p] * factor;
40004              }
40005
40006              result = copy;
40007            } else {
40008              result *= factor;
40009            }
40010          }
40011
40012          return result;
40013        };
40014      } else {
40015        vars.end = snap;
40016      }
40017    }
40018
40019    if (max || max === 0) {
40020      vars.max = max;
40021    }
40022
40023    if (min || min === 0) {
40024      vars.min = min;
40025    }
40026
40027    if (forceZeroVelocity) {
40028      vars.velocity = 0;
40029    }
40030
40031    return vars;
40032  },
40033      _isClickable = function _isClickable(element) {
40034    var data;
40035    return !element || !element.getAttribute || element === _body$1 ? false : (data = element.getAttribute("data-clickable")) === "true" || data !== "false" && (_clickableTagExp.test(element.nodeName + "") || element.getAttribute("contentEditable") === "true") ? true : _isClickable(element.parentNode);
40036  },
40037      _setSelectable = function _setSelectable(elements, selectable) {
40038    var i = elements.length,
40039        e;
40040
40041    while (i--) {
40042      e = elements[i];
40043      e.ondragstart = e.onselectstart = selectable ? null : _emptyFunc;
40044      gsap.set(e, {
40045        lazy: true,
40046        userSelect: selectable ? "text" : "none"
40047      });
40048    }
40049  },
40050      _isFixed$1 = function _isFixed(element) {
40051    if (_getComputedStyle(element).position === "fixed") {
40052      return true;
40053    }
40054
40055    element = element.parentNode;
40056
40057    if (element && element.nodeType === 1) {
40058      return _isFixed(element);
40059    }
40060  },
40061      _supports3D,
40062      _addPaddingBR,
40063      ScrollProxy = function ScrollProxy(element, vars) {
40064    element = gsap.utils.toArray(element)[0];
40065    vars = vars || {};
40066    var content = document.createElement("div"),
40067        style = content.style,
40068        node = element.firstChild,
40069        offsetTop = 0,
40070        offsetLeft = 0,
40071        prevTop = element.scrollTop,
40072        prevLeft = element.scrollLeft,
40073        scrollWidth = element.scrollWidth,
40074        scrollHeight = element.scrollHeight,
40075        extraPadRight = 0,
40076        maxLeft = 0,
40077        maxTop = 0,
40078        elementWidth,
40079        elementHeight,
40080        contentHeight,
40081        nextNode,
40082        transformStart,
40083        transformEnd;
40084
40085    if (_supports3D && vars.force3D !== false) {
40086      transformStart = "translate3d(";
40087      transformEnd = "px,0px)";
40088    } else if (_transformProp$1) {
40089      transformStart = "translate(";
40090      transformEnd = "px)";
40091    }
40092
40093    this.scrollTop = function (value, force) {
40094      if (!arguments.length) {
40095        return -this.top();
40096      }
40097
40098      this.top(-value, force);
40099    };
40100
40101    this.scrollLeft = function (value, force) {
40102      if (!arguments.length) {
40103        return -this.left();
40104      }
40105
40106      this.left(-value, force);
40107    };
40108
40109    this.left = function (value, force) {
40110      if (!arguments.length) {
40111        return -(element.scrollLeft + offsetLeft);
40112      }
40113
40114      var dif = element.scrollLeft - prevLeft,
40115          oldOffset = offsetLeft;
40116
40117      if ((dif > 2 || dif < -2) && !force) {
40118        prevLeft = element.scrollLeft;
40119        gsap.killTweensOf(this, {
40120          left: 1,
40121          scrollLeft: 1
40122        });
40123        this.left(-prevLeft);
40124
40125        if (vars.onKill) {
40126          vars.onKill();
40127        }
40128
40129        return;
40130      }
40131
40132      value = -value;
40133
40134      if (value < 0) {
40135        offsetLeft = value - 0.5 | 0;
40136        value = 0;
40137      } else if (value > maxLeft) {
40138        offsetLeft = value - maxLeft | 0;
40139        value = maxLeft;
40140      } else {
40141        offsetLeft = 0;
40142      }
40143
40144      if (offsetLeft || oldOffset) {
40145        if (!this._skip) {
40146          style[_transformProp$1] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd;
40147        }
40148
40149        if (offsetLeft + extraPadRight >= 0) {
40150          style.paddingRight = offsetLeft + extraPadRight + "px";
40151        }
40152      }
40153
40154      element.scrollLeft = value | 0;
40155      prevLeft = element.scrollLeft;
40156    };
40157
40158    this.top = function (value, force) {
40159      if (!arguments.length) {
40160        return -(element.scrollTop + offsetTop);
40161      }
40162
40163      var dif = element.scrollTop - prevTop,
40164          oldOffset = offsetTop;
40165
40166      if ((dif > 2 || dif < -2) && !force) {
40167        prevTop = element.scrollTop;
40168        gsap.killTweensOf(this, {
40169          top: 1,
40170          scrollTop: 1
40171        });
40172        this.top(-prevTop);
40173
40174        if (vars.onKill) {
40175          vars.onKill();
40176        }
40177
40178        return;
40179      }
40180
40181      value = -value;
40182
40183      if (value < 0) {
40184        offsetTop = value - 0.5 | 0;
40185        value = 0;
40186      } else if (value > maxTop) {
40187        offsetTop = value - maxTop | 0;
40188        value = maxTop;
40189      } else {
40190        offsetTop = 0;
40191      }
40192
40193      if (offsetTop || oldOffset) {
40194        if (!this._skip) {
40195          style[_transformProp$1] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd;
40196        }
40197      }
40198
40199      element.scrollTop = value | 0;
40200      prevTop = element.scrollTop;
40201    };
40202
40203    this.maxScrollTop = function () {
40204      return maxTop;
40205    };
40206
40207    this.maxScrollLeft = function () {
40208      return maxLeft;
40209    };
40210
40211    this.disable = function () {
40212      node = content.firstChild;
40213
40214      while (node) {
40215        nextNode = node.nextSibling;
40216        element.appendChild(node);
40217        node = nextNode;
40218      }
40219
40220      if (element === content.parentNode) {
40221        element.removeChild(content);
40222      }
40223    };
40224
40225    this.enable = function () {
40226      node = element.firstChild;
40227
40228      if (node === content) {
40229        return;
40230      }
40231
40232      while (node) {
40233        nextNode = node.nextSibling;
40234        content.appendChild(node);
40235        node = nextNode;
40236      }
40237
40238      element.appendChild(content);
40239      this.calibrate();
40240    };
40241
40242    this.calibrate = function (force) {
40243      var widthMatches = element.clientWidth === elementWidth,
40244          cs,
40245          x,
40246          y;
40247      prevTop = element.scrollTop;
40248      prevLeft = element.scrollLeft;
40249
40250      if (widthMatches && element.clientHeight === elementHeight && content.offsetHeight === contentHeight && scrollWidth === element.scrollWidth && scrollHeight === element.scrollHeight && !force) {
40251        return;
40252      }
40253
40254      if (offsetTop || offsetLeft) {
40255        x = this.left();
40256        y = this.top();
40257        this.left(-element.scrollLeft);
40258        this.top(-element.scrollTop);
40259      }
40260
40261      cs = _getComputedStyle(element);
40262
40263      if (!widthMatches || force) {
40264        style.display = "block";
40265        style.width = "auto";
40266        style.paddingRight = "0px";
40267        extraPadRight = Math.max(0, element.scrollWidth - element.clientWidth);
40268
40269        if (extraPadRight) {
40270          extraPadRight += parseFloat(cs.paddingLeft) + (_addPaddingBR ? parseFloat(cs.paddingRight) : 0);
40271        }
40272      }
40273
40274      style.display = "inline-block";
40275      style.position = "relative";
40276      style.overflow = "visible";
40277      style.verticalAlign = "top";
40278      style.boxSizing = "content-box";
40279      style.width = "100%";
40280      style.paddingRight = extraPadRight + "px";
40281
40282      if (_addPaddingBR) {
40283        style.paddingBottom = cs.paddingBottom;
40284      }
40285
40286      elementWidth = element.clientWidth;
40287      elementHeight = element.clientHeight;
40288      scrollWidth = element.scrollWidth;
40289      scrollHeight = element.scrollHeight;
40290      maxLeft = element.scrollWidth - elementWidth;
40291      maxTop = element.scrollHeight - elementHeight;
40292      contentHeight = content.offsetHeight;
40293      style.display = "block";
40294
40295      if (x || y) {
40296        this.left(x);
40297        this.top(y);
40298      }
40299    };
40300
40301    this.content = content;
40302    this.element = element;
40303    this._skip = false;
40304    this.enable();
40305  },
40306      _initCore = function _initCore(required) {
40307    if (_windowExists() && document.body) {
40308      var nav = window && window.navigator;
40309      _win$1 = window;
40310      _doc$1 = document;
40311      _docElement$1 = _doc$1.documentElement;
40312      _body$1 = _doc$1.body;
40313      _tempDiv = _createElement("div");
40314      _supportsPointer = !!window.PointerEvent;
40315      _placeholderDiv = _createElement("div");
40316      _placeholderDiv.style.cssText = "visibility:hidden;height:1px;top:-1px;pointer-events:none;position:relative;clear:both;cursor:grab";
40317      _defaultCursor = _placeholderDiv.style.cursor === "grab" ? "grab" : "move";
40318      _isAndroid = nav && nav.userAgent.toLowerCase().indexOf("android") !== -1;
40319      _isTouchDevice = "ontouchstart" in _docElement$1 && "orientation" in _win$1 || nav && (nav.MaxTouchPoints > 0 || nav.msMaxTouchPoints > 0);
40320
40321      _addPaddingBR = function () {
40322        var div = _createElement("div"),
40323            child = _createElement("div"),
40324            childStyle = child.style,
40325            parent = _body$1,
40326            val;
40327
40328        childStyle.display = "inline-block";
40329        childStyle.position = "relative";
40330        div.style.cssText = "width:90px;height:40px;padding:10px;overflow:auto;visibility:hidden";
40331        div.appendChild(child);
40332        parent.appendChild(div);
40333        val = child.offsetHeight + 18 > div.scrollHeight;
40334        parent.removeChild(div);
40335        return val;
40336      }();
40337
40338      _touchEventLookup = function (types) {
40339        var standard = types.split(","),
40340            converted = ("onpointerdown" in _tempDiv ? "pointerdown,pointermove,pointerup,pointercancel" : "onmspointerdown" in _tempDiv ? "MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancel" : types).split(","),
40341            obj = {},
40342            i = 4;
40343
40344        while (--i > -1) {
40345          obj[standard[i]] = converted[i];
40346          obj[converted[i]] = standard[i];
40347        }
40348
40349        try {
40350          _docElement$1.addEventListener("test", null, Object.defineProperty({}, "passive", {
40351            get: function get() {
40352              _supportsPassive = 1;
40353            }
40354          }));
40355        } catch (e) {}
40356
40357        return obj;
40358      }("touchstart,touchmove,touchend,touchcancel");
40359
40360      _addListener(_doc$1, "touchcancel", _emptyFunc);
40361
40362      _addListener(_win$1, "touchmove", _emptyFunc);
40363
40364      _body$1 && _body$1.addEventListener("touchstart", _emptyFunc);
40365
40366      _addListener(_doc$1, "contextmenu", function () {
40367        for (var p in _lookup) {
40368          if (_lookup[p].isPressed) {
40369            _lookup[p].endDrag();
40370          }
40371        }
40372      });
40373
40374      gsap = _coreInitted = _getGSAP();
40375    }
40376
40377    if (gsap) {
40378      InertiaPlugin = gsap.plugins.inertia;
40379
40380      _context = gsap.core.context || function () {};
40381
40382      _checkPrefix = gsap.utils.checkPrefix;
40383      _transformProp$1 = _checkPrefix(_transformProp$1);
40384      _transformOriginProp$1 = _checkPrefix(_transformOriginProp$1);
40385      _toArray = gsap.utils.toArray;
40386      _getStyleSaver = gsap.core.getStyleSaver;
40387      _supports3D = !!_checkPrefix("perspective");
40388    } else if (required) {
40389      console.warn("Please gsap.registerPlugin(Draggable)");
40390    }
40391  };
40392
40393  var EventDispatcher = function () {
40394    function EventDispatcher(target) {
40395      this._listeners = {};
40396      this.target = target || this;
40397    }
40398
40399    var _proto = EventDispatcher.prototype;
40400
40401    _proto.addEventListener = function addEventListener(type, callback) {
40402      var list = this._listeners[type] || (this._listeners[type] = []);
40403
40404      if (!~list.indexOf(callback)) {
40405        list.push(callback);
40406      }
40407    };
40408
40409    _proto.removeEventListener = function removeEventListener(type, callback) {
40410      var list = this._listeners[type],
40411          i = list && list.indexOf(callback);
40412      i >= 0 && list.splice(i, 1);
40413    };
40414
40415    _proto.dispatchEvent = function dispatchEvent(type) {
40416      var _this = this;
40417
40418      var result;
40419      (this._listeners[type] || []).forEach(function (callback) {
40420        return callback.call(_this, {
40421          type: type,
40422          target: _this.target
40423        }) === false && (result = false);
40424      });
40425      return result;
40426    };
40427
40428    return EventDispatcher;
40429  }();
40430
40431  var Draggable = function (_EventDispatcher) {
40432    _inheritsLoose(Draggable, _EventDispatcher);
40433
40434    function Draggable(target, vars) {
40435      var _this2;
40436
40437      _this2 = _EventDispatcher.call(this) || this;
40438      _coreInitted || _initCore(1);
40439      target = _toArray(target)[0];
40440      _this2.styles = _getStyleSaver && _getStyleSaver(target, "transform,left,top");
40441
40442      if (!InertiaPlugin) {
40443        InertiaPlugin = gsap.plugins.inertia;
40444      }
40445
40446      _this2.vars = vars = _copy(vars || {});
40447      _this2.target = target;
40448      _this2.x = _this2.y = _this2.rotation = 0;
40449      _this2.dragResistance = parseFloat(vars.dragResistance) || 0;
40450      _this2.edgeResistance = isNaN(vars.edgeResistance) ? 1 : parseFloat(vars.edgeResistance) || 0;
40451      _this2.lockAxis = vars.lockAxis;
40452      _this2.autoScroll = vars.autoScroll || 0;
40453      _this2.lockedAxis = null;
40454      _this2.allowEventDefault = !!vars.allowEventDefault;
40455      gsap.getProperty(target, "x");
40456
40457      var type = (vars.type || "x,y").toLowerCase(),
40458          xyMode = ~type.indexOf("x") || ~type.indexOf("y"),
40459          rotationMode = type.indexOf("rotation") !== -1,
40460          xProp = rotationMode ? "rotation" : xyMode ? "x" : "left",
40461          yProp = xyMode ? "y" : "top",
40462          allowX = !!(~type.indexOf("x") || ~type.indexOf("left") || type === "scroll"),
40463          allowY = !!(~type.indexOf("y") || ~type.indexOf("top") || type === "scroll"),
40464          minimumMovement = vars.minimumMovement || 2,
40465          self = _assertThisInitialized(_this2),
40466          triggers = _toArray(vars.trigger || vars.handle || target),
40467          killProps = {},
40468          dragEndTime = 0,
40469          checkAutoScrollBounds = false,
40470          autoScrollMarginTop = vars.autoScrollMarginTop || 40,
40471          autoScrollMarginRight = vars.autoScrollMarginRight || 40,
40472          autoScrollMarginBottom = vars.autoScrollMarginBottom || 40,
40473          autoScrollMarginLeft = vars.autoScrollMarginLeft || 40,
40474          isClickable = vars.clickableTest || _isClickable,
40475          clickTime = 0,
40476          gsCache = target._gsap || gsap.core.getCache(target),
40477          isFixed = _isFixed$1(target),
40478          getPropAsNum = function getPropAsNum(property, unit) {
40479        return parseFloat(gsCache.get(target, property, unit));
40480      },
40481          ownerDoc = target.ownerDocument || _doc$1,
40482          enabled,
40483          scrollProxy,
40484          startPointerX,
40485          startPointerY,
40486          startElementX,
40487          startElementY,
40488          hasBounds,
40489          hasDragCallback,
40490          hasMoveCallback,
40491          maxX,
40492          minX,
40493          maxY,
40494          minY,
40495          touch,
40496          touchID,
40497          rotationOrigin,
40498          dirty,
40499          old,
40500          snapX,
40501          snapY,
40502          snapXY,
40503          isClicking,
40504          touchEventTarget,
40505          matrix,
40506          interrupted,
40507          allowNativeTouchScrolling,
40508          touchDragAxis,
40509          isDispatching,
40510          clickDispatch,
40511          trustedClickDispatch,
40512          isPreventingDefault,
40513          innerMatrix,
40514          dragged,
40515          onContextMenu = function onContextMenu(e) {
40516        _preventDefault(e);
40517
40518        e.stopImmediatePropagation && e.stopImmediatePropagation();
40519        return false;
40520      },
40521          render = function render(suppressEvents) {
40522        if (self.autoScroll && self.isDragging && (checkAutoScrollBounds || dirty)) {
40523          var e = target,
40524              autoScrollFactor = self.autoScroll * 15,
40525              parent,
40526              isRoot,
40527              rect,
40528              pointerX,
40529              pointerY,
40530              changeX,
40531              changeY,
40532              gap;
40533          checkAutoScrollBounds = false;
40534          _windowProxy.scrollTop = _win$1.pageYOffset != null ? _win$1.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop;
40535          _windowProxy.scrollLeft = _win$1.pageXOffset != null ? _win$1.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft;
40536          pointerX = self.pointerX - _windowProxy.scrollLeft;
40537          pointerY = self.pointerY - _windowProxy.scrollTop;
40538
40539          while (e && !isRoot) {
40540            isRoot = _isRoot(e.parentNode);
40541            parent = isRoot ? _windowProxy : e.parentNode;
40542            rect = isRoot ? {
40543              bottom: Math.max(_docElement$1.clientHeight, _win$1.innerHeight || 0),
40544              right: Math.max(_docElement$1.clientWidth, _win$1.innerWidth || 0),
40545              left: 0,
40546              top: 0
40547            } : parent.getBoundingClientRect();
40548            changeX = changeY = 0;
40549
40550            if (allowY) {
40551              gap = parent._gsMaxScrollY - parent.scrollTop;
40552
40553              if (gap < 0) {
40554                changeY = gap;
40555              } else if (pointerY > rect.bottom - autoScrollMarginBottom && gap) {
40556                checkAutoScrollBounds = true;
40557                changeY = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.bottom - pointerY) / autoScrollMarginBottom) | 0);
40558              } else if (pointerY < rect.top + autoScrollMarginTop && parent.scrollTop) {
40559                checkAutoScrollBounds = true;
40560                changeY = -Math.min(parent.scrollTop, autoScrollFactor * (1 - Math.max(0, pointerY - rect.top) / autoScrollMarginTop) | 0);
40561              }
40562
40563              if (changeY) {
40564                parent.scrollTop += changeY;
40565              }
40566            }
40567
40568            if (allowX) {
40569              gap = parent._gsMaxScrollX - parent.scrollLeft;
40570
40571              if (gap < 0) {
40572                changeX = gap;
40573              } else if (pointerX > rect.right - autoScrollMarginRight && gap) {
40574                checkAutoScrollBounds = true;
40575                changeX = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.right - pointerX) / autoScrollMarginRight) | 0);
40576              } else if (pointerX < rect.left + autoScrollMarginLeft && parent.scrollLeft) {
40577                checkAutoScrollBounds = true;
40578                changeX = -Math.min(parent.scrollLeft, autoScrollFactor * (1 - Math.max(0, pointerX - rect.left) / autoScrollMarginLeft) | 0);
40579              }
40580
40581              if (changeX) {
40582                parent.scrollLeft += changeX;
40583              }
40584            }
40585
40586            if (isRoot && (changeX || changeY)) {
40587              _win$1.scrollTo(parent.scrollLeft, parent.scrollTop);
40588
40589              setPointerPosition(self.pointerX + changeX, self.pointerY + changeY);
40590            }
40591
40592            e = parent;
40593          }
40594        }
40595
40596        if (dirty) {
40597          var x = self.x,
40598              y = self.y;
40599
40600          if (rotationMode) {
40601            self.deltaX = x - parseFloat(gsCache.rotation);
40602            self.rotation = x;
40603            gsCache.rotation = x + "deg";
40604            gsCache.renderTransform(1, gsCache);
40605          } else {
40606            if (scrollProxy) {
40607              if (allowY) {
40608                self.deltaY = y - scrollProxy.top();
40609                scrollProxy.top(y);
40610              }
40611
40612              if (allowX) {
40613                self.deltaX = x - scrollProxy.left();
40614                scrollProxy.left(x);
40615              }
40616            } else if (xyMode) {
40617              if (allowY) {
40618                self.deltaY = y - parseFloat(gsCache.y);
40619                gsCache.y = y + "px";
40620              }
40621
40622              if (allowX) {
40623                self.deltaX = x - parseFloat(gsCache.x);
40624                gsCache.x = x + "px";
40625              }
40626
40627              gsCache.renderTransform(1, gsCache);
40628            } else {
40629              if (allowY) {
40630                self.deltaY = y - parseFloat(target.style.top || 0);
40631                target.style.top = y + "px";
40632              }
40633
40634              if (allowX) {
40635                self.deltaX = x - parseFloat(target.style.left || 0);
40636                target.style.left = x + "px";
40637              }
40638            }
40639          }
40640
40641          if (hasDragCallback && !suppressEvents && !isDispatching) {
40642            isDispatching = true;
40643
40644            if (_dispatchEvent(self, "drag", "onDrag") === false) {
40645              if (allowX) {
40646                self.x -= self.deltaX;
40647              }
40648
40649              if (allowY) {
40650                self.y -= self.deltaY;
40651              }
40652
40653              render(true);
40654            }
40655
40656            isDispatching = false;
40657          }
40658        }
40659
40660        dirty = false;
40661      },
40662          syncXY = function syncXY(skipOnUpdate, skipSnap) {
40663        var x = self.x,
40664            y = self.y,
40665            snappedValue,
40666            cs;
40667
40668        if (!target._gsap) {
40669          gsCache = gsap.core.getCache(target);
40670        }
40671
40672        gsCache.uncache && gsap.getProperty(target, "x");
40673
40674        if (xyMode) {
40675          self.x = parseFloat(gsCache.x);
40676          self.y = parseFloat(gsCache.y);
40677        } else if (rotationMode) {
40678          self.x = self.rotation = 
40678parseFloat(gsCache.rotation
vendor: 18,327 bytes, lines 40678-41228
40678);
40679        } else if (scrollProxy) {
40680          self.y = scrollProxy.top();
40681          self.x = scrollProxy.left();
40682        } else {
40683          self.y = parseFloat(target.style.top || (cs = _getComputedStyle(target)) && cs.top) || 0;
40684          self.x = parseFloat(target.style.left || (cs || {}).left) || 0;
40685        }
40686
40687        if ((snapX || snapY || snapXY) && !skipSnap && (self.isDragging || self.isThrowing)) {
40688          if (snapXY) {
40689            _temp1.x = self.x;
40690            _temp1.y = self.y;
40691            snappedValue = snapXY(_temp1);
40692
40693            if (snappedValue.x !== self.x) {
40694              self.x = snappedValue.x;
40695              dirty = true;
40696            }
40697
40698            if (snappedValue.y !== self.y) {
40699              self.y = snappedValue.y;
40700              dirty = true;
40701            }
40702          }
40703
40704          if (snapX) {
40705            snappedValue = snapX(self.x);
40706
40707            if (snappedValue !== self.x) {
40708              self.x = snappedValue;
40709
40710              if (rotationMode) {
40711                self.rotation = snappedValue;
40712              }
40713
40714              dirty = true;
40715            }
40716          }
40717
40718          if (snapY) {
40719            snappedValue = snapY(self.y);
40720
40721            if (snappedValue !== self.y) {
40722              self.y = snappedValue;
40723            }
40724
40725            dirty = true;
40726          }
40727        }
40728
40729        dirty && render(true);
40730
40731        if (!skipOnUpdate) {
40732          self.deltaX = self.x - x;
40733          self.deltaY = self.y - y;
40734
40735          _dispatchEvent(self, "throwupdate", "onThrowUpdate");
40736        }
40737      },
40738          buildSnapFunc = function buildSnapFunc(snap, min, max, factor) {
40739        if (min == null) {
40740          min = -_bigNum;
40741        }
40742
40743        if (max == null) {
40744          max = _bigNum;
40745        }
40746
40747        if (_isFunction(snap)) {
40748          return function (n) {
40749            var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance;
40750            return snap.call(self, (n > max ? max + (n - max) * edgeTolerance : n < min ? min + (n - min) * edgeTolerance : n) * factor) * factor;
40751          };
40752        }
40753
40754        if (_isArray(snap)) {
40755          return function (n) {
40756            var i = snap.length,
40757                closest = 0,
40758                absDif = _bigNum,
40759                val,
40760                dif;
40761
40762            while (--i > -1) {
40763              val = snap[i];
40764              dif = val - n;
40765
40766              if (dif < 0) {
40767                dif = -dif;
40768              }
40769
40770              if (dif < absDif && val >= min && val <= max) {
40771                closest = i;
40772                absDif = dif;
40773              }
40774            }
40775
40776            return snap[closest];
40777          };
40778        }
40779
40780        return isNaN(snap) ? function (n) {
40781          return n;
40782        } : function () {
40783          return snap * factor;
40784        };
40785      },
40786          buildPointSnapFunc = function buildPointSnapFunc(snap, minX, maxX, minY, maxY, radius, factor) {
40787        radius = radius && radius < _bigNum ? radius * radius : _bigNum;
40788
40789        if (_isFunction(snap)) {
40790          return function (point) {
40791            var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance,
40792                x = point.x,
40793                y = point.y,
40794                result,
40795                dx,
40796                dy;
40797            point.x = x = x > maxX ? maxX + (x - maxX) * edgeTolerance : x < minX ? minX + (x - minX) * edgeTolerance : x;
40798            point.y = y = y > maxY ? maxY + (y - maxY) * edgeTolerance : y < minY ? minY + (y - minY) * edgeTolerance : y;
40799            result = snap.call(self, point);
40800
40801            if (result !== point) {
40802              point.x = result.x;
40803              point.y = result.y;
40804            }
40805
40806            if (factor !== 1) {
40807              point.x *= factor;
40808              point.y *= factor;
40809            }
40810
40811            if (radius < _bigNum) {
40812              dx = point.x - x;
40813              dy = point.y - y;
40814
40815              if (dx * dx + dy * dy > radius) {
40816                point.x = x;
40817                point.y = y;
40818              }
40819            }
40820
40821            return point;
40822          };
40823        }
40824
40825        if (_isArray(snap)) {
40826          return function (p) {
40827            var i = snap.length,
40828                closest = 0,
40829                minDist = _bigNum,
40830                x,
40831                y,
40832                point,
40833                dist;
40834
40835            while (--i > -1) {
40836              point = snap[i];
40837              x = point.x - p.x;
40838              y = point.y - p.y;
40839              dist = x * x + y * y;
40840
40841              if (dist < minDist) {
40842                closest = i;
40843                minDist = dist;
40844              }
40845            }
40846
40847            return minDist <= radius ? snap[closest] : p;
40848          };
40849        }
40850
40851        return function (n) {
40852          return n;
40853        };
40854      },
40855          calculateBounds = function calculateBounds() {
40856        var bounds, targetBounds, snap, snapIsRaw;
40857        hasBounds = false;
40858
40859        if (scrollProxy) {
40860          scrollProxy.calibrate();
40861          self.minX = minX = -scrollProxy.maxScrollLeft();
40862          self.minY = minY = -scrollProxy.maxScrollTop();
40863          self.maxX = maxX = self.maxY = maxY = 0;
40864          hasBounds = true;
40865        } else if (!!vars.bounds) {
40866          bounds = _getBounds(vars.bounds, target.parentNode);
40867
40868          if (rotationMode) {
40869            self.minX = minX = bounds.left;
40870            self.maxX = maxX = bounds.left + bounds.width;
40871            self.minY = minY = self.maxY = maxY = 0;
40872          } else if (!_isUndefined(vars.bounds.maxX) || !_isUndefined(vars.bounds.maxY)) {
40873            bounds = vars.bounds;
40874            self.minX = minX = bounds.minX;
40875            self.minY = minY = bounds.minY;
40876            self.maxX = maxX = bounds.maxX;
40877            self.maxY = maxY = bounds.maxY;
40878          } else {
40879            targetBounds = _getBounds(target, target.parentNode);
40880            self.minX = minX = Math.round(getPropAsNum(xProp, "px") + bounds.left - targetBounds.left);
40881            self.minY = minY = Math.round(getPropAsNum(yProp, "px") + bounds.top - targetBounds.top);
40882            self.maxX = maxX = Math.round(minX + (bounds.width - targetBounds.width));
40883            self.maxY = maxY = Math.round(minY + (bounds.height - targetBounds.height));
40884          }
40885
40886          if (minX > maxX) {
40887            self.minX = maxX;
40888            self.maxX = maxX = minX;
40889            minX = self.minX;
40890          }
40891
40892          if (minY > maxY) {
40893            self.minY = maxY;
40894            self.maxY = maxY = minY;
40895            minY = self.minY;
40896          }
40897
40898          if (rotationMode) {
40899            self.minRotation = minX;
40900            self.maxRotation = maxX;
40901          }
40902
40903          hasBounds = true;
40904        }
40905
40906        if (vars.liveSnap) {
40907          snap = vars.liveSnap === true ? vars.snap || {} : vars.liveSnap;
40908          snapIsRaw = _isArray(snap) || _isFunction(snap);
40909
40910          if (rotationMode) {
40911            snapX = buildSnapFunc(snapIsRaw ? snap : snap.rotation, minX, maxX, 1);
40912            snapY = null;
40913          } else {
40914            if (snap.points) {
40915              snapXY = buildPointSnapFunc(snapIsRaw ? snap : snap.points, minX, maxX, minY, maxY, snap.radius, scrollProxy ? -1 : 1);
40916            } else {
40917              if (allowX) {
40918                snapX = buildSnapFunc(snapIsRaw ? snap : snap.x || snap.left || snap.scrollLeft, minX, maxX, scrollProxy ? -1 : 1);
40919              }
40920
40921              if (allowY) {
40922                snapY = buildSnapFunc(snapIsRaw ? snap : snap.y || snap.top || snap.scrollTop, minY, maxY, scrollProxy ? -1 : 1);
40923              }
40924            }
40925          }
40926        }
40927      },
40928          onThrowComplete = function onThrowComplete() {
40929        self.isThrowing = false;
40930
40931        _dispatchEvent(self, "throwcomplete", "onThrowComplete");
40932      },
40933          onThrowInterrupt = function onThrowInterrupt() {
40934        self.isThrowing = false;
40935      },
40936          animate = function animate(inertia, forceZeroVelocity) {
40937        var snap, snapIsRaw, tween, overshootTolerance;
40938
40939        if (inertia && InertiaPlugin) {
40940          if (inertia === true) {
40941            snap = vars.snap || vars.liveSnap || {};
40942            snapIsRaw = _isArray(snap) || _isFunction(snap);
40943            inertia = {
40944              resistance: (vars.throwResistance || vars.resistance || 1000) / (rotationMode ? 10 : 1)
40945            };
40946
40947            if (rotationMode) {
40948              inertia.rotation = _parseInertia(self, snapIsRaw ? snap : snap.rotation, maxX, minX, 1, forceZeroVelocity);
40949            } else {
40950              if (allowX) {
40951                inertia[xProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.x || snap.left, maxX, minX, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "x");
40952              }
40953
40954              if (allowY) {
40955                inertia[yProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.y || snap.top, maxY, minY, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "y");
40956              }
40957
40958              if (snap.points || _isArray(snap) && _isObject(snap[0])) {
40959                inertia.linkedProps = xProp + "," + yProp;
40960                inertia.radius = snap.radius;
40961              }
40962            }
40963          }
40964
40965          self.isThrowing = true;
40966          overshootTolerance = !isNaN(vars.overshootTolerance) ? vars.overshootTolerance : vars.edgeResistance === 1 ? 0 : 1 - self.edgeResistance + 0.2;
40967
40968          if (!inertia.duration) {
40969            inertia.duration = {
40970              max: Math.max(vars.minDuration || 0, "maxDuration" in vars ? vars.maxDuration : 2),
40971              min: !isNaN(vars.minDuration) ? vars.minDuration : overshootTolerance === 0 || _isObject(inertia) && inertia.resistance > 1000 ? 0 : 0.5,
40972              overshoot: overshootTolerance
40973            };
40974          }
40975
40976          self.tween = tween = gsap.to(scrollProxy || target, {
40977            inertia: inertia,
40978            data: "_draggable",
40979            inherit: false,
40980            onComplete: onThrowComplete,
40981            onInterrupt: onThrowInterrupt,
40982            onUpdate: vars.fastMode ? _dispatchEvent : syncXY,
40983            onUpdateParams: vars.fastMode ? [self, "onthrowupdate", "onThrowUpdate"] : snap && snap.radius ? [false, true] : []
40984          });
40985
40986          if (!vars.fastMode) {
40987            if (scrollProxy) {
40988              scrollProxy._skip = true;
40989            }
40990
40991            tween.render(1e9, true, true);
40992            syncXY(true, true);
40993            self.endX = self.x;
40994            self.endY = self.y;
40995
40996            if (rotationMode) {
40997              self.endRotation = self.x;
40998            }
40999
41000            tween.play(0);
41001            syncXY(true, true);
41002
41003            if (scrollProxy) {
41004              scrollProxy._skip = false;
41005            }
41006          }
41007        } else if (hasBounds) {
41008          self.applyBounds();
41009        }
41010      },
41011          updateMatrix = function updateMatrix(shiftStart) {
41012        var start = matrix,
41013            p;
41014        matrix = getGlobalMatrix(target.parentNode, true);
41015
41016        if (shiftStart && self.isPressed && !matrix.equals(start || new Matrix2D())) {
41017          p = start.inverse().apply({
41018            x: startPointerX,
41019            y: startPointerY
41020          });
41021          matrix.apply(p, p);
41022          startPointerX = p.x;
41023          startPointerY = p.y;
41024        }
41025
41026        if (matrix.equals(_identityMatrix$1)) {
41027          matrix = null;
41028        }
41029      },
41030          recordStartPositions = function recordStartPositions() {
41031        var edgeTolerance = 1 - self.edgeResistance,
41032            offsetX = isFixed ? _getDocScrollLeft$1(ownerDoc) : 0,
41033            offsetY = isFixed ? _getDocScrollTop$1(ownerDoc) : 0,
41034            parsedOrigin,
41035            x,
41036            y;
41037
41038        if (xyMode) {
41039          gsCache.x = getPropAsNum(xProp, "px") + "px";
41040          gsCache.y = getPropAsNum(yProp, "px") + "px";
41041          gsCache.renderTransform();
41042        }
41043
41044        updateMatrix(false);
41045        _point1.x = self.pointerX - offsetX;
41046        _point1.y = self.pointerY - offsetY;
41047        matrix && matrix.apply(_point1, _point1);
41048        startPointerX = _point1.x;
41049        startPointerY = _point1.y;
41050
41051        if (dirty) {
41052          setPointerPosition(self.pointerX, self.pointerY);
41053          render(true);
41054        }
41055
41056        innerMatrix = getGlobalMatrix(target);
41057
41058        if (scrollProxy) {
41059          calculateBounds();
41060          startElementY = scrollProxy.top();
41061          startElementX = scrollProxy.left();
41062        } else {
41063          if (isTweening()) {
41064            syncXY(true, true);
41065            calculateBounds();
41066          } else {
41067            self.applyBounds();
41068          }
41069
41070          if (rotationMode) {
41071            parsedOrigin = target.ownerSVGElement ? [gsCache.xOrigin - target.getBBox().x, gsCache.yOrigin - target.getBBox().y] : (_getComputedStyle(target)[_transformOriginProp$1] || "0 0").split(" ");
41072            rotationOrigin = self.rotationOrigin = getGlobalMatrix(target).apply({
41073              x: parseFloat(parsedOrigin[0]) || 0,
41074              y: parseFloat(parsedOrigin[1]) || 0
41075            });
41076            syncXY(true, true);
41077            x = self.pointerX - rotationOrigin.x - offsetX;
41078            y = rotationOrigin.y - self.pointerY + offsetY;
41079            startElementX = self.x;
41080            startElementY = self.y = Math.atan2(y, x) * _RAD2DEG;
41081          } else {
41082            startElementY = getPropAsNum(yProp, "px");
41083            startElementX = getPropAsNum(xProp, "px");
41084          }
41085        }
41086
41087        if (hasBounds && edgeTolerance) {
41088          if (startElementX > maxX) {
41089            startElementX = maxX + (startElementX - maxX) / edgeTolerance;
41090          } else if (startElementX < minX) {
41091            startElementX = minX - (minX - startElementX) / edgeTolerance;
41092          }
41093
41094          if (!rotationMode) {
41095            if (startElementY > maxY) {
41096              startElementY = maxY + (startElementY - maxY) / edgeTolerance;
41097            } else if (startElementY < minY) {
41098              startElementY = minY - (minY - startElementY) / edgeTolerance;
41099            }
41100          }
41101        }
41102
41103        self.startX = startElementX = _round(startElementX);
41104        self.startY = startElementY = _round(startElementY);
41105      },
41106          isTweening = function isTweening() {
41107        return self.tween && self.tween.isActive();
41108      },
41109          removePlaceholder = function removePlaceholder() {
41110        if (_placeholderDiv.parentNode && !isTweening() && !self.isDragging) {
41111          _placeholderDiv.parentNode.removeChild(_placeholderDiv);
41112        }
41113      },
41114          onPress = function onPress(e, force) {
41115        var i;
41116
41117        if (!enabled || self.isPressed || !e || (e.type === "mousedown" || e.type === "pointerdown") && !force && _getTime() - clickTime < 30 && _touchEventLookup[self.pointerEvent.type]) {
41118          isPreventingDefault && e && enabled && _preventDefault(e);
41119          return;
41120        }
41121
41122        interrupted = isTweening();
41123        dragged = false;
41124        self.pointerEvent = e;
41125
41126        if (_touchEventLookup[e.type]) {
41127          touchEventTarget = ~e.type.indexOf("touch") ? e.currentTarget || e.target : ownerDoc;
41128
41129          _addListener(touchEventTarget, "touchend", onRelease);
41130
41131          _addListener(touchEventTarget, "touchmove", onMove);
41132
41133          _addListener(touchEventTarget, "touchcancel", onRelease);
41134
41135          _addListener(ownerDoc, "touchstart", _onMultiTouchDocument);
41136        } else {
41137          touchEventTarget = null;
41138
41139          _addListener(ownerDoc, "mousemove", onMove);
41140        }
41141
41142        touchDragAxis = null;
41143
41144        if (!_supportsPointer || !touchEventTarget) {
41145          _addListener(ownerDoc, "mouseup", onRelease);
41146
41147          e && e.target && _addListener(e.target, "mouseup", onRelease);
41148        }
41149
41150        isClicking = isClickable.call(self, e.target) && vars.dragClickables === false && !force;
41151
41152        if (isClicking) {
41153          _addListener(e.target, "change", onRelease);
41154
41155          _dispatchEvent(self, "pressInit", "onPressInit");
41156
41157          _dispatchEvent(self, "press", "onPress");
41158
41159          _setSelectable(triggers, true);
41160
41161          isPreventingDefault = false;
41162          return;
41163        }
41164
41165        allowNativeTouchScrolling = !touchEventTarget || allowX === allowY || self.vars.allowNativeTouchScrolling === false || self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2) ? false : allowX ? "y" : "x";
41166        isPreventingDefault = !allowNativeTouchScrolling && !self.allowEventDefault;
41167
41168        if (isPreventingDefault) {
41169          _preventDefault(e);
41170
41171          _addListener(_win$1, "touchforcechange", _preventDefault);
41172        }
41173
41174        if (e.changedTouches) {
41175          e = touch = e.changedTouches[0];
41176          touchID = e.identifier;
41177        } else if (e.pointerId) {
41178          touchID = e.pointerId;
41179        } else {
41180          touch = touchID = null;
41181        }
41182
41183        _dragCount++;
41184
41185        _addToRenderQueue(render);
41186
41187        startPointerY = self.pointerY = e.pageY;
41188        startPointerX = self.pointerX = e.pageX;
41189
41190        _dispatchEvent(self, "pressInit", "onPressInit");
41191
41192        if (allowNativeTouchScrolling || self.autoScroll) {
41193          _recordMaxScrolls(target.parentNode);
41194        }
41195
41196        if (target.parentNode && self.autoScroll && !scrollProxy && !rotationMode && target.parentNode._gsMaxScrollX && !_placeholderDiv.parentNode && !target.getBBox) {
41197          _placeholderDiv.style.width = target.parentNode.scrollWidth + "px";
41198          target.parentNode.appendChild(_placeholderDiv);
41199        }
41200
41201        recordStartPositions();
41202        self.tween && self.tween.kill();
41203        self.isThrowing = false;
41204        gsap.killTweensOf(scrollProxy || target, killProps, true);
41205        scrollProxy && gsap.killTweensOf(target, {
41206          scrollTo: 1
41207        }, true);
41208        self.tween = self.lockedAxis = null;
41209
41210        if (vars.zIndexBoost || !rotationMode && !scrollProxy && vars.zIndexBoost !== false) {
41211          target.style.zIndex = Draggable.zIndex++;
41212        }
41213
41214        self.isPressed = true;
41215        hasDragCallback = !!(vars.onDrag || self._listeners.drag);
41216        hasMoveCallback = !!(vars.onMove || self._listeners.move);
41217
41218        if (vars.cursor !== false || vars.activeCursor) {
41219          i = triggers.length;
41220
41221          while (--i > -1) {
41222            gsap.set(triggers[i], {
41223              cursor: vars.activeCursor || vars.cursor || (_defaultCursor === "grab" ? "grabbing" : _defaultCursor)
41224            });
41225          }
41226        }
41227
41228        _dispatchEvent(self, "press", "onPress");
vendor: 2,447 bytes, lines 41229-41296
41229      },
41230          onMove = function onMove(e) {
41231        var originalEvent = e,
41232            touches,
41233            pointerX,
41234            pointerY,
41235            i,
41236            dx,
41237            dy;
41238
41239        if (!enabled || _isMultiTouching || !self.isPressed || !e) {
41240          isPreventingDefault && e && enabled && _preventDefault(e);
41241          return;
41242        }
41243
41244        self.pointerEvent = e;
41245        touches = e.changedTouches;
41246
41247        if (touches) {
41248          e = touches[0];
41249
41250          if (e !== touch && e.identifier !== touchID) {
41251            i = touches.length;
41252
41253            while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {}
41254
41255            if (i < 0) {
41256              return;
41257            }
41258          }
41259        } else if (e.pointerId && touchID && e.pointerId !== touchID) {
41260          return;
41261        }
41262
41263        if (touchEventTarget && allowNativeTouchScrolling && !touchDragAxis) {
41264          _point1.x = e.pageX - (isFixed ? _getDocScrollLeft$1(ownerDoc) : 0);
41265          _point1.y = e.pageY - (isFixed ? _getDocScrollTop$1(ownerDoc) : 0);
41266          matrix && matrix.apply(_point1, _point1);
41267          pointerX = _point1.x;
41268          pointerY = _point1.y;
41269          dx = Math.abs(pointerX - startPointerX);
41270          dy = Math.abs(pointerY - startPointerY);
41271
41272          if (dx !== dy && (dx > minimumMovement || dy > minimumMovement) || _isAndroid && allowNativeTouchScrolling === touchDragAxis) {
41273            touchDragAxis = dx > dy && allowX ? "x" : "y";
41274
41275            if (allowNativeTouchScrolling && touchDragAxis !== allowNativeTouchScrolling) {
41276              _addListener(_win$1, "touchforcechange", _preventDefault);
41277            }
41278
41279            if (self.vars.lockAxisOnTouchScroll !== false && allowX && allowY) {
41280              self.lockedAxis = touchDragAxis === "x" ? "y" : "x";
41281              _isFunction(self.vars.onLockAxis) && self.vars.onLockAxis.call(self, originalEvent);
41282            }
41283
41284            if (_isAndroid && allowNativeTouchScrolling === touchDragAxis) {
41285              onRelease(originalEvent);
41286              return;
41287            }
41288          }
41289        }
41290
41291        if (!self.allowEventDefault && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling !== touchDragAxis) && originalEvent.cancelable !== false) {
41292          _preventDefault(originalEvent);
41293
41294          isPreventingDefault = true;
41295        } else if (isPreventingDefault) {
41296          isPreventingDefault = false;
vendor: 3,917 bytes, lines 41297-41425
41297        }
41298
41299        if (self.autoScroll) {
41300          checkAutoScrollBounds = true;
41301        }
41302
41303        setPointerPosition(e.pageX, e.pageY, hasMoveCallback);
41304      },
41305          setPointerPosition = function setPointerPosition(pointerX, pointerY, invokeOnMove) {
41306        var dragTolerance = 1 - self.dragResistance,
41307            edgeTolerance = 1 - self.edgeResistance,
41308            prevPointerX = self.pointerX,
41309            prevPointerY = self.pointerY,
41310            prevStartElementY = startElementY,
41311            prevX = self.x,
41312            prevY = self.y,
41313            prevEndX = self.endX,
41314            prevEndY = self.endY,
41315            prevEndRotation = self.endRotation,
41316            prevDirty = dirty,
41317            xChange,
41318            yChange,
41319            x,
41320            y,
41321            dif,
41322            temp;
41323        self.pointerX = pointerX;
41324        self.pointerY = pointerY;
41325
41326        if (isFixed) {
41327          pointerX -= _getDocScrollLeft$1(ownerDoc);
41328          pointerY -= _getDocScrollTop$1(ownerDoc);
41329        }
41330
41331        if (rotationMode) {
41332          y = Math.atan2(rotationOrigin.y - pointerY, pointerX - rotationOrigin.x) * _RAD2DEG;
41333          dif = self.y - y;
41334
41335          if (dif > 180) {
41336            startElementY -= 360;
41337            self.y = y;
41338          } else if (dif < -180) {
41339            startElementY += 360;
41340            self.y = y;
41341          }
41342
41343          if (self.x !== startElementX || Math.abs(startElementY - y) > minimumMovement) {
41344            self.y = y;
41345            x = startElementX + (startElementY - y) * dragTolerance;
41346          } else {
41347            x = startElementX;
41348          }
41349        } else {
41350          if (matrix) {
41351            temp = pointerX * matrix.a + pointerY * matrix.c + matrix.e;
41352            pointerY = pointerX * matrix.b + pointerY * matrix.d + matrix.f;
41353            pointerX = temp;
41354          }
41355
41356          yChange = pointerY - startPointerY;
41357          xChange = pointerX - startPointerX;
41358
41359          if (yChange < minimumMovement && yChange > -minimumMovement) {
41360            yChange = 0;
41361          }
41362
41363          if (xChange < minimumMovement && xChange > -minimumMovement) {
41364            xChange = 0;
41365          }
41366
41367          if ((self.lockAxis || self.lockedAxis) && (xChange || yChange)) {
41368            temp = self.lockedAxis;
41369
41370            if (!temp) {
41371              self.lockedAxis = temp = allowX && Math.abs(xChange) > Math.abs(yChange) ? "y" : allowY ? "x" : null;
41372
41373              if (temp && _isFunction(self.vars.onLockAxis)) {
41374                self.vars.onLockAxis.call(self, self.pointerEvent);
41375              }
41376            }
41377
41378            if (temp === "y") {
41379              yChange = 0;
41380            } else if (temp === "x") {
41381              xChange = 0;
41382            }
41383          }
41384
41385          x = _round(startElementX + xChange * dragTolerance);
41386          y = _round(startElementY + yChange * dragTolerance);
41387        }
41388
41389        if ((snapX || snapY || snapXY) && (self.x !== x || self.y !== y && !rotationMode)) {
41390          if (snapXY) {
41391            _temp1.x = x;
41392            _temp1.y = y;
41393            temp = snapXY(_temp1);
41394            x = _round(temp.x);
41395            y = _round(temp.y);
41396          }
41397
41398          if (snapX) {
41399            x = _round(snapX(x));
41400          }
41401
41402          if (snapY) {
41403            y = _round(snapY(y));
41404          }
41405        }
41406
41407        if (hasBounds) {
41408          if (x > maxX) {
41409            x = maxX + Math.round((x - maxX) * edgeTolerance);
41410          } else if (x < minX) {
41411            x = minX + Math.round((x - minX) * edgeTolerance);
41412          }
41413
41414          if (!rotationMode) {
41415            if (y > maxY) {
41416              y = Math.round(maxY + (y - maxY) * edgeTolerance);
41417            } else if (y < minY) {
41418              y = Math.round(minY + (y - minY) * edgeTolerance);
41419            }
41420          }
41421        }
41422
41423        if (self.x !== x || self.y !== y && !rotationMode) {
41424          if (rotationMode) {
41425            self.endRotation = self.x = self.endX = x
vendor: 13,666 bytes, lines 41425-41832
41425;
41426            dirty = true;
41427          } else {
41428            if (allowY) {
41429              self.y = self.endY = y;
41430              dirty = true;
41431            }
41432
41433            if (allowX) {
41434              self.x = self.endX = x;
41435              dirty = true;
41436            }
41437          }
41438
41439          if (!invokeOnMove || _dispatchEvent(self, "move", "onMove") !== false) {
41440            if (!self.isDragging && self.isPressed) {
41441              self.isDragging = dragged = true;
41442
41443              _dispatchEvent(self, "dragstart", "onDragStart");
41444            }
41445          } else {
41446            self.pointerX = prevPointerX;
41447            self.pointerY = prevPointerY;
41448            startElementY = prevStartElementY;
41449            self.x = prevX;
41450            self.y = prevY;
41451            self.endX = prevEndX;
41452            self.endY = prevEndY;
41453            self.endRotation = prevEndRotation;
41454            dirty = prevDirty;
41455          }
41456        }
41457      },
41458          onRelease = function onRelease(e, force) {
41459        if (!enabled || !self.isPressed || e && touchID != null && !force && (e.pointerId && e.pointerId !== touchID && e.target !== target || e.changedTouches && !_hasTouchID(e.changedTouches, touchID))) {
41460          isPreventingDefault && e && enabled && _preventDefault(e);
41461          return;
41462        }
41463
41464        self.isPressed = false;
41465        var originalEvent = e,
41466            wasDragging = self.isDragging,
41467            isContextMenuRelease = self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2),
41468            placeholderDelayedCall = gsap.delayedCall(0.001, removePlaceholder),
41469            touches,
41470            i,
41471            syntheticEvent,
41472            eventTarget,
41473            syntheticClick;
41474
41475        if (touchEventTarget) {
41476          _removeListener(touchEventTarget, "touchend", onRelease);
41477
41478          _removeListener(touchEventTarget, "touchmove", onMove);
41479
41480          _removeListener(touchEventTarget, "touchcancel", onRelease);
41481
41482          _removeListener(ownerDoc, "touchstart", _onMultiTouchDocument);
41483        } else {
41484          _removeListener(ownerDoc, "mousemove", onMove);
41485        }
41486
41487        _removeListener(_win$1, "touchforcechange", _preventDefault);
41488
41489        if (!_supportsPointer || !touchEventTarget) {
41490          _removeListener(ownerDoc, "mouseup", onRelease);
41491
41492          e && e.target && _removeListener(e.target, "mouseup", onRelease);
41493        }
41494
41495        dirty = false;
41496
41497        if (wasDragging) {
41498          dragEndTime = _lastDragTime = _getTime();
41499          self.isDragging = false;
41500        }
41501
41502        _removeFromRenderQueue(render);
41503
41504        if (isClicking && !isContextMenuRelease) {
41505          if (e) {
41506            _removeListener(e.target, "change", onRelease);
41507
41508            self.pointerEvent = originalEvent;
41509          }
41510
41511          _setSelectable(triggers, false);
41512
41513          _dispatchEvent(self, "release", "onRelease");
41514
41515          _dispatchEvent(self, "click", "onClick");
41516
41517          isClicking = false;
41518          return;
41519        }
41520
41521        i = triggers.length;
41522
41523        while (--i > -1) {
41524          _setStyle(triggers[i], "cursor", vars.cursor || (vars.cursor !== false ? _defaultCursor : null));
41525        }
41526
41527        _dragCount--;
41528
41529        if (e) {
41530          touches = e.changedTouches;
41531
41532          if (touches) {
41533            e = touches[0];
41534
41535            if (e !== touch && e.identifier !== touchID) {
41536              i = touches.length;
41537
41538              while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {}
41539
41540              if (i < 0 && !force) {
41541                return;
41542              }
41543            }
41544          }
41545
41546          self.pointerEvent = originalEvent;
41547          self.pointerX = e.pageX;
41548          self.pointerY = e.pageY;
41549        }
41550
41551        if (isContextMenuRelease && originalEvent) {
41552          _preventDefault(originalEvent);
41553
41554          isPreventingDefault = true;
41555
41556          _dispatchEvent(self, "release", "onRelease");
41557        } else if (originalEvent && !wasDragging) {
41558          isPreventingDefault = false;
41559
41560          if (interrupted && (vars.snap || vars.bounds)) {
41561            animate(vars.inertia || vars.throwProps);
41562          }
41563
41564          _dispatchEvent(self, "release", "onRelease");
41565
41566          if ((!_isAndroid || originalEvent.type !== "touchmove") && originalEvent.type.indexOf("cancel") === -1) {
41567            _dispatchEvent(self, "click", "onClick");
41568
41569            if (_getTime() - clickTime < 300) {
41570              _dispatchEvent(self, "doubleclick", "onDoubleClick");
41571            }
41572
41573            eventTarget = originalEvent.target || target;
41574            clickTime = _getTime();
41575
41576            syntheticClick = function syntheticClick() {
41577              if (clickTime !== clickDispatch && self.enabled() && !self.isPressed && !originalEvent.defaultPrevented) {
41578                if (eventTarget.click) {
41579                  eventTarget.click();
41580                } else if (ownerDoc.createEvent) {
41581                  syntheticEvent = ownerDoc.createEvent("MouseEvents");
41582                  syntheticEvent.initMouseEvent("click", true, true, _win$1, 1, self.pointerEvent.screenX, self.pointerEvent.screenY, self.pointerX, self.pointerY, false, false, false, false, 0, null);
41583                  eventTarget.dispatchEvent(syntheticEvent);
41584                }
41585              }
41586            };
41587
41588            if (!_isAndroid && !originalEvent.defaultPrevented) {
41589              gsap.delayedCall(0.05, syntheticClick);
41590            }
41591          }
41592        } else {
41593          animate(vars.inertia || vars.throwProps);
41594
41595          if (!self.allowEventDefault && originalEvent && (vars.dragClickables !== false || !isClickable.call(self, originalEvent.target)) && wasDragging && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling === touchDragAxis) && originalEvent.cancelable !== false) {
41596            isPreventingDefault = true;
41597
41598            _preventDefault(originalEvent);
41599          } else {
41600            isPreventingDefault = false;
41601          }
41602
41603          _dispatchEvent(self, "release", "onRelease");
41604        }
41605
41606        isTweening() && placeholderDelayedCall.duration(self.tween.duration());
41607        wasDragging && _dispatchEvent(self, "dragend", "onDragEnd");
41608        return true;
41609      },
41610          updateScroll = function updateScroll(e) {
41611        if (e && self.isDragging && !scrollProxy) {
41612          var parent = e.target || target.parentNode,
41613              deltaX = parent.scrollLeft - parent._gsScrollX,
41614              deltaY = parent.scrollTop - parent._gsScrollY;
41615
41616          if (deltaX || deltaY) {
41617            if (matrix) {
41618              startPointerX -= deltaX * matrix.a + deltaY * matrix.c;
41619              startPointerY -= deltaY * matrix.d + deltaX * matrix.b;
41620            } else {
41621              startPointerX -= deltaX;
41622              startPointerY -= deltaY;
41623            }
41624
41625            parent._gsScrollX += deltaX;
41626            parent._gsScrollY += deltaY;
41627            setPointerPosition(self.pointerX, self.pointerY);
41628          }
41629        }
41630      },
41631          onClick = function onClick(e) {
41632        var time = _getTime(),
41633            recentlyClicked = time - clickTime < 100,
41634            recentlyDragged = time - dragEndTime < 50,
41635            alreadyDispatched = recentlyClicked && clickDispatch === clickTime,
41636            defaultPrevented = self.pointerEvent && self.pointerEvent.defaultPrevented,
41637            alreadyDispatchedTrusted = recentlyClicked && trustedClickDispatch === clickTime,
41638            trusted = e.isTrusted || e.isTrusted == null && recentlyClicked && alreadyDispatched;
41639
41640        if ((alreadyDispatched || recentlyDragged && self.vars.suppressClickOnDrag !== false) && e.stopImmediatePropagation) {
41641          e.stopImmediatePropagation();
41642        }
41643
41644        if (recentlyClicked && !(self.pointerEvent && self.pointerEvent.defaultPrevented) && (!alreadyDispatched || trusted && !alreadyDispatchedTrusted)) {
41645          if (trusted && alreadyDispatched) {
41646            trustedClickDispatch = clickTime;
41647          }
41648
41649          clickDispatch = clickTime;
41650          return;
41651        }
41652
41653        if (self.isPressed || recentlyDragged || recentlyClicked) {
41654          if (!trusted || !e.detail || !recentlyClicked || defaultPrevented) {
41655            _preventDefault(e);
41656          }
41657        }
41658
41659        if (!recentlyClicked && !recentlyDragged && !dragged) {
41660          e && e.target && (self.pointerEvent = e);
41661
41662          _dispatchEvent(self, "click", "onClick");
41663        }
41664      },
41665          localizePoint = function localizePoint(p) {
41666        return matrix ? {
41667          x: p.x * matrix.a + p.y * matrix.c + matrix.e,
41668          y: p.x * matrix.b + p.y * matrix.d + matrix.f
41669        } : {
41670          x: p.x,
41671          y: p.y
41672        };
41673      };
41674
41675      old = Draggable.get(target);
41676      old && old.kill();
41677
41678      _this2.startDrag = function (event, align) {
41679        var r1, r2, p1, p2;
41680        onPress(event || self.pointerEvent, true);
41681
41682        if (align && !self.hitTest(event || self.pointerEvent)) {
41683          r1 = _parseRect(event || self.pointerEvent);
41684          r2 = _parseRect(target);
41685          p1 = localizePoint({
41686            x: r1.left + r1.width / 2,
41687            y: r1.top + r1.height / 2
41688          });
41689          p2 = localizePoint({
41690            x: r2.left + r2.width / 2,
41691            y: r2.top + r2.height / 2
41692          });
41693          startPointerX -= p1.x - p2.x;
41694          startPointerY -= p1.y - p2.y;
41695        }
41696
41697        if (!self.isDragging) {
41698          self.isDragging = dragged = true;
41699
41700          _dispatchEvent(self, "dragstart", "onDragStart");
41701        }
41702      };
41703
41704      _this2.drag = onMove;
41705
41706      _this2.endDrag = function (e) {
41707        return onRelease(e || self.pointerEvent, true);
41708      };
41709
41710      _this2.timeSinceDrag = function () {
41711        return self.isDragging ? 0 : (_getTime() - dragEndTime) / 1000;
41712      };
41713
41714      _this2.timeSinceClick = function () {
41715        return (_getTime() - clickTime) / 1000;
41716      };
41717
41718      _this2.hitTest = function (target, threshold) {
41719        return Draggable.hitTest(self.target, target, threshold);
41720      };
41721
41722      _this2.getDirection = function (from, diagonalThreshold) {
41723        var mode = from === "velocity" && InertiaPlugin ? from : _isObject(from) && !rotationMode ? "element" : "start",
41724            xChange,
41725            yChange,
41726            ratio,
41727            direction,
41728            r1,
41729            r2;
41730
41731        if (mode === "element") {
41732          r1 = _parseRect(self.target);
41733          r2 = _parseRect(from);
41734        }
41735
41736        xChange = mode === "start" ? self.x - startElementX : mode === "velocity" ? InertiaPlugin.getVelocity(target, xProp) : r1.left + r1.width / 2 - (r2.left + r2.width / 2);
41737
41738        if (rotationMode) {
41739          return xChange < 0 ? "counter-clockwise" : "clockwise";
41740        } else {
41741          diagonalThreshold = diagonalThreshold || 2;
41742          yChange = mode === "start" ? self.y - startElementY : mode === "velocity" ? InertiaPlugin.getVelocity(target, yProp) : r1.top + r1.height / 2 - (r2.top + r2.height / 2);
41743          ratio = Math.abs(xChange / yChange);
41744          direction = ratio < 1 / diagonalThreshold ? "" : xChange < 0 ? "left" : "right";
41745
41746          if (ratio < diagonalThreshold) {
41747            if (direction !== "") {
41748              direction += "-";
41749            }
41750
41751            direction += yChange < 0 ? "up" : "down";
41752          }
41753        }
41754
41755        return direction;
41756      };
41757
41758      _this2.applyBounds = function (newBounds, sticky) {
41759        var x, y, forceZeroVelocity, e, parent, isRoot;
41760
41761        if (newBounds && vars.bounds !== newBounds) {
41762          vars.bounds = newBounds;
41763          return self.update(true, sticky);
41764        }
41765
41766        syncXY(true);
41767        calculateBounds();
41768
41769        if (hasBounds && !isTweening()) {
41770          x = self.x;
41771          y = self.y;
41772
41773          if (x > maxX) {
41774            x = maxX;
41775          } else if (x < minX) {
41776            x = minX;
41777          }
41778
41779          if (y > maxY) {
41780            y = maxY;
41781          } else if (y < minY) {
41782            y = minY;
41783          }
41784
41785          if (self.x !== x || self.y !== y) {
41786            forceZeroVelocity = true;
41787            self.x = self.endX = x;
41788
41789            if (rotationMode) {
41790              self.endRotation = x;
41791            } else {
41792              self.y = self.endY = y;
41793            }
41794
41795            dirty = true;
41796            render(true);
41797
41798            if (self.autoScroll && !self.isDragging) {
41799              _recordMaxScrolls(target.parentNode);
41800
41801              e = target;
41802              _windowProxy.scrollTop = _win$1.pageYOffset != null ? _win$1.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop;
41803              _windowProxy.scrollLeft = _win$1.pageXOffset != null ? _win$1.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft;
41804
41805              while (e && !isRoot) {
41806                isRoot = _isRoot(e.parentNode);
41807                parent = isRoot ? _windowProxy : e.parentNode;
41808
41809                if (allowY && parent.scrollTop > parent._gsMaxScrollY) {
41810                  parent.scrollTop = parent._gsMaxScrollY;
41811                }
41812
41813                if (allowX && parent.scrollLeft > parent._gsMaxScrollX) {
41814                  parent.scrollLeft = parent._gsMaxScrollX;
41815                }
41816
41817                e = parent;
41818              }
41819            }
41820          }
41821
41822          if (self.isThrowing && (forceZeroVelocity || self.endX > maxX || self.endX < minX || self.endY > maxY || self.endY < minY)) {
41823            animate(vars.inertia || vars.throwProps, forceZeroVelocity);
41824          }
41825        }
41826
41827        return self;
41828      };
41829
41830      _this2.update = function (applyBounds, sticky, ignoreExternalChanges) {
41831        if (sticky && self.isPressed) {
41832          
vendor: 3,070 bytes, lines 41832-41933
41832var m = getGlobalMatrix(target),
41833              p = innerMatrix.apply({
41834            x: self.x - startElementX,
41835            y: self.y - startElementY
41836          }),
41837              m2 = getGlobalMatrix(target.parentNode, true);
41838          m2.apply({
41839            x: m.e - p.x,
41840            y: m.f - p.y
41841          }, p);
41842          self.x -= p.x - m2.e;
41843          self.y -= p.y - m2.f;
41844          render(true);
41845          recordStartPositions();
41846        }
41847
41848        var x = self.x,
41849            y = self.y;
41850        updateMatrix(!sticky);
41851
41852        if (applyBounds) {
41853          self.applyBounds();
41854        } else {
41855          dirty && ignoreExternalChanges && render(true);
41856          syncXY(true);
41857        }
41858
41859        if (sticky) {
41860          setPointerPosition(self.pointerX, self.pointerY);
41861          dirty && render(true);
41862        }
41863
41864        if (self.isPressed && !sticky && (allowX && Math.abs(x - self.x) > 0.01 || allowY && Math.abs(y - self.y) > 0.01 && !rotationMode)) {
41865          recordStartPositions();
41866        }
41867
41868        if (self.autoScroll) {
41869          _recordMaxScrolls(target.parentNode, self.isDragging);
41870
41871          checkAutoScrollBounds = self.isDragging;
41872          render(true);
41873
41874          _removeScrollListener(target, updateScroll);
41875
41876          _addScrollListener(target, updateScroll);
41877        }
41878
41879        return self;
41880      };
41881
41882      _this2.enable = function (type) {
41883        var setVars = {
41884          lazy: true
41885        },
41886            id,
41887            i,
41888            trigger;
41889
41890        if (vars.cursor !== false) {
41891          setVars.cursor = vars.cursor || _defaultCursor;
41892        }
41893
41894        if (gsap.utils.checkPrefix("touchCallout")) {
41895          setVars.touchCallout = "none";
41896        }
41897
41898        if (type !== "soft") {
41899          _setTouchActionForAllDescendants(triggers, allowX === allowY ? "none" : vars.allowNativeTouchScrolling && target.scrollHeight === target.clientHeight === (target.scrollWidth === target.clientHeight) || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x");
41900
41901          i = triggers.length;
41902
41903          while (--i > -1) {
41904            trigger = triggers[i];
41905            _supportsPointer || _addListener(trigger, "mousedown", onPress);
41906
41907            _addListener(trigger, "touchstart", onPress);
41908
41909            _addListener(trigger, "click", onClick, true);
41910
41911            gsap.set(trigger, setVars);
41912
41913            if (trigger.getBBox && trigger.ownerSVGElement && allowX !== allowY) {
41914              gsap.set(trigger.ownerSVGElement, {
41915                touchAction: vars.allowNativeTouchScrolling || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x"
41916              });
41917            }
41918
41919            vars.allowContextMenu || _addListener(trigger, "contextmenu", onContextMenu);
41920          }
41921
41922          _setSelectable(triggers, false);
41923        }
41924
41925        _addScrollListener(target, updateScroll);
41926
41927        enabled = true;
41928
41929        if (InertiaPlugin && type !== "soft") {
41930          InertiaPlugin.track(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left");
41931        }
41932
41933        target._gsDragID = id =
vendor: 5,466 bytes, lines 41933-42139
41933 "d" + _lookupCount++;
41934        _lookup[id] = self;
41935
41936        if (scrollProxy) {
41937          scrollProxy.enable();
41938          scrollProxy.element._gsDragID = id;
41939        }
41940
41941        (vars.bounds || rotationMode) && recordStartPositions();
41942        vars.bounds && self.applyBounds();
41943        return self;
41944      };
41945
41946      _this2.disable = function (type) {
41947        var dragging = self.isDragging,
41948            i = triggers.length,
41949            trigger;
41950
41951        while (--i > -1) {
41952          _setStyle(triggers[i], "cursor", null);
41953        }
41954
41955        if (type !== "soft") {
41956          _setTouchActionForAllDescendants(triggers, null);
41957
41958          i = triggers.length;
41959
41960          while (--i > -1) {
41961            trigger = triggers[i];
41962
41963            _setStyle(trigger, "touchCallout", null);
41964
41965            _removeListener(trigger, "mousedown", onPress);
41966
41967            _removeListener(trigger, "touchstart", onPress);
41968
41969            _removeListener(trigger, "click", onClick, true);
41970
41971            _removeListener(trigger, "contextmenu", onContextMenu);
41972          }
41973
41974          _setSelectable(triggers, true);
41975
41976          if (touchEventTarget) {
41977            _removeListener(touchEventTarget, "touchcancel", onRelease);
41978
41979            _removeListener(touchEventTarget, "touchend", onRelease);
41980
41981            _removeListener(touchEventTarget, "touchmove", onMove);
41982          }
41983
41984          _removeListener(ownerDoc, "mouseup", onRelease);
41985
41986          _removeListener(ownerDoc, "mousemove", onMove);
41987        }
41988
41989        _removeScrollListener(target, updateScroll);
41990
41991        enabled = false;
41992
41993        if (InertiaPlugin && type !== "soft") {
41994          InertiaPlugin.untrack(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left");
41995          self.tween && self.tween.kill();
41996        }
41997
41998        scrollProxy && scrollProxy.disable();
41999
42000        _removeFromRenderQueue(render);
42001
42002        self.isDragging = self.isPressed = isClicking = false;
42003        dragging && _dispatchEvent(self, "dragend", "onDragEnd");
42004        return self;
42005      };
42006
42007      _this2.enabled = function (value, type) {
42008        return arguments.length ? value ? self.enable(type) : self.disable(type) : enabled;
42009      };
42010
42011      _this2.kill = function () {
42012        self.isThrowing = false;
42013        self.tween && self.tween.kill();
42014        self.disable();
42015        gsap.set(triggers, {
42016          clearProps: "userSelect"
42017        });
42018        delete _lookup[target._gsDragID];
42019        return self;
42020      };
42021
42022      _this2.revert = function () {
42023        this.kill();
42024        this.styles && this.styles.revert();
42025      };
42026
42027      if (~type.indexOf("scroll")) {
42028        scrollProxy = _this2.scrollProxy = new ScrollProxy(target, _extend({
42029          onKill: function onKill() {
42030            self.isPressed && onRelease(null);
42031          }
42032        }, vars));
42033        target.style.overflowY = allowY && !_isTouchDevice ? "auto" : "hidden";
42034        target.style.overflowX = allowX && !_isTouchDevice ? "auto" : "hidden";
42035        target = scrollProxy.content;
42036      }
42037
42038      if (rotationMode) {
42039        killProps.rotation = 1;
42040      } else {
42041        if (allowX) {
42042          killProps[xProp] = 1;
42043        }
42044
42045        if (allowY) {
42046          killProps[yProp] = 1;
42047        }
42048      }
42049
42050      gsCache.force3D = "force3D" in vars ? vars.force3D : true;
42051
42052      _context(_assertThisInitialized(_this2));
42053
42054      _this2.enable();
42055
42056      return _this2;
42057    }
42058
42059    Draggable.register = function register(core) {
42060      gsap = core;
42061
42062      _initCore();
42063    };
42064
42065    Draggable.create = function create(targets, vars) {
42066      _coreInitted || _initCore(true);
42067      return _toArray(targets).map(function (target) {
42068        return new Draggable(target, vars);
42069      });
42070    };
42071
42072    Draggable.get = function get(target) {
42073      return _lookup[(_toArray(target)[0] || {})._gsDragID];
42074    };
42075
42076    Draggable.timeSinceDrag = function timeSinceDrag() {
42077      return (_getTime() - _lastDragTime) / 1000;
42078    };
42079
42080    Draggable.hitTest = function hitTest(obj1, obj2, threshold) {
42081      if (obj1 === obj2) {
42082        return false;
42083      }
42084
42085      var r1 = _parseRect(obj1),
42086          r2 = _parseRect(obj2),
42087          top = r1.top,
42088          left = r1.left,
42089          right = r1.right,
42090          bottom = r1.bottom,
42091          width = r1.width,
42092          height = r1.height,
42093          isOutside = r2.left > right || r2.right < left || r2.top > bottom || r2.bottom < top,
42094          overlap,
42095          area,
42096          isRatio;
42097
42098      if (isOutside || !threshold) {
42099        return !isOutside;
42100      }
42101
42102      isRatio = (threshold + "").indexOf("%") !== -1;
42103      threshold = parseFloat(threshold) || 0;
42104      overlap = {
42105        left: Math.max(left, r2.left),
42106        top: Math.max(top, r2.top)
42107      };
42108      overlap.width = Math.min(right, r2.right) - overlap.left;
42109      overlap.height = Math.min(bottom, r2.bottom) - overlap.top;
42110
42111      if (overlap.width < 0 || overlap.height < 0) {
42112        return false;
42113      }
42114
42115      if (isRatio) {
42116        threshold *= 0.01;
42117        area = overlap.width * overlap.height;
42118        return area >= width * height * threshold || area >= r2.width * r2.height * threshold;
42119      }
42120
42121      return overlap.width > threshold && overlap.height > threshold;
42122    };
42123
42124    return Draggable;
42125  }(EventDispatcher);
42126
42127  _setDefaults(Draggable.prototype, {
42128    pointerX: 0,
42129    pointerY: 0,
42130    startX: 0,
42131    startY: 0,
42132    deltaX: 0,
42133    deltaY: 0,
42134    isDragging: false,
42135    isPressed: false
42136  });
42137
42138  Draggable.zIndex = 1000;
42139  Draggable.version = "3.1
421392.5";
42140  _getGSAP() && gsap.registerPlugin(Draggable);
42141
42142  exports.Draggable = Draggable;
42143  exports.default = Draggable;
42144
42145  if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;}
42146
42147})));
42148/* ========================================================================
42149 * Bootstrap: collapse.js v3.1.1
42150 * http://getbootstrap.com/javascript/#collapse
42151 * ========================================================================
42152 * Copyright 2011-2014 Twitter, Inc.
42153 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42154 * ======================================================================== */
42155
42156
42157+function ($) {
42158	'use strict';
42159
42160	// COLLAPSE PUBLIC CLASS DEFINITION
42161	// ================================
42162
42163	var Collapse = function (element, options) {
42164		this.$element      = $(element)
42165		this.options       = $.extend({}, Collapse.DEFAULTS, options)
42166		this.transitioning = null
42167
42168		if (this.options.parent) this.$parent = $(this.options.parent)
42169		if (this.options.toggle) this.toggle()
42170	}
42171
42172	Collapse.DEFAULTS = {
42173		toggle: true
42174	}
42175
42176	Collapse.prototype.dimension = function () {
42177		var hasWidth = this.$element.hasClass('width')
42178		return hasWidth ? 'width' : 'height'
42179	}
42180
42181	Collapse.prototype.show = function () {
42182		if (this.transitioning || this.$element.hasClass('in')) return
42183
42184		var startEvent = $.Event('show.bs.collapse')
42185		this.$element.trigger(startEvent)
42186		if (startEvent.isDefaultPrevented()) return
42187
42188		var actives = this.$parent && this.$parent.find('> .panel > .in')
42189
42190		if (actives && actives.length) {
42191			var hasData = actives.data('bs.collapse')
42192			if (hasData && hasData.transitioning) return
42193			//START UNCODE EDIT
42194			var parentNoToggle = this.$parent.data('no-toggle')
42195			if (!parentNoToggle) {
42196				actives.collapse('hide')
42197			}
42198			//END UNCODE EDIT
42199			hasData || actives.data('bs.collapse', null)
42200		}
42201
42202		var dimension = this.dimension()
42203
42204		this.$element
42205			.removeClass('collapse')
42206			.addClass('collapsing')[dimension](0)
42207
42208		this.transitioning = 1
42209
42210		var complete = function (e) {
42211			if (e && e.target != this.$element[0]) return
42212			this.$element
42213				.removeClass('collapsing')
42214				.addClass('collapse in')[dimension]('auto')
42215			this.transitioning = 0
42216			this.$element.trigger('shown.bs.collapse')
42217		}
42218
42219		if (!$.support.transition) return complete.call(this)
42220
42221		var scrollSize = $.camelCase(['scroll', dimension].join('-'))
42222
42223		this.$element
42224			.one($.support.transition.end, $.proxy(complete, this))
42225			.emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
42226	}
42227
42228	Collapse.prototype.hide = function () {
42229		if (this.transitioning || !this.$element.hasClass('in')) return
42230
42231		var startEvent = $.Event('hide.bs.collapse')
42232		this.$element.trigger(startEvent)
42233		if (startEvent.isDefaultPrevented()) return
42234
42235		var dimension = this.dimension()
42236
42237		this.$element[dimension](this.$element[dimension]())[0].offsetHeight
42238
42239		this.$element
42240			.addClass('collapsing')
42241			.removeClass('collapse')
42242			.removeClass('in')
42243
42244		this.transitioning = 1
42245
42246		var complete = function (e) {
42247			if (e && e.target != this.$element[0]) return
42248			this.transitioning = 0
42249			this.$element
42250				.trigger('hidden.bs.collapse')
42251				.removeClass('collapsing')
42252				.addClass('collapse')
42253		}
42254
42255		if (!$.support.transition) return complete.call(this)
42256
42257		this.$element
42258			[dimension](0)
42259			.one($.support.transition.end, $.proxy(complete, this))
42260			.emulateTransitionEnd(350)
42261	}
42262
42263	Collapse.prototype.toggle = function () {
42264		this[this.$element.hasClass('in') ? 'hide' : 'show']()
42265	}
42266
42267
42268	// COLLAPSE PLUGIN DEFINITION
42269	// ==========================
42270
42271	var old = $.fn.collapse
42272
42273	$.fn.collapse = function (option) {
42274		return this.each(function () {
42275			var $this   = $(this)
42276			var data    = $this.data('bs.collapse')
42277			var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
42278
42279			if (!data && options.toggle && option == 'show') option = !option
42280			if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
42281			if (typeof option == 'string') data[option]()
42282		})
42283	}
42284
42285	$.fn.collapse.Constructor = Collapse
42286
42287
42288	// COLLAPSE NO CONFLICT
42289	// ====================
42290
42291	$.fn.collapse.noConflict = function () {
42292		$.fn.collapse = old
42293		return this
42294	}
42295
42296
42297	// COLLAPSE DATA-API
42298	// =================
42299
42300	$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
42301		var $this   = $(this), href
42302		var target  = $this.attr('data-target')
42303				|| e.preventDefault()
42304				|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
42305		//Edited by Uncode to replace ID in panel [START]
42306		var _target = href.replace(/^#/, "");
42307		if ( $('[data-id="' + _target + '"]').length ) {
42308			var $target = $('[data-id="' + _target + '"]')
42309		} else {
42310			var $target = $(target)
42311		}
42312		//Edited by Uncode to replace ID in panel [END]
42313		var data    = $target.data('bs.collapse')
42314		var option  = data ? 'toggle' : $this.data()
42315		var parent  = $this.attr('data-parent')
42316		var $parent = parent && $(parent)
42317
42318		if (!data || !data.transitioning) {
42319			if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
42320			$this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
42321		}
42322
42323		$target.collapse(option)
42324	})
42325
42326}(jQuery);
42327
42328/* ========================================================================
42329 * Bootstrap: tab.js v3.1.1
42330 * http://getbootstrap.com/javascript/#tabs
42331 * ========================================================================
42332 * Copyright 2011-2014 Twitter, Inc.
42333 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42334 * ======================================================================== */
42335
42336
42337+function ($) {
42338  'use strict';
42339
42340  // TAB CLASS DEFINITION
42341  // ====================
42342
42343  var Tab = function (element) {
42344    this.element = $(element)
42345  }
42346
42347  Tab.prototype.show = function () {
42348    var $this    = this.element
42349    var $ul      = $this.closest('ul:not(.dropdown-menu)')
42350    var selector = $this.data('target')
42351
42352    if (!selector) {
42353      selector = $this.attr('href')
42354      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
42355    }
42356
42357    if ($this.parent('li').hasClass('active')) return
42358
42359    var previous = $ul.find('.active:last a')[0]
42360    var e        = $.Event('show.bs.tab', {
42361      relatedTarget: previous
42362    })
42363
42364    $this.trigger(e)
42365
42366    if (e.isDefaultPrevented()) return
42367
42368    //Edited by Uncode to replace ID in panel [START]
42369    var _target = selector.replace(/^#/, "");
42370    if ( $('[data-id="' + _target + '"]').length )
42371      var $target = $('[data-id="' + _target + '"]')
42372    else
42373      var $target = $(selector)
42374    //Edited by Uncode to replace ID in panel [END]
42375
42376    this.activate($this.parent('li'), $ul)
42377    this.activate($target, $target.parent(), function () {
42378      $this.trigger({
42379        type: 'shown.bs.tab',
42380        relatedTarget: previous
42381      })
42382    })
42383  }
42384
42385  Tab.prototype.activate = function (element, container, callback) {
42386    var $active    = container.find('> .active').add(container.find('> .active > .active'))
42387    var transition = callback
42388      && $.support.transition
42389      && $active.hasClass('fade')
42390
42391    function next() {
42392      $active
42393        .removeClass('active')
42394        .find('> .dropdown-menu > .active')
42395        .removeClass('active')
42396
42397      $active
42398        .find('.tab-excerpt').slideUp();
42399
42400      element.addClass('active')
42401      $('.tab-excerpt', element).slideDown();
42402
42403      //if (transition) {
42404        element[0].offsetWidth // reflow for transition
42405        element.add($active).addClass('in')
42406      /*} else {
42407        element.removeClass('fade')
42408      }*/
42409
42410      if (element.parent('.dropdown-menu')) {
42411        element.closest('li.dropdown').addClass('active')
42412      }
42413
42414      if ( ! element.is('li') ) {
42415        element.closest('.tab-content').find('> .active').not(element).removeClass('active');
42416      }
42417
42418      callback && callback()
42419    }
42420
42421    transition ?
42422      $active
42423        .one($.support.transition.end, next)
42424        .emulateTransitionEnd(150) :
42425      next()
42426
42427    $active.removeClass('in')
42428  }
42429
42430
42431  // TAB PLUGIN DEFINITION
42432  // =====================
42433
42434  var old = $.fn.tab
42435
42436  $.fn.tab = function ( option ) {
42437    return this.each(function () {
42438      var $this = $(this)
42439      var data  = $this.data('bs.tab')
42440
42441      if (!data) $this.data('bs.tab', (data = new Tab(this)))
42442      if (typeof option == 'string') data[option]()
42443    })
42444  }
42445
42446  $.fn.tab.Constructor = Tab
42447
42448
42449  // TAB NO CONFLICT
42450  // ===============
42451
42452  $.fn.tab.noConflict = function () {
42453    $.fn.tab = old
42454    return this
42455  }
42456
42457
42458  // TAB DATA-API
42459  // ============
42460
42461  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
42462    e.preventDefault()
42463    $(this).tab('show')
42464  })
42465
42466}(jQuery);
42467
42468/* ========================================================================
42469 * Bootstrap: tooltip.js v3.1.1
42470 * http://getbootstrap.com/javascript/#tooltip
42471 * Inspired by the original jQuery.tipsy by Jason Frame
42472 * ========================================================================
42473 * Copyright 2011-2014 Twitter, Inc.
42474 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42475 * ======================================================================== */
42476
42477
42478+function ($) {
42479  'use strict';
42480
42481  // TOOLTIP PUBLIC CLASS DEFINITION
42482  // ===============================
42483
42484  var Tooltip = function (element, options) {
42485    this.type       =
42486    this.options    =
42487    this.enabled    =
42488    this.timeout    =
42489    this.hoverState =
42490    this.$element   = null
42491
42492    this.init('tooltip', element, options)
42493  }
42494
42495  Tooltip.DEFAULTS = {
42496    animation: true,
42497    placement: 'top',
42498    selector: false,
42499    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
42500    trigger: 'hover focus',
42501    title: '',
42502    delay: 0,
42503    html: false,
42504    container: false,
42505    viewport: {
42506      selector: 'body',
42507      padding: 0
42508    }
42509  }
42510
42511  Tooltip.prototype.init = function (type, element, options) {
42512    this.enabled   = true
42513    this.type      = type
42514    this.$element  = $(element)
42515    this.options   = this.getOptions(options)
42516    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
42517
42518    var triggers = this.options.trigger.split(' ')
42519
42520    for (var i = triggers.length; i--;) {
42521      var trigger = triggers[i]
42522
42523      if (trigger == 'click') {
42524        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
42525      } else if (trigger != 'manual') {
42526        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
42527        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
42528
42529        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
42530        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
42531      }
42532    }
42533
42534    this.options.selector ?
42535      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
42536      this.fixTitle()
42537  }
42538
42539  Tooltip.prototype.getDefaults = function () {
42540    return Tooltip.DEFAULTS
42541  }
42542
42543  Tooltip.prototype.getOptions = function (options) {
42544    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
42545
42546    if (options.delay && typeof options.delay == 'number') {
42547      options.delay = {
42548        show: options.delay,
42549        hide: options.delay
42550      }
42551    }
42552
42553    return options
42554  }
42555
42556  Tooltip.prototype.getDelegateOptions = function () {
42557    var options  = {}
42558    var defaults = this.getDefaults()
42559
42560    this._options && $.each(this._options, function (key, value) {
42561      if (defaults[key] != value) options[key] = value
42562    })
42563
42564    return options
42565  }
42566
42567  Tooltip.prototype.enter = function (obj) {
42568    var self = obj instanceof this.constructor ?
42569      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
42570
42571    clearTimeout(self.timeout)
42572
42573    self.hoverState = 'in'
42574
42575    if (!self.options.delay || !self.options.delay.show) return self.show()
42576
42577    self.timeout = setTimeout(function () {
42578      if (self.hoverState == 'in') self.show()
42579    }, self.options.delay.show)
42580  }
42581
42582  Tooltip.prototype.leave = function (obj) {
42583    var self = obj instanceof this.constructor ?
42584      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
42585
42586    clearTimeout(self.timeout)
42587
42588    self.hoverState = 'out'
42589
42590    if (!self.options.delay || !self.options.delay.hide) return self.hide()
42591
42592    self.timeout = setTimeout(function () {
42593      if (self.hoverState == 'out') self.hide()
42594    }, self.options.delay.hide)
42595  }
42596
42597  Tooltip.prototype.show = function () {
42598    var e = $.Event('show.bs.' + this.type)
42599
42600    if (this.hasContent() && this.enabled) {
42601      this.$element.trigger(e)
42602
42603      if (e.isDefaultPrevented()) return
42604      var that = this;
42605
42606      var $tip = this.tip()
42607
42608      this.setContent()
42609
42610      if (this.options.animation) $tip.addClass('fade')
42611
42612      var placement = typeof this.options.placement == 'function' ?
42613        this.options.placement.call(this, $tip[0], this.$element[0]) :
42614        this.options.placement
42615
42616      var autoToken = /\s?auto?\s?/i
42617      var autoPlace = autoToken.test(placement)
42618      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
42619
42620      $tip
42621        .detach()
42622        .css({ top: 0, left: 0, display: 'block' })
42623        .addClass(placement)
42624
42625      this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)
42626
42627      var pos          = this.getPosition()
42628      var actualWidth  = $tip[0].offsetWidth
42629      var actualHeight = $tip[0].offsetHeight
42630
42631      if (autoPlace) {
42632        var orgPlacement = placement
42633        var $parent      = this.$element.parent()
42634        var parentDim    = this.getPosition($parent)
42635
42636        placement = placement == 'bottom' && pos.top   + pos.height       + actualHeight - parentDim.scroll > parentDim.height ? 'top'    :
42637                    placement == 'top'    && pos.top   - parentDim.scroll - actualHeight < 0                                   ? 'bottom' :
42638                    placement == 'right'  && pos.right + actualWidth      > parentDim.width                                    ? 'left'   :
42639                    placement == 'left'   && pos.left  - actualWidth      < parentDim.left                                     ? 'right'  :
42640                    placement
42641
42642        $tip
42643          .removeClass(orgPlacement)
42644          .addClass(placement)
42645      }
42646
42647      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
42648
42649      this.applyPlacement(calculatedOffset, placement)
42650      this.hoverState = null
42651
42652      var complete = function() {
42653        that.$element.trigger('shown.bs.' + that.type)
42654      }
42655
42656      $.support.transition && this.$tip.hasClass('fade') ?
42657        $tip
42658          .one($.support.transition.end, complete)
42659          .emulateTransitionEnd(150) :
42660        complete()
42661    }
42662  }
42663
42664  Tooltip.prototype.applyPlacement = function (offset, placement) {
42665    var $tip   = this.tip()
42666    var width  = $tip[0].offsetWidth
42667    var height = $tip[0].offsetHeight
42668
42669    // manually read margins because getBoundingClientRect includes difference
42670    var marginTop = parseInt($tip.css('margin-top'), 10)
42671    var marginLeft = parseInt($tip.css('margin-left'), 10)
42672
42673    // we must check for NaN for ie 8/9
42674    if (isNaN(marginTop))  marginTop  = 0
42675    if (isNaN(marginLeft)) marginLeft = 0
42676
42677    offset.top  = offset.top  + marginTop
42678    offset.left = offset.left + marginLeft
42679
42680    // $.fn.offset doesn't round pixel values
42681    // so we use setOffset directly with our own function B-0
42682    $.offset.setOffset($tip[0], $.extend({
42683      using: function (props) {
42684        $tip.css({
42685          top: Math.round(props.top),
42686          left: Math.round(props.left)
42687        })
42688      }
42689    }, offset), 0)
42690
42691    $tip.addClass('in')
42692
42693    // check to see if placing tip in new offset caused the tip to resize itself
42694    var actualWidth  = $tip[0].offsetWidth
42695    var actualHeight = $tip[0].offsetHeight
42696
42697    if (placement == 'top' && actualHeight != height) {
42698      offset.top = offset.top + height - actualHeight
42699    }
42700
42701    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actua
42701lHeight)
42702
42703    if (delta.left) offset.left += delta.left
42704    else offset.top += delta.top
42705
42706    var arrowDelta          = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
42707    var arrowPosition       = delta.left ? 'left'        : 'top'
42708    var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
42709
42710    $tip.offset(offset)
42711    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
42712  }
42713
42714  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
42715    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
42716  }
42717
42718  Tooltip.prototype.setContent = function () {
42719    var $tip  = this.tip()
42720    var title = this.getTitle()
42721
42722    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
42723    $tip.removeClass('fade in top bottom left right')
42724  }
42725
42726  Tooltip.prototype.hide = function () {
42727    var that = this
42728    var $tip = this.tip()
42729    var e    = $.Event('hide.bs.' + this.type)
42730
42731    function complete() {
42732      if (that.hoverState != 'in') $tip.detach()
42733      that.$element.trigger('hidden.bs.' + that.type)
42734    }
42735
42736    this.$element.trigger(e)
42737
42738    if (e.isDefaultPrevented()) return
42739
42740    $tip.removeClass('in')
42741
42742    $.support.transition && this.$tip.hasClass('fade') ?
42743      $tip
42744        .one($.support.transition.end, complete)
42745        .emulateTransitionEnd(150) :
42746      complete()
42747
42748    this.hoverState = null
42749
42750    return this
42751  }
42752
42753  Tooltip.prototype.fixTitle = function () {
42754    var $e = this.$element
42755    if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
42756      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
42757    }
42758  }
42759
42760  Tooltip.prototype.hasContent = function () {
42761    return this.getTitle()
42762  }
42763
42764  Tooltip.prototype.getPosition = function ($element) {
42765    $element   = $element || this.$element
42766    var el     = $element[0]
42767    var isBody = el.tagName == 'BODY'
42768    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
42769      scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
42770      width:  isBody ? $(window).width()  : $element.outerWidth(),
42771      height: isBody ? $(window).height() : $element.outerHeight()
42772    }, isBody ? {top: 0, left: 0} : $element.offset())
42773  }
42774
42775  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
42776    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
42777           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
42778           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
42779        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
42780
42781  }
42782
42783  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
42784    var delta = { top: 0, left: 0 }
42785    if (!this.$viewport) return delta
42786
42787    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
42788    var viewportDimensions = this.getPosition(this.$viewport)
42789
42790    if (/right|left/.test(placement)) {
42791      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
42792      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
42793      if (topEdgeOffset < viewportDimensions.top) { // top overflow
42794        delta.top = viewportDimensions.top - topEdgeOffset
42795      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
42796        delta.top = viewportDimensions.top + viewportDimensions.height - bottom
42796EdgeOffset
42797      }
42798    } else {
42799      var leftEdgeOffset  = pos.left - viewportPadding
42800      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
42801      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
42802        delta.left = viewportDimensions.left - leftEdgeOffset
42803      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
42804        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
42805      }
42806    }
42807
42808    return delta
42809  }
42810
42811  Tooltip.prototype.getTitle = function () {
42812    var title
42813    var $e = this.$element
42814    var o  = this.options
42815
42816    title = $e.attr('data-original-title')
42817      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
42818
42819    return title
42820  }
42821
42822  Tooltip.prototype.tip = function () {
42823    return this.$tip = this.$tip || $(this.options.template)
42824  }
42825
42826  Tooltip.prototype.arrow = function () {
42827    return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
42828  }
42829
42830  Tooltip.prototype.validate = function () {
42831    if (!this.$element[0].parentNode) {
42832      this.hide()
42833      this.$element = null
42834      this.options  = null
42835    }
42836  }
42837
42838  Tooltip.prototype.enable = function () {
42839    this.enabled = true
42840  }
42841
42842  Tooltip.prototype.disable = function () {
42843    this.enabled = false
42844  }
42845
42846  Tooltip.prototype.toggleEnabled = function () {
42847    this.enabled = !this.enabled
42848  }
42849
42850  Tooltip.prototype.toggle = function (e) {
42851    var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
42852    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
42853  }
42854
42855  Tooltip.prototype.destroy = function () {
42856    clearTimeout(this.timeout)
42857    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
42858  }
42859
42860
42861  // TOOLTIP PLUGIN DEFINITION
42862  // =========================
42863
42864  var old = $.fn.tooltip
42865
42866  $.fn.tooltip = function (option) {
42867    return this.each(function () {
42868      var $this   = $(this)
42869      var data    = $this.data('bs.tooltip')
42870      var options = typeof option == 'object' && option
42871
42872      if (!data && option == 'destroy') return
42873      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
42874      if (typeof option == 'string') data[option]()
42875    })
42876  }
42877
42878  $.fn.tooltip.Constructor = Tooltip
42879
42880
42881  // TOOLTIP NO CONFLICT
42882  // ===================
42883
42884  $.fn.tooltip.noConflict = function () {
42885    $.fn.tooltip = old
42886    return this
42887  }
42888
42889}(jQuery);
42890
42891/* ========================================================================
42892 * Bootstrap: transition.js v3.1.1
42893 * http://getbootstrap.com/javascript/#transitions
42894 * ========================================================================
42895 * Copyright 2011-2014 Twitter, Inc.
42896 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42897 * ======================================================================== */
42898
42899
42900+function ($) {
42901  'use strict';
42902
42903  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
42904  // ============================================================
42905
42906  function transitionEnd() {
42907    var el = document.createElement('bootstrap')
42908
42909    var transEndEventNames = {
42910      WebkitTransition : 'webkitTransitionEnd',
42911      MozTransition    : 'transitionend',
42912      OTransition      : 'oTransitionEnd otransitionend',
42913      transition       : 'transitionend'
42914    }
42915
42916    for (var name in transEndEventNames) {
42917      if (el.style[name] !== undefined) {
42918        return { end: transEndEventNames[name] }
42919      }
42920    }
42921
42922    return false // explicit for ie8 (  ._.)
42923  }
42924
42925  // http://blog.alexmaccaw.com/css-transitions
42926  $.fn.emulateTransitionEnd = function (duration) {
42927    var called = false, $el = this
42928    $(this).one($.support.transition.end, function () { called = true })
42929    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
42930    setTimeout(callback, duration)
42931    return this
42932  }
42933
42934  $(function () {
42935    $.support.transition = transitionEnd()
42936  })
42937
42938}(jQuery);
42939
42940
42941// ------------------------------------------
42942// Rellax.js
42943// Buttery smooth parallax library
42944// Copyright (c) 2016 Moe Amaya (@moeamaya)
42945// MIT license
42946//
42947// Thanks to Paraxify.js and Jaime Cabllero
42948// for parallax concepts
42949// ------------------------------------------
42950
42951(function (root, factory) {
42952	if (typeof define === 'function' && define.amd) {
42953		// AMD. Register as an anonymous module.
42954		define([], factory);
42955	} else if (typeof module === 'object' && module.exports) {
42956		// Node. Does not work with strict CommonJS, but
42957		// only CommonJS-like environments that support module.exports,
42958		// like Node.
42959		module.exports = factory();
42960	} else {
42961		// Browser globals (root is window)
42962		root.Rellax = factory();
42963	}
42964}(typeof window !== "undefined" ? window : global, function () {
42965	var Rellax = function(el, options){
42966		"use strict";
42967
42968		var self = Object.create(Rellax.prototype);
42969
42970		var posY = 0;
42971		var screenY = 0;
42972		var posX = 0;
42973		var screenX = 0;
42974		var blocks = [];
42975		var pause = true;
42976
42977		// check what requestAnimationFrame to use, and if
42978		// it's not supported, use the onscroll event
42979		var loop = window.requestAnimationFrame ||
42980			window.webkitRequestAnimationFrame ||
42981			window.mozRequestAnimationFrame ||
42982			window.msRequestAnimationFrame ||
42983			window.oRequestAnimationFrame ||
42984			function(callback){ return setTimeout(callback, 1000 / 60); };
42985
42986		// store the id for later use
42987		var loopId = null;
42988
42989		// Test via a getter in the options object to see if the passive property is accessed
42990		var supportsPassive = false;
vendor: 10,724 bytes, lines 42991-43292
42991		try {
42992			var opts = Object.defineProperty({}, 'passive', {
42993				get: function() {
42994					supportsPassive = true;
42995				}
42996			});
42997			window.addEventListener("testPassive", null, opts);
42998			window.removeEventListener("testPassive", null, opts);
42999		} catch (e) {}
43000
43001		// check what cancelAnimation method to use
43002		var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout;
43003
43004		// check which transform property to use
43005		var transformProp = window.transformProp || (function(){
43006				var testEl = document.createElement('div');
43007				if (testEl.style.transform === null) {
43008					var vendors = ['Webkit', 'Moz', 'ms'];
43009					for (var vendor in vendors) {
43010						if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) {
43011							return vendors[vendor] + 'Transform';
43012						}
43013					}
43014				}
43015				return 'transform';
43016			})();
43017
43018		// Default Settings
43019		self.options = {
43020			speed: -2,
43021			verticalSpeed: null,
43022			horizontalSpeed: null,
43023			breakpoints: [576, 768, 1201],
43024			center: false,
43025			wrapper: null,
43026			relativeToWrapper: false,
43027			round: true,
43028			vertical: true,
43029			horizontal: false,
43030			verticalScrollAxis: "y",
43031			horizontalScrollAxis: "x",
43032			callback: function() {},
43033		};
43034
43035		// User defined options (might have more in the future)
43036		if (options){
43037			Object.keys(options).forEach(function(key){
43038				self.options[key] = options[key];
43039			});
43040		}
43041
43042		function validateCustomBreakpoints () {
43043			if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) {
43044				var isAscending = true;
43045				var isNumerical = true;
43046				var lastVal;
43047				self.options.breakpoints.forEach(function (i) {
43048					if (typeof i !== 'number') isNumerical = false;
43049					if (lastVal !== null) {
43050						if (i < lastVal) isAscending = false;
43051					}
43052					lastVal = i;
43053				});
43054				if (isAscending && isNumerical) return;
43055			}
43056			// revert defaults if set incorrectly
43057			self.options.breakpoints = [576, 768, 1201];
43058			console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted");
43059		}
43060
43061		if (options && options.breakpoints) {
43062			validateCustomBreakpoints();
43063		}
43064
43065		// By default, rellax class
43066		if (!el) {
43067			el = '.rellax';
43068		}
43069
43070		// check if el is a className or a node
43071		var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el];
43072
43073		// Now query selector
43074		if (elements.length > 0) {
43075			self.elems = elements;
43076		}
43077
43078		// The elements don't exist
43079		else {
43080			console.warn("Rellax: The elements you're trying to select don't exist.");
43081			return;
43082		}
43083
43084		// Has a wrapper and it exists
43085		if (self.options.wrapper) {
43086			if (!self.options.wrapper.nodeType) {
43087				var wrapper = document.querySelector(self.options.wrapper);
43088
43089				if (wrapper) {
43090					self.options.wrapper = wrapper;
43091				} else {
43092					console.warn("Rellax: The wrapper you're trying to use doesn't exist.");
43093					return;
43094				}
43095			}
43096		}
43097
43098		// set a placeholder for the current breakpoint
43099		var currentBreakpoint;
43100
43101		// helper to determine current breakpoint
43102		var getCurrentBreakpoint = function (w) {
43103			var bp = self.options.breakpoints;
43104			if (w < bp[0]) return 'xs';
43105			if (w >= bp[0] && w < bp[1]) return 'sm';
43106			if (w >= bp[1] && w < bp[2]) return 'md';
43107			return 'lg';
43108		};
43109
43110		// Get and cache initial position of all elements
43111		var cacheBlocks = function() {
43112			for (var i = 0; i < self.elems.length; i++){
43113				var block = createBlock(self.elems[i]);
43114				blocks.push(block);
43115			}
43116		};
43117
43118
43119		// Let's kick this script off
43120		// Build array for cached element values
43121		var init = function() {
43122			for (var i = 0; i < blocks.length; i++){
43123				self.elems[i].style.cssText = blocks[i].style;
43124			}
43125
43126			blocks = [];
43127
43128			screenY = window.innerHeight;
43129			screenX = window.innerWidth;
43130			currentBreakpoint = getCurrentBreakpoint(screenX);
43131
43132			setPosition();
43133
43134			cacheBlocks();
43135
43136			animate();
43137
43138			// If paused, unpause and set listener for window resizing events
43139			if (pause) {
43140				window.addEventListener('resize', init);
43141				pause = false;
43142				// Start the loop
43143				update();
43144			}
43145		};
43146
43147		// We want to cache the parallax blocks'
43148		// values: base, top, height, speed
43149		// el: is dom object, return: el cache values
43150		var createBlock = function(el) {
43151			var dataPercentage = el.getAttribute( 'data-rellax-percentage' );
43152			var dataSpeed = el.getAttribute( 'data-rellax-speed' );
43153			var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' );
43154			var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' );
43155			var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' );
43156			var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' );
43157			var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed');
43158			var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed');
43159			var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis');
43160			var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis');
43161			var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0;
43162			var dataMin = el.getAttribute( 'data-rellax-min' );
43163			var dataMax = el.getAttribute( 'data-rellax-max' );
43164			var dataMinX = el.getAttribute('data-rellax-min-x');
43165			var dataMaxX = el.getAttribute('data-rellax-max-x');
43166			var dataMinY = el.getAttribute('data-rellax-min-y');
43167			var dataMaxY = el.getAttribute('data-rellax-max-y');
43168			var mapBreakpoints;
43169			var breakpoints = true;
43170
43171			if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) {
43172				breakpoints = false;
43173			} else {
43174				mapBreakpoints = {
43175					'xs': dataXsSpeed,
43176					'sm': dataMobileSpeed,
43177					'md': dataTabletSpeed,
43178					'lg': dataDesktopSpeed
43179				};
43180			}
43181
43182			// initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser)
43183			// ensures elements are positioned based on HTML layout.
43184			//
43185			// If the element has the percentage attribute, the posY and posX needs to be
43186			// the current scroll position's value, so that the elements are still positioned based on HTML layout
43187			var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
43188			// If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll.
43189			if (self.options.relativeToWrapper) {
43190				var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
43191				wrapperPosY = scrollPosY - self.options.wrapper.offsetTop;
43192			}
43193			var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0;
43194			var posX = self.options.horizontal ? ( dataPercentage || self.options.center ? self.options.wrapper ? self.options.wrapper.scrollLeft : (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft) : 0 ) : 0;
43195
43196			var blockTop = posY + el.getBoundingClientRect().top;
43197			var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight;
43198
43199			var blockLeft = posX + el.getBoundingClientRect().left;
43200			var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth;
43201
43202			// apparently parallax equation everyone uses
43203			var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY);
43204			var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX);
43205			if(self.options.center){ percentageX = 0.5; percentageY = 0.5; }
43206
43207			// Optional individual block speed as data attr, otherwise global speed
43208			var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed);
43209			var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed;
43210			var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed;
43211
43212			// Optional individual block movement axis direction as data attr, otherwise global movement direction
43213			var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis;
43214			var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis;
43215
43216			var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed);
43217
43218			// ~~Store non-translate3d transforms~~
43219			// Store inline styles and extract transforms
43220			var style = el.style.cssText;
43221			var transform = '';
43222
43223			// Check if there's an inline styled transform
43224			var searchResult = /transform\s*:/i.exec(style);
43225			if (searchResult) {
43226				// Get the index of the transform
43227				var index = searchResult.index;
43228
43229				// Trim the style to the transform point and get the following semi-colon index
43230				var trimmedStyle = style.slice(index);
43231				var delimiter = trimmedStyle.indexOf(';');
43232
43233				// Remove "transform" string and save the attribute
43234				if (delimiter) {
43235					transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,'');
43236				} else {
43237					transform = " " + trimmedStyle.slice(11).replace(/\s/g,'');
43238				}
43239			}
43240
43241			return {
43242				baseX: bases.x,
43243				baseY: bases.y,
43244				top: blockTop,
43245				left: blockLeft,
43246				height: blockHeight,
43247				width: blockWidth,
43248				speed: speed,
43249				verticalSpeed: verticalSpeed,
43250				horizontalSpeed: horizontalSpeed,
43251				verticalScrollAxis: verticalScrollAxis,
43252				horizontalScrollAxis: horizontalScrollAxis,
43253				style: style,
43254				transform: transform,
43255				zindex: dataZindex,
43256				min: dataMin,
43257				max: dataMax,
43258				minX: dataMinX,
43259				maxX: dataMaxX,
43260				minY: dataMinY,
43261				maxY: dataMaxY
43262			};
43263		};
43264
43265		// set scroll position (posY, posX)
43266		// side effect method is not ideal, but okay for now
43267		// returns true if the scroll changed, false if nothing happened
43268		var setPosition = function() {
43269			var oldY = posY;
43270			var oldX = posX;
43271
43272			posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset;
43273			posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset;
43274			// If option relativeToWrapper is true, use relative wrapper value instead.
43275			if (self.options.relativeToWrapper) {
43276				var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset;
43277				posY = scrollPosY - self.options.wrapper.offsetTop;
43278			}
43279
43280
43281			if (oldY != posY && self.options.vertical) {
43282				// scroll changed, return true
43283				return true;
43284			}
43285
43286			if (oldX != posX && self.options.horizontal) {
43287				// scroll changed, return true
43288				return true;
43289			}
43290
43291			// scroll did not change
43292			return false;
43293		};
43294
43295		// Ahh a pure function, gets new transform value
43296		// based on scrollPosition and speed
43297		// Allow for decimal pixel values
43298		var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) {
43299			var result = {};
43300			var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX)));
43301			var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY)));
43302
43303			result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100;
43304			result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100;
43305
43306			return result;
43307		};
43308
43309		// Remove event listeners and loop again
43310		var deferredUpdate = function() {
43311			window.removeEventListener('resize', deferredUpdate);
43312			window.removeEventListener('orientationchange', deferredUpdate);
43313			(self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate);
43314			(self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate);
43315
43316			// loop again
43317			loopId = loop(update);
43318		};
43319
43320		// Loop
43321		var update = function() {
43322			if (setPosition() && pause === false) {
43323				animate();
43324
43325				// loop again
43326				loopId = loop(update);
43327			} else {
43328				loopId = null;
43329
43330				// Don't animate until we get a position updating event
43331				window.addEventListener('resize', deferredUpdate);
43332				window.addEventListener('orientationchange', deferredUpdate);
43333				(self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false);
43334				(self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false);
43335			}
43336		};
43337
43338		// Transform3d on parallax element
43339		var animate = function() {
43340			var positions;
43341			for (var i = 0; i < self.elems.length; i++){
43342				// Determine relevant movement directions
43343				var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase();
43344				var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase();
43345				var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0;
43346				var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0;
43347				var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0;
43348				var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0;
43349
43350				var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY));
43351				var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX));
43352
43353				// Subtracting initialize value, so element stays in same spot as HTML
43354				positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed);
43355				var positionY = positions.y - blocks[i].baseY;
43356				var positionX = positions.x - blocks[i].baseX;
43357
43358				// The next two "if" blocks go like this:
43359				// Check if a limit is defined (first "min", then "max");
43360				// Check if we need to change the Y or the X
43361				// (Currently working only if just one of the axes is enabled)
43362				// Then, check if the new position is inside the allowed limit
43363				// If so, use new position. If not, set position to limit.
43364
43365				// Check if a min limit is defined
43366				if (blocks[i].min !== null) {
43367					if (self.options.vertical && !self.options.horizontal) {
43368						positionY = positionY <= blocks[i].min ? blocks[i].min : positionY;
43369					}
43370					if (self.options.horizontal && !self.options.vertical) {
43371						positionX = positionX <= blocks[i].min ? blocks[i].min : positionX;
43372					}
43373				}
43374
43375				// Check if directional min limits are defined
43376				if (blocks[i].minY != null) {
43377						positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY;
43378				}
43379				if (blocks[i].minX != null) {
43380						positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX;
43381				}
43382
43383				// Check if a max limit is defined
43384				if (blocks[i].max !== null) {
43385					if (self.options.vertical && !self.options.horizontal) {
43386						positionY = positionY >= blocks[i].max ? blocks[i].max : positionY;
43387					}
43388					if (self.options.horizontal && !self.options.vertical) {
43389						positionX = positionX >= blocks[i].max ? blocks[i].max : positionX;
43390					}
43391				}
43392
43393				// Check if directional max limits are defined
43394				if (blocks[i].maxY != null) {
43395						positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY;
43396				}
43397				if (blocks[i].maxX != null) {
43398						positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX;
43399				}
43400
43401				var zindex = blocks[i].zindex;
43402
43403				// Move that element
43404				// (Set the new translation and append initial inline transforms.)
43405				var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform;
43406				self.elems[i].style[transformProp] = translate;
43407			}
43408			self.options.callback(positions);
43409		};
43410
43411		self.destroy = function() {
43412			for (var i = 0; i < self.elems.length; i++){
43413				self.elems[i].style.cssText = blocks[i].style;
43414			}
43415
43416			// Remove resize event listener if not pause, and pause
43417			if (!pause) {
43418				window.removeEventListener('resize', init);
43419				pause = true;
43420			}
43421
43422			// Clear the animation loop to prevent possible memory leak
43423			clearLoop(loopId);
43424			loopId = null;
43425		};
43426
43427		// Init
43428		init();
43429
43430		// Allow to recalculate the initial values whenever we want
43431		self.refresh = init;
43432
43433		return self;
43434	};
43435	return Rellax;
43436}));
43437
43438/*
43439 * OKVideo by OKFocus v2.3.2
43440 * http://okfoc.us
43441 *
43442 * Copyright 2014, OKFocus
43443 * Licensed under the MIT license.
43444 *
43445 */
43446var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array();
43447// youtube player ready
43448function onYouTubeIframeAPIReady() {
43449	YTplayers = new Array();
43450	jQuery('.uncode-video-container.video').each(function() {
43451		var playerY;
43452		if (jQuery(this).attr('data-provider') == 'youtube') {
43453			var id = jQuery(this).attr('data-id'),
43454				start = jQuery(this).attr('data-start'),
43455				end = jQuery(this).attr('data-end');
43456			start = typeof start && start !== null ? start : 0;
43457			end = typeof end && end !== null ? end : 0;
43458			options = jQuery(window).data('okoptions-' + id);
43459			if ( typeof options === 'undefined' ) {
43460				return true;
43461			}
43462			options.time = jQuery(this).attr('data-t');
43463			playerY = new YT.Player('okplayer-' + id, {
43464				videoId: options.video ? options.video.id : null,
43465				playerVars: {
43466					'autohide': 1,
43467					'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay,
43468					'disablekb': 1,
43469					'cc_load_policy': options.captions,
43470					'controls': 0,
43471					'enablejsapi': 1,
43472					'fs': 0,
43473					'modestbranding': 1,
43474					'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname),
43475					'iv_load_policy': options.annotations,
43476					'loop': options.loop,
43477					'showinfo': 0,
43478					'rel': 0,
43479					'wmode': 'opaque',
43480					'hd': options.hd,
43481					'mute': 1,
43482					'start': start,
43483					'end': end
43484				},
43485				events: {
43486					'onReady': OKEvents.yt.ready,
43487					'onStateChange': OKEvents.yt.onStateChange,
43488					'onError': OKEvents.yt.error
43489				}
43490			});
43491			YTplayers[id] = playerY;
43492			playerY.videoId = id;
43493		}
43494
43495	});
43496}
43497// vimeo player ready
43498function vimeoPlayerReady(id) {
43499	options = jQuery(window).data('okoptions-' + id);
43500	if ( typeof options === 'undefined' ) {
43501		return true;
43502	}
43503	var jIframe = options.jobject,
43504		iframe = jIframe[0];
43505
43506	jIframe.attr('src', jIframe.data('src'));
43507	var playerV = new Vimeo.Player(iframe);
43508	// hide player until Vimeo hides controls...
43509	playerV.on('loaded', function(e) {
43510		OKEvents.v.onReady(iframe);
43511		var carouselContainer = jQuery(iframe).closest('.owl-carousel');
43512		if (carouselContainer.length) {
43513			UNCODE.owlPlayVideo(carouselContainer);
43514		}
43515		// "Do not try to add listeners or call functions before receiving this event."
43516		if (OKEvents.utils.isMobile()) {
43517			// mobile devices cannot listen for play event
43518			OKEvents.v.onPlay(playerV);
43519		} else {
43520			playerV.on('play', function(){
43521				OKEvents.v.onPlay(playerV);
43522				jQuery(window).trigger('okevents.v.play', [playerV]);
43523			});
43524			playerV.on('pause', function(){
43525				OKEvents.v.onPause;
43526				jQuery(window).trigger('okevents.v.pause', [playerV]);
43527			});
43528			playerV.on('ended', function(){
43529				OKEvents.v.onFinish
43530				jQuery(window).trigger('okevents.v.ended', [playerV]);
43531			});
43532		}
43533		if (options.time != null) {
43534			var optsTimeStr = (options.time).replace('t=', ''),
43535				timeV = '';
43536
43537			if ( /[a-zA-Z]/g.test(optsTimeStr) ) {
43538				var timeArr = optsTimeStr.split(/([^\d.-])/);
43539				for ( var i = 0; i < timeArr.length; i++ ) {
43540					if ( timeArr[i] === 'h' ) {
43541						timeV += parseFloat(timeArr[i-1]) * 3600;
43542					} else if ( timeArr[i] === 'm' ) {
43543						timeV += parseFloat(timeArr[i-1]) * 60;
43544					} else if ( timeArr[i] === 's' ) {
43545						timeV += parseFloat(timeArr[i-1]);
43546					}
43547				}
43548			} else {
43549				timeV = optsTimeStr;
43550			}
43551
43552			playerV.setCurrentTime(timeV);
43553		}
43554
43555		playerV.setVolume(0);
43556		playerV.play();
43557		jQuery(iframe).css({
43558			visibility: 'visible',
43559			opacity: 1
43560		});
43561		jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43562		jQuery(iframe).closest('#page-header').addClass('video-started');
43563		jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43564
43565		jQuery(window).trigger('okevents.v.loaded', [playerV]);
43566	});
43567}
43568OKEvents = {
43569	yt: {
43570		ready: function(event) {
43571			var id = event.target.videoId,
43572				$video = jQuery('#okplayer-' + id),
43573				options = jQuery(window).data('okoptions-' + id);
43574			if ( typeof options === 'undefined' ) {
43575				return true;
43576			}
43577			youtubePlayers[id] = event.target;
43578			event.target.setVolume(options.volume);
43579			if (options.autoplay === 1) {
43580				if (options.playlist.list) {
43581					player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality);
43582				} else {
43583					var inCarousel = $video.closest('.owl-item');
43584					if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) {
43585						if (options.time != null) {
43586							event.target.seekTo(parseInt(options.time));
43587						}
43588						event.target.playVideo();
43589					} else {
43590						event.target.pauseVideo();
43591					}
43592				}
43593			}
43594			OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target);
43595
43596			$video.closest('[data-provider]').on('uncode-resume', function(){
43597				if (options.time != null) {
43598					event.target.seekTo(parseInt(options.time)).playVideo();
43599				} else {
43600					event.target.seekTo(0).playVideo();
43601				}
43602			});
43603
43604			$video.closest('[data-provider]').on('uncode-pause', function(){
43605				if (options.time != null) {
43606					event.target.seekTo(parseInt(options.time)).pauseVideo();
43607				} else {
43608					event.target.seekTo(0).pauseVideo();
43609				}
43610			});
43611			jQuery(window).trigger('okevents.y.loaded', [event]);
43612		},
43613		onStateChange: function(event) {
43614			var id = event.target.videoId,
43615				$video = jQuery('#okplayer-' + id),
43616				options = jQuery(window).data('okoptions-' + id);
43617			if ( typeof options === 'undefined' || typeof event.target.setVolume === 'undefined' ) {
43618				return true;
43619			}
43620			youtubePlayers[id] = event.target;
43621			event.target.setVolume(options.volume);
43622			var $fluid = $video.closest('.fluid-object'),
43623				$tmb = $video.closest('.tmb'),
43624				setTime;
43625			switch (event.data) {
43626				case -1:
43627					OKEvents.utils.isFunction(options.unstarted) && options.unstarted();
43628					break;
43629				case 0:
43630					OKEvents.utils.isFunction(options.onFinished) && options.onFinished();
43631					options.loop && event.target.playVideo();
43632					break;
43633				case 1:
43634					OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
43635					setTimeout(function() {
43636						UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)');
43637						jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43638						jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started');
43639						jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43640					}, 300);
43641				break;
43642				case 2:
43643					OKEvents.utils.isFunction(options.onPause) && options.onPause();
43644					break;
43645				case 3:
43646					OKEvents.utils.isFunction(options.buffering) && options.buffering();
43647					break;
43648				case 5:
43649					OKEvents.utils.isFunction(options.cued) && options.cued();
43650					break;
43651				default:
43652					throw "OKVideo: received invalid data from YT player.";
43653			}
43654
43655			jQuery(window).trigger('okevents.y.change', [event]);
43656		},
43657		error: function(event) {
43658			throw event;
43659		}
43660	},
43661	v: {
43662		onReady: function(target) {
43663			if ( typeof options === 'undefined' ) {
43664				return true;
43665			}
43666			OKEvents.utils.isFunction(options.onReady) && options.onReady(target);
43667		},
43668		onPlay: function(player) {
43669			if ( typeof options === 'undefined' ) {
43670				return true;
43671			}
43672			if (!OKEvents.utils.isMobile()) player.setVolume(options.volume);
43673			OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
43674			jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43675			jQuery(player.element).closest('#page-header').addClass('video-started');
43676			jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43677		},
43678		onPause: function() {
43679			if ( typeof options === 'undefined' ) {
43680				return true;
43681			}
43682			OKEvents.utils.isFunction(options.onPause) && options.onPause();
43683		},
43684		onFinish: function() {
43685			if ( typeof options === 'undefined' ) {
43686				return true;
43687			}
43688			OKEvents.utils.isFunction(options.onFinish) && options.onFinish();
43689		}
43690	},
43691	utils: {
43692		isFunction: function(func) {
43693			if (typeof func === 'function') {
43694				return true;
43695			} else {
43696				return false;
43697			}
43698		},
43699		isMobile: function() {
43700			if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
43701				return true;
43702			} else {
43703				return false;
43704			}
43705		}
43706	}
43707};
43708/**
43709 * vivus - JavaScript library to make drawing animation on SVG
43710 * @version v0.4.4
43711 * @link https://github.com/maxwellito/vivus
43712 * @license MIT
43713 */
43714
43715'use strict';
43716
43717(function () {
43718
43719  'use strict';
43720
43721/**
43722 * Pathformer
43723 * Beta version
43724 *
43725 * Take any SVG version 1.1 and transform
43726 * child elements to 'path' elements
43727 *
43728 * This code is purely forked from
43729 * https://github.com/Waest/SVGPathConverter
43730 */
43731
43732/**
43733 * Class constructor
43734 *
43735 * @param {DOM|String} element Dom element of the SVG or id of it
43736 */
43737function Pathformer(element) {
43738  // Test params
43739  if (typeof element === 'undefined') {
43740	throw new Error('Pathformer [constructor]: "element" parameter is required');
43741  }
43742
43743  // Set the element
43744  if (element.constructor === String) {
43745	element = document.getElementById(element);
43746	if (!element) {
43747	  throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID');
43748	}
43749  }
43750  if (element instanceof window.SVGElement ||
43751	  element instanceof window.SVGGElement ||
43752	  /^svg$/i.test(element.nodeName)) {
43753	this.el = element;
43754  } else {
43755	throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement');
43756  }
43757
43758  // Start
43759  this.scan(element);
43760}
43761
43762/**
43763 * List of tags which can be transformed
43764 * to path elements
43765 *
43766 * @type {Array}
43767 */
43768Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect'];
43769
43770/**
43771 * List of attribute names which contain
43772 * data. This array list them to check if
43773 * they contain bad values, like percentage.
43774 *
43775 * @type {Array}
43776 */
43777Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 43777-44575
43777y1', 'y2'];
43778
43779/**
43780 * Finds the elements compatible for transform
43781 * and apply the liked method
43782 *
43783 * @param  {object} options Object from the constructor
43784 */
43785Pathformer.prototype.scan = function (svg) {
43786  var fn, element, pathData, pathDom,
43787	  elements = svg.querySelectorAll(this.TYPES.join(','));
43788
43789  for (var i = 0; i < elements.length; i++) {
43790	element = elements[i];
43791	fn = this[element.tagName.toLowerCase() + 'ToPath'];
43792	pathData = fn(this.parseAttr(element.attributes));
43793	pathDom = this.pathMaker(element, pathData);
43794	element.parentNode.replaceChild(pathDom, element);
43795  }
43796};
43797
43798
43799/**
43800 * Read `line` element to extract and transform
43801 * data, to make it ready for a `path` object.
43802 *
43803 * @param  {DOMelement} element Line element to transform
43804 * @return {object}			 Data for a `path` element
43805 */
43806Pathformer.prototype.lineToPath = function (element) {
43807  var newElement = {},
43808	  x1 = element.x1 || 0,
43809	  y1 = element.y1 || 0,
43810	  x2 = element.x2 || 0,
43811	  y2 = element.y2 || 0;
43812
43813  newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2;
43814  return newElement;
43815};
43816
43817/**
43818 * Read `rect` element to extract and transform
43819 * data, to make it ready for a `path` object.
43820 * The radius-border is not taken in charge yet.
43821 * (your help is more than welcomed)
43822 *
43823 * @param  {DOMelement} element Rect element to transform
43824 * @return {object}             Data for a `path` element
43825 */
43826Pathformer.prototype.rectToPath = function (element) {
43827  var newElement = {},
43828      x      = parseFloat(element.x)      || 0,
43829      y      = parseFloat(element.y)      || 0,
43830      width  = parseFloat(element.width)  || 0,
43831      height = parseFloat(element.height) || 0;
43832
43833  if (element.rx || element.ry) {
43834    var rx = parseInt(element.rx, 10) || -1,
43835        ry = parseInt(element.ry, 10) || -1;
43836    rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2);
43837    ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2);
43838
43839    newElement.d = 'M ' + (x + rx) + ',' + y + ' ' +
43840                   'L ' + (x + width - rx) + ',' + y + ' ' +
43841                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' +
43842                   'L ' + (x + width) + ',' + (y + height - ry) + ' ' +
43843                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' +
43844                   'L ' + (x + rx) + ',' + (y + height) + ' ' +
43845                   'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' +
43846                   'L ' + x + ',' + (y + ry) + ' ' +
43847                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y;
43848  }
43849  else {
43850    newElement.d = 'M' + x + ' ' + y + ' ' +
43851                   'L' + (x + width) + ' ' + y + ' ' +
43852                   'L' + (x + width) + ' ' + (y + height) + ' ' +
43853                   'L' + x + ' ' + (y + height) + ' Z';
43854  }
43855  return newElement;
43856};
43857
43858/**
43859 * Read `polyline` element to extract and transform
43860 * data, to make it ready for a `path` object.
43861 *
43862 * @param  {DOMelement} element Polyline element to transform
43863 * @return {object}             Data for a `path` element
43864 */
43865Pathformer.prototype.polylineToPath = function (element) {
43866  var newElement = {},
43867      points = element.points.trim().split(' '),
43868      i, path;
43869
43870  // Reformatting if points are defined without commas
43871  if (element.points.indexOf(',') === -1) {
43872    var formattedPoints = [];
43873    for (i = 0; i < points.length; i+=2) {
43874      formattedPoints.push(points[i] + ',' + points[i+1]);
43875    }
43876    points = formattedPoints;
43877  }
43878
43879  // Generate the path.d value
43880  path = 'M' + points[0];
43881  for(i = 1; i < points.length; i++) {
43882    if (points[i].indexOf(',') !== -1) {
43883      path += 'L' + points[i];
43884    }
43885  }
43886  newElement.d = path;
43887  return newElement;
43888};
43889
43890/**
43891 * Read `polygon` element to extract and transform
43892 * data, to make it ready for a `path` object.
43893 * This method rely on polylineToPath, because the
43894 * logic is similar. The path created is just closed,
43895 * so it needs an 'Z' at the end.
43896 *
43897 * @param  {DOMelement} element Polygon element to transform
43898 * @return {object}             Data for a `path` element
43899 */
43900Pathformer.prototype.polygonToPath = function (element) {
43901  var newElement = Pathformer.prototype.polylineToPath(element);
43902
43903  newElement.d += 'Z';
43904  return newElement;
43905};
43906
43907/**
43908 * Read `ellipse` element to extract and transform
43909 * data, to make it ready for a `path` object.
43910 *
43911 * @param  {DOMelement} element ellipse element to transform
43912 * @return {object}             Data for a `path` element
43913 */
43914Pathformer.prototype.ellipseToPath = function (element) {
43915  var newElement = {},
43916      rx = parseFloat(element.rx) || 0,
43917      ry = parseFloat(element.ry) || 0,
43918      cx = parseFloat(element.cx) || 0,
43919      cy = parseFloat(element.cy) || 0,
43920      startX = cx - rx,
43921      startY = cy,
43922      endX = parseFloat(cx) + parseFloat(rx),
43923      endY = cy;
43924
43925  newElement.d = 'M' + startX + ',' + startY +
43926                 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY +
43927                 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY;
43928  return newElement;
43929};
43930
43931/**
43932 * Read `circle` element to extract and transform
43933 * data, to make it ready for a `path` object.
43934 *
43935 * @param  {DOMelement} element Circle element to transform
43936 * @return {object}             Data for a `path` element
43937 */
43938Pathformer.prototype.circleToPath = function (element) {
43939  var newElement = {},
43940      r  = parseFloat(element.r)  || 0,
43941      cx = parseFloat(element.cx) || 0,
43942      cy = parseFloat(element.cy) || 0,
43943      startX = cx - r,
43944      startY = cy,
43945      endX = parseFloat(cx) + parseFloat(r),
43946      endY = cy;
43947
43948  newElement.d =  'M' + startX + ',' + startY +
43949                  'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY +
43950                  'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY;
43951  return newElement;
43952};
43953
43954/**
43955 * Create `path` elements form original element
43956 * and prepared objects
43957 *
43958 * @param  {DOMelement} element  Original element to transform
43959 * @param  {object} pathData     Path data (from `toPath` methods)
43960 * @return {DOMelement}          Path element
43961 */
43962Pathformer.prototype.pathMaker = function (element, pathData) {
43963  var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path');
43964  for(i = 0; i < element.attributes.length; i++) {
43965    attr = element.attributes[i];
43966    if (this.ATTR_WATCH.indexOf(attr.name) === -1) {
43967      pathTag.setAttribute(attr.name, attr.value);
43968    }
43969  }
43970  for(i in pathData) {
43971    pathTag.setAttribute(i, pathData[i]);
43972  }
43973  return pathTag;
43974};
43975
43976/**
43977 * Parse attributes of a DOM element to
43978 * get an object of attribute => value
43979 *
43980 * @param  {NamedNodeMap} attributes Attributes object from DOM element to parse
43981 * @return {object}                  Object of attributes
43982 */
43983Pathformer.prototype.parseAttr = function (element) {
43984  var attr, output = {};
43985  for (var i = 0; i < element.length; i++) {
43986    attr = element[i];
43987    // Check if no data attribute contains '%', or the transformation is impossible
43988    if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) {
43989      throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.');
43990    }
43991    output[attr.name] = attr.value;
43992  }
43993  return output;
43994};
43995
43996  'use strict';
43997
43998var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt;
43999
44000/**
44001 * Vivus
44002 * Beta version
44003 *
44004 * Take any SVG and make the animation
44005 * to give give the impression of live drawing
44006 *
44007 * This in more than just inspired from codrops
44008 * At that point, it's a pure fork.
44009 */
44010
44011/**
44012 * Class constructor
44013 * option structure
44014 *   type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed)
44015 *   duration: <int> (in frames)
44016 *   start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport)
44017 *   delay: <int> (delay between the drawing of first and last path)
44018 *   dashGap <integer> whitespace extra margin between dashes
44019 *   pathTimingFunction <function> timing animation function for each path element of the SVG
44020 *   animTimingFunction <function> timing animation function for the complete SVG
44021 *   forceRender <boolean> force the browser to re-render all updated path items
44022 *   selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original
44023 *
44024 * The attribute 'type' is by default on 'delayed'.
44025 *  - 'delayed'
44026 *    all paths are draw at the same time but with a
44027 *    little delay between them before start
44028 *  - 'sync'
44029 *    all path are start and finish at the same time
44030 *  - 'oneByOne'
44031 *    only one path is draw at the time
44032 *    the end of the first one will trigger the draw
44033 *    of the next one
44034 *
44035 * All these values can be overwritten individually
44036 * for each path item in the SVG
44037 * The value of frames will always take the advantage of
44038 * the duration value.
44039 * If you fail somewhere, an error will be thrown.
44040 * Good luck.
44041 *
44042 * @constructor
44043 * @this {Vivus}
44044 * @param {DOM|String}   element  Dom element of the SVG or id of it
44045 * @param {Object}       options  Options about the animation
44046 * @param {Function}     callback Callback for the end of the animation
44047 */
44048function Vivus (element, options, callback) {
44049
44050  setupEnv();
44051
44052  // Setup
44053  this.isReady = false;
44054  this.setElement(element, options);
44055  this.setOptions(options);
44056  this.setCallback(callback);
44057
44058  if (this.isReady) {
44059    this.init();
44060  }
44061}
44062
44063/**
44064 * Timing functions
44065 **************************************
44066 *
44067 * Default functions to help developers.
44068 * It always take a number as parameter (between 0 to 1) then
44069 * return a number (between 0 and 1)
44070 */
44071Vivus.LINEAR          = function (x) {return x;};
44072Vivus.EASE            = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;};
44073Vivus.EASE_OUT        = function (x) {return 1 - Math.pow(1-x, 3);};
44074Vivus.EASE_IN         = function (x) {return Math.pow(x, 3);};
44075Vivus.EASE_OUT_BOUNCE = function (x) {
44076  var base = -Math.cos(x * (0.5 * Math.PI)) + 1,
44077    rate = Math.pow(base,1.5),
44078    rateR = Math.pow(1 - x, 2),
44079    progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1;
44080  return (1- rateR) + (progress * rateR);
44081};
44082
44083
44084/**
44085 * Setters
44086 **************************************
44087 */
44088
44089/**
44090 * Check and set the element in the instance
44091 * The method will not return anything, but will throw an
44092 * error if the parameter is invalid
44093 *
44094 * @param {DOM|String}   element  SVG Dom element or id of it
44095 */
44096Vivus.prototype.setElement = function (element, options) {
44097  var onLoad, self;
44098
44099  // Basic check
44100  if (typeof element === 'undefined') {
44101    throw new Error('Vivus [constructor]: "element" parameter is required');
44102  }
44103
44104  // Set the element
44105  if (element.constructor === String) {
44106    element = document.getElementById(element);
44107    if (!element) {
44108      throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');
44109    }
44110  }
44111  this.parentEl = element;
44112
44113  // Load the SVG with XMLHttpRequest and extract the SVG
44114  if (options && options.file) {
44115    var self = this;
44116    onLoad = function (e) {
44117      var domSandbox = document.createElement('div');
44118      domSandbox.innerHTML = this.responseText;
44119
44120      var svgTag = domSandbox.querySelector('svg');
44121      if (!svgTag) {
44122        throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file);
44123      }
44124
44125      self.el = svgTag
44126      self.el.setAttribute('width', '100%');
44127      self.el.setAttribute('height', '100%');
44128      self.parentEl.appendChild(self.el)
44129      self.isReady = true;
44130      self.init();
44131      self = null;
44132    }
44133
44134    var oReq = new window.XMLHttpRequest();
44135    oReq.addEventListener('load', onLoad);
44136    oReq.open('GET', options.file);
44137    oReq.send();
44138    return;
44139  }
44140
44141  switch (element.constructor) {
44142  case window.SVGSVGElement:
44143  case window.SVGElement:
44144  case window.SVGGElement:
44145    this.el = element;
44146    this.isReady = true;
44147    break;
44148
44149  case window.HTMLObjectElement:
44150    self = this;
44151    onLoad = function (e) {
44152      if (self.isReady) {
44153        return;
44154      }
44155      self.el = element.contentDocument && element.contentDocument.querySelector('svg');
44156      if (!self.el && e) {
44157        throw new Error('Vivus [constructor]: object loaded does not contain any SVG');
44158      }
44159      else if (self.el) {
44160        if (element.getAttribute('built-by-vivus')) {
44161          self.parentEl.insertBefore(self.el, element);
44162          self.parentEl.removeChild(element);
44163          self.el.setAttribute('width', '100%');
44164          self.el.setAttribute('height', '100%');
44165        }
44166        self.isReady = true;
44167        self.init();
44168        self = null;
44169      }
44170    };
44171
44172    if (!onLoad()) {
44173      element.addEventListener('load', onLoad);
44174    }
44175    break;
44176
44177  default:
44178    throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)');
44179  }
44180};
44181
44182/**
44183 * Set up user option to the instance
44184 * The method will not return anything, but will throw an
44185 * error if the parameter is invalid
44186 *
44187 * @param  {object} options Object from the constructor
44188 */
44189Vivus.prototype.setOptions = function (options) {
44190  var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync'];
44191  var allowedStarts =  ['inViewport', 'manual', 'autostart'];
44192
44193  // Basic check
44194  if (options !== undefined && options.constructor !== Object) {
44195    throw new Error('Vivus [constructor]: "options" parameter must be an object');
44196  }
44197  else {
44198    options = options || {};
44199  }
44200
44201  // Set the animation type
44202  if (options.type && allowedTypes.indexOf(options.type) === -1) {
44203    throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`');
44204  }
44205  else {
44206    this.type = options.type || allowedTypes[0];
44207  }
44208
44209  // Set the start type
44210  if (options.start && allowedStarts.indexOf(options.start) === -1) {
44211    throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option');
44212  }
44213  else {
44214    this.start = options.start || allowedStarts[0];
44215  }
44216
44217  this.isIE         = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 );
44218  this.duration     = parsePositiveInt(options.duration, 120);
44219  this.delay        = parsePositiveInt(options.delay, null);
44220  //Uncode addition
44221  this.delayStart   = parsePositiveInt(options.delayStart, null);
44222  //#END
44223  this.dashGap      = parsePositiveInt(options.dashGap, 1);
44224  this.forceRender  = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE;
44225  this.reverseStack = !!options.reverseStack;
44226  this.selfDestroy  = !!options.selfDestroy;
44227  this.onReady      = options.onReady;
44228  this.map          = [];
44229  this.frameLength  = this.currentFrame = this.delayUnit = this.speed = this.handle = null;
44230
44231  this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false;
44232
44233  this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR;
44234  this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR;
44235
44236  if (this.delay >= this.duration) {
44237    throw new Error('Vivus [constructor]: delay must be shorter than duration');
44238  }
44239};
44240
44241/**
44242 * Set up callback to the instance
44243 * The method will not return enything, but will throw an
44244 * error if the parameter is invalid
44245 *
44246 * @param  {Function} callback Callback for the animation end
44247 */
44248Vivus.prototype.setCallback = function (callback) {
44249  // Basic check
44250  if (!!callback && callback.constructor !== Function) {
44251    throw new Error('Vivus [constructor]: "callback" parameter must be a function');
44252  }
44253  this.callback = callback || function () {};
44254};
44255
44256
44257/**
44258 * Core
44259 **************************************
44260 */
44261
44262/**
44263 * Map the svg, path by path.
44264 * The method return nothing, it just fill the
44265 * `map` array. Each item in this array represent
44266 * a path element from the SVG, with informations for
44267 * the animation.
44268 *
44269 * ```
44270 * [
44271 *   {
44272 *     el: <DOMobj> the path element
44273 *     length: <number> length of the path line
44274 *     startAt: <number> time start of the path animation (in frames)
44275 *     duration: <number> path animation duration (in frames)
44276 *   },
44277 *   ...
44278 * ]
44279 * ```
44280 *
44281 */
44282Vivus.prototype.mapping = function () {
44283  var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint;
44284  timePoint = totalLength = lengthMeter = 0;
44285  paths = this.el.querySelectorAll('path');
44286
44287  for (i = 0; i < paths.length; i++) {
44288    path = paths[i];
44289    if (this.isInvisible(path)) {
44290      continue;
44291    }
44292    pathObj = {
44293      el: path,
44294      length: Math.ceil(path.getTotalLength())
44295    };
44296    // Test if the path length is correct
44297    if (isNaN(pathObj.length)) {
44298      if (window.console && console.warn) {
44299        console.warn('Vivus [mapping]: cannot retrieve a path element length', path);
44300      }
44301      continue;
44302    }
44303    this.map.push(pathObj);
44304    path.style.strokeDasharray  = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2);
44305    path.style.strokeDashoffset = pathObj.length + this.dashGap;
44306    pathObj.length += this.dashGap;
44307    totalLength += pathObj.length;
44308
44309    this.renderPath(i);
44310  }
44311
44312  totalLength = totalLength === 0 ? 1 : totalLength;
44313  this.delay = this.delay === null ? this.duration / 3 : this.delay;
44314  this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1);
44315
44316  // Reverse stack if asked
44317  if (this.reverseStack) {
44318    this.map.reverse();
44319  }
44320
44321  for (i = 0; i < this.map.length; i++) {
44322    pathObj = this.map[i];
44323
44324    switch (this.type) {
44325    case 'delayed':
44326      pathObj.startAt = this.delayUnit * i;
44327      pathObj.duration = this.duration - this.delay;
44328      break;
44329
44330    case 'oneByOne':
44331      pathObj.startAt = lengthMeter / totalLength * this.duration;
44332      pathObj.duration = pathObj.length / totalLength * this.duration;
44333      break;
44334
44335    case 'sync':
44336    case 'async':
44337    case 'nsync':
44338      pathObj.startAt = 0;
44339      pathObj.duration = this.duration;
44340      break;
44341
44342    case 'scenario-sync':
44343      path = pathObj.el;
44344      pAttrs = this.parseAttr(path);
44345      pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0);
44346      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
44347      timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration;
44348      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
44349      break;
44350
44351    case 'scenario':
44352      path = pathObj.el;
44353      pAttrs = this.parseAttr(path);
44354      pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0;
44355      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
44356      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
44357      break;
44358    }
44359    lengthMeter += pathObj.length;
44360    this.frameLength = this.frameLength || this.duration;
44361  }
44362};
44363
44364/**
44365 * Interval method to draw the SVG from current
44366 * position of the animation. It update the value of
44367 * `currentFrame` and re-trace the SVG.
44368 *
44369 * It use this.handle to store the requestAnimationFrame
44370 * and clear it one the animation is stopped. So this
44371 * attribute can be used to know if the animation is
44372 * playing.
44373 *
44374 * Once the animation at the end, this method will
44375 * trigger the Vivus callback.
44376 *
44377 */
44378Vivus.prototype.drawer = function () {
44379  var self = this;
44380  this.currentFrame += this.speed;
44381
44382  if (this.currentFrame <= 0) {
44383    this.stop();
44384    this.reset();
44385  } else if (this.currentFrame >= this.frameLength) {
44386    this.stop();
44387    this.currentFrame = this.frameLength;
44388    this.trace();
44389    if (this.selfDestroy) {
44390      this.destroy();
44391    }
44392  } else {
44393    this.trace();
44394    this.handle = requestAnimFrame(function () {
44395      self.drawer();
44396    });
44397    return;
44398  }
44399
44400  this.callback(this);
44401  if (this.instanceCallback) {
44402    this.instanceCallback(this);
44403    this.instanceCallback = null;
44404  }
44405};
44406
44407/**
44408 * Draw the SVG at the current instant from the
44409 * `currentFrame` value. Here is where most of the magic is.
44410 * The trick is to use the `strokeDashoffset` style property.
44411 *
44412 * For optimisation reasons, a new property called `progress`
44413 * is added in each item of `map`. This one contain the current
44414 * progress of the path element. Only if the new value is different
44415 * the new value will be applied to the DOM element. This
44416 * method save a lot of resources to re-render the SVG. And could
44417 * be improved if the animation couldn't be played forward.
44418 *
44419 */
44420Vivus.prototype.trace = function () {
44421  var i, progress, path, currentFrame;
44422  currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength;
44423  for (i = 0; i < this.map.length; i++) {
44424    path = this.map[i];
44425    progress = (currentFrame - path.startAt) / path.duration;
44426    progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress)));
44427    if (path.progress !== progress) {
44428      path.progress = progress;
44429      path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress));
44430      this.renderPath(i);
44431    }
44432  }
44433};
44434
44435/**
44436 * Method forcing the browser to re-render a path element
44437 * from it's index in the map. Depending on the `forceRender`
44438 * value.
44439 * The trick is to replace the path element by it's clone.
44440 * This practice is not recommended because it's asking more
44441 * ressources, too much DOM manupulation..
44442 * but it's the only way to let the magic happen on IE.
44443 * By default, this fallback is only applied on IE.
44444 *
44445 * @param  {Number} index Path index
44446 */
44447Vivus.prototype.renderPath = function (index) {
44448  if (this.forceRender && this.map && this.map[index]) {
44449    var pathObj = this.map[index],
44450        newPath = pathObj.el.cloneNode(true);
44451    pathObj.el.parentNode.replaceChild(newPath, pathObj.el);
44452    pathObj.el = newPath;
44453  }
44454};
44455
44456/**
44457 * When the SVG object is loaded and ready,
44458 * this method will continue the initialisation.
44459 *
44460 * This this mainly due to the case of passing an
44461 * object tag in the constructor. It will wait
44462 * the end of the loading to initialise.
44463 *
44464 */
44465Vivus.prototype.init = function () {
44466  // Set object variables
44467  this.frameLength = 0;
44468  this.currentFrame = 0;
44469  this.map = [];
44470
44471  // Start
44472  new Pathformer(this.el);
44473  this.mapping();
44474  this.starter();
44475
44476  if (this.onReady) {
44477    this.onReady(this);
44478  }
44479};
44480
44481/**
44482 * Trigger to start of the animation.
44483 * Depending on the `start` value, a different script
44484 * will be applied.
44485 *
44486 * If the `start` value is not valid, an error will be thrown.
44487 * Even if technically, this is impossible.
44488 *
44489 */
44490Vivus.prototype.starter = function () {
44491  switch (this.start) {
44492  case 'manual':
44493    return;
44494
44495  case 'autostart':
44496    this.play();
44497    break;
44498
44499  case 'inViewport':
44500    var self = this,
44501    listener = function () {
44502      if (self.isInViewport(self.parentEl, 1)) {
44503        self.play();
44504        window.removeEventListener('scroll', listener);
44505        //Uncode addition
44506        window.removeEventListener('fp-slide-changed', listener);
44507        window.removeEventListener('fp-slide-scroll', listener);
44508        //#END
44509      }
44510    };
44511    window.addEventListener('scroll', listener);
44512    //Uncode addition
44513    window.addEventListener('fp-slide-changed', listener);
44514    window.addEventListener('fp-slide-scroll', listener);
44515    //#END
44516    listener();
44517    break;
44518  }
44519};
44520
44521
44522/**
44523 * Controls
44524 **************************************
44525 */
44526
44527/**
44528 * Get the current status of the animation between
44529 * three different states: 'start', 'progress', 'end'.
44530 * @return {string} Instance status
44531 */
44532Vivus.prototype.getStatus = function () {
44533  return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress';
44534};
44535
44536/**
44537 * Reset the instance to the initial state : undraw
44538 * Be careful, it just reset the animation, if you're
44539 * playing the animation, this won't stop it. But just
44540 * make it start from start.
44541 *
44542 */
44543Vivus.prototype.reset = function () {
44544  return this.setFrameProgress(0);
44545};
44546
44547/**
44548 * Set the instance to the final state : drawn
44549 * Be careful, it just set the animation, if you're
44550 * playing the animation on rewind, this won't stop it.
44551 * But just make it start from the end.
44552 *
44553 */
44554Vivus.prototype.finish = function () {
44555  return this.setFrameProgress(1);
44556};
44557
44558/**
44559 * Set the level of progress of the drawing.
44560 *
44561 * @param {number} progress Level of progress to set
44562 */
44563Vivus.prototype.setFrameProgress = function (progress) {
44564  progress = Math.min(1, Math.max(0, progress));
44565  this.currentFrame = Math.round(this.frameLength * progress);
44566  this.trace();
44567  return this;
44568};
44569
44570/**
44571 * Play the animation at the desired speed.
44572 * Speed must be a valid number (no zero).
44573 * By default, the speed value is 1.
44574 * But a negative value is accepted to go forward.
44575 *
44576 * And works with float too.
44577 * But don't forget we are in JavaScript, se be nice
44578 * with him and give him a 1/2^x value.
44579 *
44580 * @param  {number} speed Animation speed [optional]
44581 */
44582Vivus.prototype.play = function (speed, callback) {
44583  this.instanceCallback = null;
44584
44585  if (speed && typeof speed === 'function') {
44586    this.instanceCallback = speed; // first parameter is actually the callback function
44587    speed = null;
44588  }
44589  else if (speed && typeof speed !== 'number') {
44590    throw new Error('Vivus [play]: invalid speed');
44591  }
44592  // if the first parameter wasn't the callback, check if the seconds was
44593  if (callback && typeof(callback) === 'function' && !this.instanceCallback) {
44594    this.instanceCallback = callback;
44595  }
44596
44597
44598  this.speed = speed || 1;
44599  //Uncode addition
44600  if (!this.handle) {
44601    var $this = this,
44602    delay = (this.delayStart != null) ? this.delayStart : 0;
44603    setTimeout(function() {
44604      $this.drawer();
44605    }, delay);
44606  }
44607  //#END
44608  return this;
44609};
44610
44611/**
44612 * Stop the current animation, if on progress.
44613 * Should not trigger any error.
44614 *
44615 */
44616Vivus.prototype.stop = function () {
44617  if (this.handle) {
44618    cancelAnimFrame(this.handle);
44619    this.handle = null;
44620  }
44621  return this;
44622};
44623
44624/**
44625 * Destroy the instance.
44626 * Remove all bad styling attributes on all
44627 * path tags
44628 *
44629 */
44630Vivus.prototype.destroy = function () {
44631  this.stop();
44632  var i, path;
44633  for (i = 0; i < this.map.length; i++) {
44634    path = this.map[i];
44635    path.el.style.strokeDashoffset = null;
44636    path.el.style.strokeDasharray = null;
44637    this.renderPath(i);
44638  }
44639};
44640
44641
44642/**
44643 * Utils methods
44644 * include methods from Codrops
44645 **************************************
44646 */
44647
44648/**
44649 * Method to best guess if a path should added into
44650 * the animation or not.
44651 *
44652 * 1. Use the `data-vivus-ignore` attribute if set
44653 * 2. Check if the instance must ignore invisible paths
44654 * 3. Check if the path is visible
44655 *
44656 * For now the visibility checking is unstable.
44657 * It will be used for a beta phase.
44658 *
44659 * Other improvments are planned. Like detecting
44660 * is the path got a stroke or a valid opacity.
44661 */
44662Vivus.prototype.isInvisible = function (el) {
44663  var rect,
44664    ignoreAttr = el.getAttribute('data-ignore');
44665
44666  if (ignoreAttr !== null) {
44667    return ignoreAttr !== 'false';
44668  }
44669
44670  if (this.ignoreInvisible) {
44671    rect = el.getBoundingClientRect();
44672    return !rect.width && !rect.height;
44673  }
44674  else {
44675    return false;
44676  }
44677};
44678
44679/**
44680 * Parse attributes of a DOM element to
44681 * get an object of {attributeName => attributeValue}
44682 *
44683 * @param  {object} element DOM element to parse
44684 * @return {object}         Object of attributes
44685 */
44686Vivus.prototype.parseAttr = function (element) {
44687  var attr, output = {};
44688  if (element && element.attributes) {
44689    for (var i = 0; i < element.attributes.length; i++) {
44690      attr = element.attributes[i];
44691      output[attr.name] = attr.value;
44692    }
44693  }
44694  return output;
44695};
44696
44697/**
44698 * Reply if an element is in the page viewport
44699 *
44700 * @param  {object} el Element to observe
44701 * @param  {number} h  Percentage of height
44702 * @return {boolean}
44703 */
44704Vivus.prototype.isInViewport = function (el, h) {
44705  var scrolled   = this.scrollY(),
44706    viewed       = scrolled + this.getViewportH(),
44707    elBCR        = el.getBoundingClientRect(),
44708    elHeight     = elBCR.height,
44709    elTop        = scrolled + elBCR.top,
44710    elBottom     = elTop + elHeight;
44711
44712  // if 0, the element is considered in the viewport as soon as it enters.
44713  // if 1, the element is considered in the viewport only when it's fully inside
44714  // value in percentage (1 >= h >= 0)
44715  h = h || 0;
44716
44717  return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled;
44718};
44719
44720
44721/**
44722 * Get the viewport height in pixels
44723 *
44724 * @return {integer} Viewport height
44725 */
44726Vivus.prototype.getViewportH = function () {
44727  var client = this.docElem.clientHeight,
44728    inner = window.innerHeight;
44729
44730  if (client < inner) {
44731    return inner;
44732  }
44733  else {
44734    return client;
44735  }
44736};
44737
44738/**
44739 * Get the page Y offset
44740 *
44741 * @return {integer} Page Y offset
44742 */
44743Vivus.prototype.scrollY = function () {
44744  return window.pageYOffset || this.docElem.scrollTop;
44745};
44746
44747setupEnv = function () {
44748
44749  if (Vivus.prototype.docElem) {
44750    return;
44751  }
44752
44753  /**
44754   * Alias for document element
44755   *
44756   * @type {DOMelement}
44757   */
44758  Vivus.prototype.docElem = window.document.documentElement;
44759
44760  /**
44761   * Alias for `requestAnimationFrame` or
44762   * `setTimeout` function for deprecated browsers.
44763   *
44764   */
44765  requestAnimFrame = (function () {
44766    return (
44767      window.requestAnimationFrame       ||
44768      window.webkitRequestAnimationFrame ||
44769      window.mozRequestAnimationFrame    ||
44770      window.oRequestAnimationFrame      ||
44771      window.msRequestAnimationFrame     ||
44772      function(/* function */ callback){
44773        return window.setTimeout(callback, 1000 / 60);
44774      }
44775    );
44776  })();
44777
44778  /**
44779   * Alias for `cancelAnimationFrame` or
44780   * `cancelTimeout` function for deprecated browsers.
44781   *
44782   */
44783  cancelAnimFrame = (function () {
44784    return (
44785      window.cancelAnimationFrame       ||
44786      window.webkitCancelAnimationFrame ||
44787      window.mozCancelAnimationFrame    ||
44788      window.oCancelAnimationFrame      ||
44789      window.msCancelAnimationFrame     ||
44790      function(id){
44791        return window.clearTimeout(id);
44792      }
44793    );
44794  })();
44795};
44796
44797/**
44798 * Parse string to integer.
44799 * If the number is not positive or null
44800 * the method will return the default value
44801 * or 0 if undefined
44802 *
44803 * @param {string} value String to parse
44804 * @param {*}
44804 defaultValue Value to return if the result parsed is invalid
44805 * @return {number}
44806 *
44807 */
44808parsePositiveInt = function (value, defaultValue) {
44809  var output = parseInt(value, 10);
44810  return (output >= 0) ? output : defaultValue;
44811};
44812
44813
44814  if (typeof define === 'function' && define.amd) {
44815    // AMD. Register as an anonymous module.
44816    define([], function() {
44817      return Vivus;
44818    });
44819  } else if (typeof exports === 'object') {
44820    // Node. Does not work with strict CommonJS, but
44821    // only CommonJS-like environments that support module.exports,
44822    // like Node.
44823    module.exports = Vivus;
44824  } else {
44825    // Browser globals
44826    window.Vivus = Vivus;
44827  }
44828
44829}());
44830
44831//Noise.js
44832!function(){"use strict";var r=.5*(Math.sqrt(3)-1),e=(3-Math.sqrt(3))/6,t=1/6,a=(Math.sqrt(5)-1)/4,o=(5-Math.sqrt(5))/20;function i(r){var e;e="function"==typeof r?r:r?function(){var r=0,e=0,t=0,a=1,o=(i=4022871197,function(r){r=r.toString();for(var e=0;e<r.length;e++){var t=.02519603282416938*(i+=r.charCodeAt(e));t-=i=t>>>0,i=(t*=i)>>>0,i+=4294967296*(t-=i)}return 2.3283064365386963e-10*(i>>>0)});var i;r=o(" "),e=o(" "),t=o(" ");for(var n=0;n<arguments.length;n++)(r-=o(arguments[n]))<0&&(r+=1),(e-=o(arguments[n]))<0&&(e+=1),(t-=o(arguments[n]))<0&&(t+=1);return o=null,function(){var o=2091639*r+2.3283064365386963e-10*a;return r=e,e=t,t=o-(a=0|o)}}(r):Math.random,this.p=n(e),this.perm=new Uint8Array(512),this.permMod12=new Uint8Array(512);for(var t=0;t<512;t++)this.perm[t]=this.p[255&t],this.permMod12[t]=this.perm[t]%12}function n(r){var e,t=new Uint8Array(256);for(e=0;e<256;e++)t[e]=e;for(e=0;e<255;e++){var a=e+~~(r()*(256-e)),o=t[e];t[e]=t[a],t[a]=o}return t}i.prototype={grad3:new Float32Array([1,1,0,-1,1,0,1,-1,0,-1,-1,0,1,0,1,-1,0,1,1,0,-1,-1,0,-1,0,1,1,0,-1,1,0,1,-1,0,-1,-1]),grad4:new Float32Array([0,1,1,1,0,1,1,-1,0,1,-1,1,0,1,-1,-1,0,-1,1,1,0,-1,1,-1,0,-1,-1,1,0,-1,-1,-1,1,0,1,1,1,0,1,-1,1,0,-1,1,1,0,-1,-1,-1,0,1,1,-1,0,1,-1,-1,0,-1,1,-1,0,-1,-1,1,1,0,1,1,1,0,-1,1,-1,0,1,1,-1,0,-1,-1,1,0,1,-1,1,0,-1,-1,-1,0,1,-1,-1,0,-1,1,1,1,0,1,1,-1,0,1,-1,1,0,1,-1,-1,0,-1,1,1,0,-1,1,-1,0,-1,-1,1,0,-1,-1,-1,0]),noise2D:function(t,a){var o,i,n=this.permMod12,f=this.perm,s=this.grad3,v=0,h=0,l=0,u=(t+a)*r,d=Math.floor(t+u),p=Math.floor(a+u),M=(d+p)*e,m=t-(d-M),c=a-(p-M);m>c?(o=1,i=0):(o=0,i=1);var y=m-o+e,w=c-i+e,g=m-1+2*e,A=c-1+2*e,x=255&d,q=255&p,D=.5-m*m-c*c;if(D>=0){var S=3*n[x+f[q]];v=(D*=D)*D*(s[S]*m+s[S+1]*c)}var U=.5-y*y-w*w;if(U>=0){var b=3*n[x+o+f[q+i]];h=(U*=U)*U*(s[b]*y+s[b+1]*w)}var F=.5-g*g-A*A;if(F>=0){var N=3*n[x+1+f[q+1]];l=(F*=F)*F*(s[N]*g+s[N+1]*A)}return 70*(v+h+l)},noise3D:function(r,e,a){var o,i,n,f,s,v,h,l,u,d,p=this.permMod12,M=this.perm,m=this.grad3,c=(r+e+a)*(1/3),y=Math.floor(r+c),w=Math.floor(e+c),g=Math.floor(a+c),A=(y+w+g)*t,x=r-(y-A),q=e-(w-A),D=a-(g-A);x>=q?q>=D?(s=1,v=0,h=0,l=1,u=1,d=0):x>=D?(s=1,v=0,h=0,l=1,u=0,d=1):(s=0,v=0,h=1,l=1,u=0,d=1):q<D?(s=0,v=0,h=1,l=0,u=1,d=1):x<D?(s=0,v=1,h=0,l=0,u=1,d=1):(s=0,v=1,h=0,l=1,u=1,d=0);var S=x-s+t,U=q-v+t,b=D-h+t,F=x-l+2*t,N=q-u+2*t,C=D-d+2*t,P=x-1+.5,T=q-1+.5,_=D-1+.5,j=255&y,k=255&w,z=255&g,B=.6-x*x-q*q-D*D;if(B<0)o=0;else{var E=3*p[j+M[k+M[z]]];o=(B*=B)*B*(m[E]*x+m[E+1]*q+m[E+2]*D)}var G=.6-S*S-U*U-b*b;if(G<0)i=0;else{var H=3*p[j+s+M[k+v+M[z+h]]];i=(G*=G)*G*(m[H]*S+m[H+1]*U+m[H+2]*b)}var I=.6-F*F-N*N-C*C;if(I<0)n=0;else{var J=3*p[j+l+M[k+u+M[z+d]]];n=(I*=I)*I*(m[J]*F+m[J+1]*N+m[J+2]*C)}var K=.6-P*P-T*T-_*_;if(K<0)f=0;else{var L=3*p[j+1+M[k+1+M[z+1]]];f=(K*=K)*K*(m[L]*P+m[L+1]*T+m[L+2]*_)}return 32*(o+i+n+f)},noise4D:function(r,e,t,i){var n,f,s,v,h,l,u,d,p,M,m,c,y,w,g,A,x,q=this.perm,D=this.grad4,S=(r+e+t+i)*a,U=Math.floor(r+S),b=Math.floor(e+S),F=Math.floor(t+S),N=Math.floor(i+S),C=(U+b+F+N)*o,P=r-(U-C),T=e-(b-C),_=t-(F-C),j=i-(N-C),k=0,z=0,B=0,E=0;P>T?k++:z++,P>_?k++:B++,P>j?k++:E++,T>_?z++:B++,T>j?z++:E++,_>j?B++:E++;var G=P-(l=k>=3?1:0)+o,H=T-(u=z>=3?1:0)+o,I=_-(d=B>=3?1:0)+o,J=j-(p=E>=3?1:0)+o,K=P-(M=k>=2?1:0)+2*o,L=T-(m=z>=2?1:0)+2*o,O=_-(c=B>=2?1:0)+2*o,Q=j-(y=E>=2?1:0)+2*o,R=P-(w=k>=1?1:0)+3*o,V=T-(g=z>=1?1:0)+3*o,W=_-(A=B>=1?1:0)+3*o,X=j-(x=E>=1?1:0)+3*o,Y=P-1+4*o,Z=T-1+4*o,$=_-1+4*o,rr=j-1+4*o,er=255&U,tr=255&b,ar=255&F,or=255&N,ir=.6-P*P-T*T-_*_-j*j;if(ir<0)n=0;else{var nr=q[er+q[tr+q[ar+q[or]]]]%32*4;n=(ir*=ir)*ir*(D[nr]*P+D[nr+1]*T+D[nr+2]*_+D[nr+3]*j)}var fr=.6-G*G-H*H-I*I-J*J;if(fr<0)f=0;else{var sr=q[er+l+q[tr+u+q[ar+d+q[or+p]]]]%32*4;f=(fr*=fr)*fr*(D[sr]*G+D[sr+1]*H+D[sr+2]*I+D[sr+3]*J)}var vr=.6-K*K-L*L-O*O-Q*Q;if(vr<0)s=0;else{var hr=q[er+M+q[tr+m+q[ar+c+q[or+y]]]]%32*4;s=(vr*=vr)*vr*(D[hr]*K+D[hr+1]*L+D[hr+2]*O+D[hr+3]*Q)}
44832var lr=.6-R*R-V*V-W*W-X*X;if(lr<0)v=0;else{var ur=q[er+w+q[tr+g+q[ar+A+q[or+x]]]]%32*4;v=(lr*=lr)*lr*(D[ur]*R+D[ur+1]*V+D[ur+2]*W+D[ur+3]*X)}var dr=.6-Y*Y-Z*Z-$*$-rr*rr;if(dr<0)h=0;else{var pr=q[er+1+q[tr+1+q[ar+1+q[or+1]]]]%32*4;h=(dr*=dr)*dr*(D[pr]*Y+D[pr+1]*Z+D[pr+2]*$+D[pr+3]*rr)}return 27*(n+f+s+v+h)}},i._buildPermutationTable=n,"undefined"!=typeof define&&define.amd&&define(function(){return i}),"undefined"!=typeof exports?exports.SimplexNoise=i:"undefined"!=typeof window&&(window.SimplexNoise=i),"undefined"!=typeof module&&(module.exports=i)}();

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.