PageSourceSearch

https://www.apassodiliberazione.it/wp-content/themes/uncode/library/js/plugins.js?ver=1356822815

js apassodiliberazione.it collected 2026-10-02 21:25:02 UTC 1,481,849 bytes, 44,842 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: 15,202 bytes, lines 2077-2609
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) {
vendor: 9,840 bytes, lines 2610-2896
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
vendor: 4,984 bytes, lines 2897-3039
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: 23,480 bytes, lines 7386-8298
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() {
vendor: 13,499 bytes, lines 8299-8867
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
vendor: 29,252 bytes, lines 10292-11448
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 spaces
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: 15,066 bytes, lines 18038-18585
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:" 
vendor: 2,803 bytes, lines 18585-18657
18585+ 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: 4,563 bytes, lines 18769-18903
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 val
vendor: 17,473 bytes, lines 18903-19317
18903id 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) {
vendor: 4,223 bytes, lines 19318-19448
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, alt) {
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			} else if ( typeof alt !== 'undefined' ) {
22759				altApp = 'alt=\"' + alt + ' \" ';
22760			}
22761
22762			if ( thumbImg ) {
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            <img data-lg-item-id=\"" + index + "\" " + altApp + "src=\"" + thumbImg + "\" />\n        </div>";
22764			} else {
22765				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>";
22766			}
22767		};
22768		Thumbnail.prototype.getThumbItemHtml = function (items) {
22769			var thumbList = '';
22770			for (var i = 0; i < items.length; i++) {
22771				thumbList += this.getThumbHtml(items[i].thumb, i, items[i].alt);
22772			}
22773			return thumbList;
22774		};
22775		Thumbnail.prototype.setThumbItemHtml = function (items) {
22776			var thumbList = this.getThumbItemHtml(items);
22777			this.$lgThumb.html(thumbList);
22778		};
22779		Thumbnail.prototype.setAnimateThumbStyles = function () {
22780			if (this.settings.animateThumb) {
22781				this.core.outer.addClass('lg-animate-thumb');
22782			}
22783		};
22784		// Manage thumbnail active calss
22785		Thumbnail.prototype.manageActiveClassOnSlideChange = function () {
22786			var _this = this;
22787			// manage active class for thumbnail
22788			//Uncode edit ##START##
22789			// this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) {
22790			this.core.LGel.on(lGEvents.beforeSlide, function (event) {
22791			//Uncode edit ##END##
22792				var $thumb = _this.core.outer.find('.lg-thumb-item');
22793				var index = event.detail.index;
22794				$thumb.removeClass('active');
22795				$thumb.eq(index).addClass('active');
22796			});
22797		};
22798		// Toggle thumbnail bar
22799		Thumbnail.prototype.toggleThumbBar = function () {
22800			var _this = this;
22801			if (this.settings.toggleThumb) {
22802				this.core.outer.addClass('lg-can-toggle');
22803				this.core.$toolbar.append('<button type="button" aria-label="' +
22804					this.settings.thumbnailPluginStrings['toggleThumbnails'] +
22805					'" class="lg-toggle-thumb lg-icon"></button>');
22806				this.core.outer
22807					.find('.lg-toggle-thumb')
22808					.first()
22809					.on('click.lg', function () {
22810					_this.core.outer.toggleClass('lg-components-open');
22811				});
22812			}
22813		};
22814		Thumbnail.prototype.thumbKeyPress = function () {
22815			var _this = this;
22816			this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) {
22817				if (!_this.core.lgOpened || !_this.settings.toggleThumb)
22818					return;
22819				if (e.keyCode === 38) {
22820					e.preventDefault();
22821					_this.core.outer.addClass('lg-components-open');
22822				}
22823				else if (e.keyCode === 40) {
22824					e.preventDefault();
22825					_this.core.outer.removeClass('lg-components-open');
22826				}
22827			});
22828		};
22829		Thumbnail.prototype.destroy = function () {
22830			if (this.settings.thumbnail) {
22831				this.$LG(window).off(".lg.thumb.global" + this.core.lgId);
22832				this.core.LGel.off('.lg.thumb');
22833				this.core.LGel.off('.thumb');
22834				this.$thumbOuter.remove();
22835				this.core.outer.removeClass('lg-has-thumb');
22836			}
22837		};
22838		return Thumbnail;
22839	}());
22840
22841	return Thumbnail;
22842
22843})));
22844/*!
22845 * lightgallery | 2.5.0 | June 13th 2022
22846 * http://www.lightgalleryjs.com/
22847 * Copyright (c) 2020 Sachin Neravath;
22848 * @license GPLv3
22849 */
22850
22851(function (global, factory) {
22852	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
22853	typeof define === 'function' && define.amd ? define(factory) :
22854	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory());
22855}(this, (function () { 'use strict';
22856
22857	/*! *****************************************************************************
22858	Copyright (c) Microsoft Corporation.
22859
22860	Permission to use, copy, modify, and/or distribute this software for any
22861	purpose with or without fee is hereby granted.
22862
22863	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22864	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22865	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22866	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22867	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22868	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22869	PERFORMANCE OF THIS SOFTWARE.
22870	***************************************************************************** */
22871
22872	var __assign = function() {
22873		__assign = Object.assign || function __assign(t) {
22874			for (var s, i = 1, n = arguments.length; i < n; i++) {
22875				s = arguments[i];
22876				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
22877			}
22878			return t;
22879		};
22880		return __assign.apply(this, arguments);
22881	};
22882
22883	var videoSettings = {
22884		autoplayFirstVideo: true,
22885		youTubePlayerParams: false,
22886		vimeoPlayerParams: false,
22887		wistiaPlayerParams: false,
22888		gotoNextSlideOnVideoEnd: true,
22889		autoplayVideoOnSlide: false,
22890		videojs: false,
22891		videojsTheme: '',
22892		videojsOptions: {},
22893	};
22894
22895	/**
22896	 * List of lightGallery events
22897	 * All events should be documented here
22898	 * Below interfaces are used to build the website documentations
22899	 * */
22900	var lGEvents = {
22901		afterAppendSlide: 'lgAfterAppendSlide',
22902		init: 'lgInit',
22903		hasVideo: 'lgHasVideo',
22904		containerResize: 'lgContainerResize',
22905		updateSlides: 'lgUpdateSlides',
22906		afterAppendSubHtml: 'lgAfterAppendSubHtml',
22907		beforeOpen: 'lgBeforeOpen',
22908		afterOpen: 'lgAfterOpen',
22909		slideItemLoad: 'lgSlideItemLoad',
22910		beforeSlide: 'lgBeforeSlide',
22911		afterSlide: 'lgAfterSlide',
22912		posterClick: 'lgPosterClick',
22913		dragStart: 'lgDragStart',
22914		dragMove: 'lgDragMove',
22915		dragEnd: 'lgDragEnd',
22916		beforeNextSlide: 'lgBeforeNextSlide',
22917		beforePrevSlide: 'lgBeforePrevSlide',
22918		beforeClose: 'lgBeforeClose',
22919		afterClose: 'lgAfterClose',
22920		rotateLeft: 'lgRotateLeft',
22921		rotateRight: 'lgRotateRight',
22922		flipHorizontal: 'lgFlipHorizontal',
22923		flipVertical: 'lgFlipVertical',
22924		autoplay: 'lgAutoplay',
22925		autoplayStart: 'lgAutoplayStart',
22926		autoplayStop: 'lgAutoplayStop',
22927	};
22928
22929	var param = function (obj) {
22930		return Object.keys(obj)
22931			.map(function (k) {
22932			return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]);
22933		})
22934			.join('&');
22935	};
22936	var getVimeoURLParams = function (defaultParams, videoInfo) {
22937		if (!videoInfo || !videoInfo.vimeo)
22938			return '';
22939		var urlParams = videoInfo.vimeo[2] || '';
22940		var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0
22941			? '&' + param(defaultParams)
22942			: '';
22943		// Support private video
22944		var urlWithHash = videoInfo.vimeo[0].split('/').pop() || '';
22945		var urlWithHashWithParams = urlWithHash.split('?')[0] || '';
22946		var hash = urlWithHashWithParams.split('#')[0];
22947		var isPrivate = videoInfo.vimeo[1] !== hash;
22948		if (isPrivate) {
22949			urlParams = urlParams.replace("/" + hash, '');
22950		}
22951		urlParams =
22952			urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || '';
22953		// For vimeo last params gets priority if duplicates found
22954		// Uncode edit ##START##
22955		var vimeoPlayerParams = '?autoplay=0';
22956		if ( videoInfo.autoplay !== '' ) {
22957			vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' );
22958			vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' );
22959		} else {
22960			if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) {
22961				vimeoPlayerParams = SiteParameters.vimeoPlayerParams;
22962			}
22963		}
22964		if ( videoInfo.muted !== '' ) {
22965			vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes');
22966		} else {
22967			if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) {
22968				vimeoPlayerParams += '&muted=1';
22969			}
22970		}
22971		// var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams;
22972		vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams;
22973		// Uncode edit ##END##
22974		return vimeoPlayerParams;
22975	};
22976
22977	/**
22978	 * Video module for lightGallery
22979	 * Supports HTML5, YouTube, Vimeo, wistia videos
22980	 *
22981	 *
22982	 * @ref Wistia
22983	 * https://wistia.com/support/integrations/wordpress(How to get url)
22984	 * https://wistia.com/support/developers/embed-options#using-embed-options
22985	 * https://wistia.com/support/developers/player-api
22986	 * https://wistia.com/support/developers/construct-an-embed-code
22987	 * http://jsfiddle.net/xvnm7xLm/
22988	 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
22989	 * https://wistia.com/support/embed-and-share/sharing-videos
22990	 * https://private-sharing.wistia.com/medias/mwhrulrucj
22991	 *
22992	 * @ref Youtube
22993	 * https://developers.google.com/youtube/player_parameters#enablejsapi
22994	 * https://developers.google.com/youtube/iframe_api_reference
22995	 * https://developer.chrome.com/blog/autoplay/#iframe-delegation
22996	 *
22997	 * @ref Vimeo
22998	 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url
22999	 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode
23000	 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters
23001	 */
23002	var Video = /** @class */ (function () {
23003		function Video(instance) {
23004			// get lightGallery core plugin instance
23005			this.core = instance;
23006			this.settings = __assign(__assign({}, videoSettings), this.core.settings);
23007			return this;
23008		}
23009		Video.prototype.init = function () {
23010			var _this = this;
23011			/**
23012			 * Event triggered when video url found without poster
23013			 * Append video HTML
23014			 * Play if autoplayFirstVideo is true
23015			 */
23016			this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this));
23017			this.core.LGel.on(lGEvents.posterClick + ".video", function () {
23018				var $el = _this.core.getSlideItem(_this.core.index);
23019				_this.loadVideoOnPosterClick($el);
23020			});
23021			this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this));
23022			// @desc fired immediately before each slide transition.
23023			this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this));
23024			// @desc fired immediately after each slide transition.
23025			this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this));
23026		};
23027		/**
23028		 * @desc Event triggered when a slide is completely loaded
23029		 *
23030		 * @param {Event} event - lightGalley custom event
23031		 */
23032		Video.prototype.onSlideItemLoad = function (event) {
23033			var _this = this;
23034			var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index;
23035			// Should check the active slide as well as user may have moved to different slide before the first slide is loaded
23036			if (this.settings.autoplayFirstVideo &&
23037				isFirstSlide &&
23038				index === this.core.index) {
23039				// Delay is just for the transition effect on video load
23040				setTimeout(function () {
23041					_this.loadAndPlayVideo(index);
23042				}, 200);
23043			}
23044			// Should not call on first slide. should check only if the slide is active
23045			if (!isFirstSlide &&
23046				this.settings.autoplayVideoOnSlide &&
23047				index === this.core.index) {
23048					setTimeout(function () {
23049						_this.loadAndPlayVideo(index);
23050					}, 500);
23051				}
23052		};
23053		/**
23054		 * @desc Event triggered when video url or poster found
23055		 * Append video HTML is poster is not given
23056		 * Play if autoplayFirstVideo is true
23057		 *
23058		 * @param {Event} event - Javascript Event object.
23059		 */
23060		Video.prototype.onHasVideo = function (event) {
23061			var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster;
23062			if (!hasPoster) {
23063				// All functions are called separately if poster exist in loadVideoOnPosterClick function
23064				this.appendVideos(this.core.getSlideItem(index), {
23065					src: src,
23066					addClass: 'lg-object',
23067					index: index,
23068					html5Video: html5Video,
23069					// Uncode edit ##START##
23070					autoplay: event.target.getAttribute('data-lb-autoplay'),
23071					muted: event.target.getAttribute('data-lb-muted'),
23072					// Uncode edit ##END##
23073				});
23074				// Automatically navigate to next slide once video reaches the end.
23075				this.gotoNextSlideOnVideoEnd(src, index);
23076			}
23077		};
23078		/**
23079		 * @desc fired immediately before each slide transition.
23080		 * Pause the previous video
23081		 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos.
23082		 *
23083		 * @param {Event} event - Javascript Event object.
23084		 * @param {number} prevIndex - Previous index of the slide.
23085		 * @param {number} index - Current index of the slide
23086		 */
23087		Video.prototype.onBeforeSlide = function (event) {
23088			if (this.core.lGalleryOn) {
23089				var prevIndex = event.detail.prevIndex;
23090				this.pauseVideo(prevIndex);
23091			}
23092			// Uncode edit ##START##
23093			var _a = event.detail, index = _a.index;
23094			var $slide = this.core.getSlideItem(index);
23095			
23096			var iframe = $slide.selector.querySelector('iframe');
23097			if ( iframe != null ) {
23098
23099				var data_play = iframe.getAttribute('data-autoplay');
23100				if ( typeof data_play !== 'undefined' && data_play === '1' ) {
23101					this.loadAndPlayVideo(index);
23102
23103					var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {},
23104						$videoElement = this.core.getSlideItem(index).find('.lg-video-object').first();
23105					if (videoInfo.vimeo) {
23106						var vimeoPlayer = new Vimeo.Player($videoElement.get());
23107						vimeoPlayer.on('play', function () {
23108							vimeoPlayer.setCurrentTime(0);
23109						});
23110					} else if ( videoInfo.youtube ) {
23111						try {
23112							$videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*');
23113						}
23114						catch (e) {
23115							console.warn(e);
23116						}
23117					}
23118				}
23119			}
23120			// Uncode edit ##END##
23121		};
23122		/**
23123		 * @desc fired immediately after each slide transition.
23124		 * Play video if autoplayVideoOnSlide option is enabled.
23125		 *
23126		 * @param {Event} event - Javascript Event object.
23127		 * @param {number} prevIndex - Previous index of the slide.
23128		 * @param {number} index - Current index of the slide
23129		 * @todo should check on onSlideLoad as well if video is not loaded on after slide
23130		 */
23131		Video.prototype.onAfterSlide = function (event) {
23132			var _this = this;
23133			var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex;
23134			// Do not call on first slide
23135			var $slide = this.core.getSlideItem(index);
23136			if (this.settings.autoplayVideoOnSlide && index !== prevIndex) {
23137				if ($slide.hasClass('lg-complete')) {
23138					setTimeout(function () {
23139						_this.loadAndPlayVideo(index);
23140					}, 100);
23141				}
23142			}
23143		};
23144		Video.prototype.loadAndPlayVideo = function (index) {
23145			var $slide = this.core.getSlideItem(index);
23146			var currentGalleryItem = this.core.galleryItems[index];
23147			if (currentGalleryItem.poster) {
23148				this.loadVideoOnPosterClick($slide, true);
23149			}
23150			else {
23151				//Uncode edit ##START##
23152				// this.playVideo(index);
23153				var iframe = $slide.selector.querySelector('iframe');
23154				if ( iframe != null ) {
23155					var data_play = iframe.getAttribute('data-autoplay');
23156					if ( typeof data_play !== 'undefined' ) {
23157						if ( data_play === '1' && this.core.index == index ) {
23158							this.playVideo(index);
23159						} else {
23160							this.pauseVideo(index);
23161						}
23162					}
23163				}
23164				//Uncode edit ##END##
23165			}
23166		};
23167		/**
23168		 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
23169		 * @param {number} index - Index of the slide
23170		 */
23171		Video.prototype.playVideo = function (index) {
23172			this.controlVideo(index, 'play');
23173		};
23174		/**
23175		 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
23176		 * @param {number} index - Index of the slide
23177		 */
23178		Video.prototype.pauseVideo = function (index) {
23179			this.controlVideo(index, 'pause');
23180		};
23181		// Uncode edit ##START##
23182		//Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) {
23183		Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) {
23184		// Uncode edit ##END##
23185			var video = '';
23186			var videoInfo = this.core.galleryItems[index]
23187				.__slideVideoInfo || {};
23188			var currentGalleryItem = this.core.galleryItems[index];
23189			var videoTitle = currentGalleryItem.title || currentGalleryItem.alt;
23190			videoTitle = videoTitle ? 'title="' + videoTitle + '"' : '';
23191			var commonIframeProps = "allowtransparency=\"true\"\n            frameborder=\"0\"\n            scrolling=\"no\"\n            allowfullscreen\n            mozallowfullscreen\n            webkitallowfullscreen\n            oallowfullscreen\n            msallowfullscreen";
23192			if (videoInfo.youtube) {
23193				var videoId = 'lg-youtube' + index;
23194				var slideUrlParams = videoInfo.youtube[2]
23195					? videoInfo.youtube[2] + '&'
23196					: '';
23197				// For youtube first parms gets priority if duplicates found
23198				// Uncode edit ##START##
23199				// var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1";
23200				var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1";
23201				if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) {
23202					youTubePlayerParams += '&autoplay=0';
23203				}
23204				if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) {
23205					youTubePlayerParams += '&mute=1';
23206				}
23207				var data_video = '';
23208				if ( autoplay !== '' ) {
23209					//youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' );
23210					youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' );
23211					youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' );
23212					data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"';
23213				}
23214				// if ( muted !== '' ) {
23215				// 	youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' );
23216				// }
23217				youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' );
23218
23219				youTubePlayerParams = youTubePlayerParams.replace('??', '?');
23220				// Uncode edit ##END##
23221				var playerParams = youTubePlayerParams +
23222					(this.settings.youTubePlayerParams
23223						? '&' + param(this.settings.youTubePlayerParams)
23224						: '');
23225				// Uncode edit ##START##
23226				// 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>";
23227				var nocookie = typeof SiteParameters.uncode_nocookie !== 'undefined' ? SiteParameters.uncode_nocookie : '';
23228				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>";
23229				var tag = document.createElement('script');
23230				tag.src = "//www.youtube.com/player_api";
23231				var firstScriptTag = document.getElementsByTagName('script')[0];
23232				firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
23233
23234				// Replace the 'ytplayer' element with an <iframe> and
23235				// YouTube player after the API code downloads.
23236				var ytIframeplayer,
23237					setMute = muted === 'yes' ? 0 : 100;
23238				window.onYouTubePlayerAPIReady = function() {
23239					ytIframeplayer = new YT.Player(videoId, {
23240						videoId: videoInfo.youtube[1],
23241						events: {
23242							'onReady': function (event) {
23243								event.target.setVolume(setMute);
23244							}
23245						}
23246					});
23247				}
23248				// Uncode edit ##END##
23249			}
23250			else if (videoInfo.vimeo) {
23251				var videoId = 'lg-vimeo' + index;
23252				// Uncode edit ##START##
23253				videoInfo.autoplay = autoplay;
23254				videoInfo.muted = muted;
23255				// Uncode edit ##END##
23256				var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo);
23257				// Uncode edit ##START##
23258				// 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>";
23259				var data_video = '';
23260				if ( autoplay !== '' ) {
23261					data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"';
23262				}
23263				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>";
23264				// Uncode edit ##END##
23265			}
23266			else if (videoInfo.wistia) {
23267				var wistiaId = 'lg-wistia' + index;
23268				var playerParams = param(this.settings.wistiaPlayerParams);
23269				playerParams = playerParams ? '?' + playerParams : '';
23270				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>";
23271			}
23272			else if (videoInfo.html5) {
23273				var html5VideoMarkup = '';
23274				for (var i = 0; i < html5Video.source.length; i++) {
23275					html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">";
23276				}
23277				if (html5Video.tracks) {
23278					var _loop_1 = function (i) {
23279						var trackAttributes = '';
23280						var track = html5Video.tracks[i];
23281						Object.keys(track || {}
23281).forEach(function (key) {
23282							trackAttributes += key + "=\"" + track[key] + "\" ";
23283						});
23284						html5VideoMarkup += "<track " + trackAttributes + ">";
23285					};
23286					for (var i = 0; i < html5Video.tracks.length; i++) {
23287						_loop_1(i);
23288					}
23289				}
23290				var html5VideoAttrs_1 = '';
23291				var videoAttributes_1 = html5Video.attributes || {};
23292				Object.keys(videoAttributes_1 || {}).forEach(function (key) {
23293					html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" ";
23294				});
23295				video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme
23296					? this.settings.videojsTheme + ' '
23297					: '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n                " + html5VideoMarkup + "\n                Your browser does not support HTML5 video.\n            </video>";
23298			}
23299			return video;
23300		};
23301		/**
23302		 * @desc - Append videos to the slide
23303		 *
23304		 * @param {HTMLElement} el - slide element
23305		 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo
23306		 */
23307		Video.prototype.appendVideos = function (el, videoParams) {
23308			var _a;
23309			// Uncode edit ##START##
23310			// var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video);
23311			var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted);
23312			// Uncode edit ##END##
23313			el.find('.lg-video-cont').append(videoHtml);
23314			var $videoElement = el.find('.lg-video-object').first();
23315			if (videoParams.html5Video) {
23316				$videoElement.on('mousedown.lg.video', function (e) {
23317					e.stopPropagation();
23318				});
23319			}
23320			if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) {
23321				try {
23322					return videojs($videoElement.get(), this.settings.videojsOptions);
23323				}
23324				catch (e) {
23325					console.warn('lightGallery:- Make sure you have included videojs');
23326				}
23327			}
23328		};
23329		Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) {
23330			var _this = this;
23331			var $videoElement = this.core
23332				.getSlideItem(index)
23333				.find('.lg-video-object')
23334				.first();
23335			var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
23336			if (this.settings.gotoNextSlideOnVideoEnd) {
23337				if (videoInfo.html5) {
23338					$videoElement.on('ended', function () {
23339						_this.core.goToNextSlide();
23340					});
23341				}
23342				else if (videoInfo.vimeo) {
23343					try {
23344						// https://github.com/vimeo/player.js/#ended
23345						new Vimeo.Player($videoElement.get()).on('ended', function () {
23346							_this.core.goToNextSlide();
23347						});
23348					}
23349					catch (e) {
23350						console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
23351					}
23352				}
23353				else if (videoInfo.wistia) {
23354					try {
23355						window._wq = window._wq || [];
23356						// @todo Event is gettign triggered multiple times
23357						window._wq.push({
23358							id: $videoElement.attr('id'),
23359							onReady: function (video) {
23360								video.bind('end', function () {
23361									_this.core.goToNextSlide();
23362								});
23363							},
23364						});
23365					}
23366					catch (e) {
23367						console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
23368					}
23369				}
23370			}
23371		};
23372		Video.prototype.controlVideo = function (index, action) {
23373			var $videoElement = this.core
23374				.getSlideItem(index)
23375				.find('.lg-video-object')
23376				.first();
23377			var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
23378			if (!$videoElement.get())
23379				return;
23380			if (videoInfo.youtube) {
23381				try {
23382					$videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*');
23383				}
23384				catch (e) {
23385					console.warn("lightGallery:- " + e);
23386				}
23387			}
23388			else if (videoInfo.vimeo) {
23389				try {
23390					new Vimeo.Player($videoElement.get())[action]();
23391				}
23392				catch (e) {
23393					console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
23394				}
23395			}
23396			else if (videoInfo.html5) {
23397				if (this.settings.videojs) {
23398					try {
23399						videojs($videoElement.get())[action]();
23400					}
23401					catch (e) {
23402						console.warn('lightGallery:- Make sure you have included videojs');
23403					}
23404				}
23405				else {
23406					$videoElement.get()[action]();
23407				}
23408			}
23409			else if (videoInfo.wistia) {
23410				try {
23411					window._wq = window._wq || [];
23412					// @todo Find a way to destroy wistia player instance
23413					window._wq.push({
23414						id: $videoElement.attr('id'),
23415						onReady: function (video) {
23416							video[action]();
23417						},
23418					});
23419				}
23420				catch (e) {
23421					console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
23422				}
23423			}
23424		};
23425		Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) {
23426			var _this = this;
23427			// check slide has poster
23428			if (!$el.hasClass('lg-video-loaded')) {
23429				// check already video element present
23430				if (!$el.hasClass('lg-has-video')) {
23431					$el.addClass('lg-has-video');
23432					var _html = void 0;
23433					var _src = this.core.galleryItems[this.core.index].src;
23434					var video = this.core.galleryItems[this.core.index].video;
23435					if (video) {
23436						_html =
23437							typeof video === 'string' ? JSON.parse(video) : video;
23438					}
23439					var videoJsPlayer_1 = this.appendVideos($el, {
23440						src: _src,
23441						addClass: '',
23442						index: this.core.index,
23443						html5Video: _html,
23444					});
23445					this.gotoNextSlideOnVideoEnd(_src, this.core.index);
23446					var $tempImg = $el.find('.lg-object').first().get();
23447					// @todo make sure it is working
23448					$el.find('.lg-video-cont').first().append($tempImg);
23449					$el.addClass('lg-video-loading');
23450					videoJsPlayer_1 &&
23451						videoJsPlayer_1.ready(function () {
23452							videoJsPlayer_1.on('loadedmetadata', function () {
23453								_this.onVideoLoadAfterPosterClick($el, _this.core.index);
23454							});
23455						});
23456					$el.find('.lg-video-object')
23457						.first()
23458						.on('load.lg error.lg loadedmetadata.lg', function () {
23459						setTimeout(function () {
23460							_this.onVideoLoadAfterPosterClick($el, _this.core.index);
23461						}, 50);
23462					});
23463				}
23464				else {
23465					this.playVideo(this.core.index);
23466				}
23467			}
23468			else if (forcePlay) {
23469				this.playVideo(this.core.index);
23470			}
23471		};
23472		Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) {
23473			$el.addClass('lg-video-loaded');
23474			this.playVideo(index);
23475		};
23476		Video.prototype.destroy = function () {
23477			this.core.LGel.off('.lg.video');
23478			this.core.LGel.off('.video');
23479		};
23480		return Video;
23481	}());
23482
23483	return Video;
23484
23485})));
23486
23487
23488/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */
23489!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:{}}
23489),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 23489
23489var 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)}
23489},{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: 6,940 bytes, lines 23489-23816
23489))}(),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});
23490
23491/**
23492 * Owl carousel
23493 * @version 2.0.0-beta.3
23494 * @author Bartosz Wojciechowski
23495 * @license The MIT License (MIT)
23496 * @todo Lazy Load Icon
23497 * @todo prevent animationend bubling
23498 * @todo itemsScaleUp
23499 * @todo Test Zepto
23500 * @todo stagePadding calculate wrong active classes
23501 */
23502;(function($, window, document, undefined) {
23503
23504	/**
23505	 * Creates a carousel.
23506	 * @class The Owl Carousel.
23507	 * @public
23508	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
23509	 * @param {Object} [options] - The options
23510	 */
23511	function Owl(element, options) {
23512
23513		/**
23514		 * Current settings for the carousel.
23515		 * @public
23516		 */
23517		this.settings = null;
23518
23519		/**
23520		 * Current options set by the caller including defaults.
23521		 * @public
23522		 */
23523		this.options = $.extend({}, Owl.Defaults, options);
23524
23525		/**
23526		 * Plugin element.
23527		 * @public
23528		 */
23529		this.$element = $(element);
23530
23531		/**
23532		 * Proxied event handlers.
23533		 * @protected
23534		 */
23535		this._handlers = {};
23536
23537		/**
23538		 * References to the running plugins of this carousel.
23539		 * @protected
23540		 */
23541		this._plugins = {};
23542
23543		/**
23544		 * Currently suppressed events to prevent them from beeing retriggered.
23545		 * @protected
23546		 */
23547		this._supress = {};
23548
23549		/**
23550		 * Absolute current position.
23551		 * @protected
23552		 */
23553		this._current = null;
23554
23555		/**
23556		 * Animation speed in milliseconds.
23557		 * @protected
23558		 */
23559		this._speed = null;
23560
23561		/**
23562		 * Coordinates of all items in pixel.
23563		 * @todo The name of this member is missleading.
23564		 * @protected
23565		 */
23566		this._coordinates = [];
23567
23568		/**
23569		 * Current breakpoint.
23570		 * @todo Real media queries would be nice.
23571		 * @protected
23572		 */
23573		this._breakpoint = null;
23574
23575		/**
23576		 * Current width of the plugin element.
23577		 */
23578		this._width = null;
23579
23580		/**
23581		 * All real items.
23582		 * @protected
23583		 */
23584		this._items = [];
23585
23586		/**
23587		 * All cloned items.
23588		 * @protected
23589		 */
23590		this._clones = [];
23591
23592		/**
23593		 * Merge values of all items.
23594		 * @todo Maybe this could be part of a plugin.
23595		 * @protected
23596		 */
23597		this._mergers = [];
23598
23599		/**
23600		 * Widths of all items.
23601		 */
23602		this._widths = [];
23603
23604		/**
23605		 * Invalidated parts within the update process.
23606		 * @protected
23607		 */
23608		this._invalidated = {};
23609
23610		/**
23611		 * Ordered list of workers for the update process.
23612		 * @protected
23613		 */
23614		this._pipe = [];
23615
23616		/**
23617		 * Current state information for the drag operation.
23618		 * @todo #261
23619		 * @protected
23620		 */
23621		this._drag = {
23622			time: null,
23623			target: null,
23624			pointer: null,
23625			stage: {
23626				start: null,
23627				current: null
23628			},
23629			direction: null
23630		};
23631
23632		/**
23633		 * Current state information and their tags.
23634		 * @type {Object}
23635		 * @protected
23636		 */
23637		this._states = {
23638			current: {},
23639			tags: {
23640				'initializing': [ 'busy' ],
23641				'animating': [ 'busy' ],
23642				'dragging': [ 'interacting' ]
23643			}
23644		};
23645
23646		$.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
23647			this._handlers[handler] = $.proxy(this[handler], this);
23648		}, this));
23649
23650		$.each(Owl.Plugins, $.proxy(function(key, plugin) {
23651			this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
23652				= new plugin(this);
23653		}, this));
23654
23655		$.each(Owl.Workers, $.proxy(function(priority, worker) {
23656			this._pipe.push({
23657				'filter': worker.filter,
23658				'run': $.proxy(worker.run, this)
23659			});
23660		}, this));
23661
23662		this.setup();
23663		this.initialize();
23664	}
23665
23666	/**
23667	 * Default options for the carousel.
23668	 * @public
23669	 */
23670	Owl.Defaults = {
23671		items: 3,
23672		loop: false,
23673		center: false,
23674		rewind: false,
23675
23676		mouseDrag: true,
23677		touchDrag: true,
23678		pullDrag: true,
23679		freeDrag: false,
23680
23681		margin: 0,
23682		stagePadding: 0,
23683
23684		merge: false,
23685		mergeFit: true,
23686		autoWidth: false,
23687
23688		startPosition: 0,
23689		rtl: false,
23690
23691		smartSpeed: 250,
23692		fluidSpeed: false,
23693		dragEndSpeed: false,
23694
23695		responsive: {},
23696		responsiveRefreshRate: 200,
23697		responsiveBaseElement: window,
23698
23699		fallbackEasing: 'swing',
23700
23701		info: false,
23702
23703		nestedItemSelector: false,
23704		itemSelector: false,
23705		itemElement: 'div',
23706		stageElement: 'div',
23707
23708		refreshClass: 'owl-refresh',
23709		loadedClass: 'owl-loaded',
23710		loadingClass: 'owl-loading',
23711		rtlClass: 'owl-rtl',
23712		responsiveClass: 'owl-responsive',
23713		dragClass: 'owl-drag',
23714		itemClass: 'owl-item',
23715		stageClass: 'owl-stage',
23716		stageOuterClass: 'owl-stage-outer',
23717		grabClass: 'owl-grab'
23718	};
23719
23720	/**
23721	 * Enumeration for width.
23722	 * @public
23723	 * @readonly
23724	 * @enum {String}
23725	 */
23726	Owl.Width = {
23727		Default: 'default',
23728		Inner: 'inner',
23729		Outer: 'outer'
23730	};
23731
23732	/**
23733	 * Enumeration for types.
23734	 * @public
23735	 * @readonly
23736	 * @enum {String}
23737	 */
23738	Owl.Type = {
23739		Event: 'event',
23740		State: 'state'
23741	};
23742
23743	/**
23744	 * Contains all registered plugins.
23745	 * @public
23746	 */
23747	Owl.Plugins = {};
23748
23749	/**
23750	 * List of workers involved in the update process.
23751	 */
23752	Owl.Workers = [ {
23753		filter: [ 'width', 'settings' ],
23754		run: function() {
23755			this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width();
23756			//this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12);
23757		}
23758	}, {
23759		filter: [ 'width', 'items', 'settings' ],
23760		run: function(cache) {
23761			cache.current = this._items && this._items[this.relative(this._current)];
23762		}
23763	}, {
23764		filter: [ 'items', 'settings' ],
23765		run: function() {
23766			this.$stage.children('.cloned').remove();
23767		}
23768	}, {
23769		filter: [ 'width', 'items', 'settings' ],
23770		run: function(cache) {
23771			var margin = this.settings.margin || '',
23772				grid = !this.settings.autoWidth,
23773				rtl = this.settings.rtl,
23774				css = {
23775					'width': 'auto',
23776					'margin-left': rtl ? margin : '',
23777					'margin-right': rtl ? '' : margin
23778				};
23779
23780			!grid && this.$stage.children().css(css);
23781
23782			cache.css = css;
23783		}
23784	}, {
23785		filter: [ 'width', 'items', 'settings' ],
23786		run: function(cache) {
23787			//UNCODE edit to fix Chrome stage padding issue
23788			var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin),
23789				merge = null,
23790				iterator = this._items.length,
23791				grid = !this.settings.autoWidth,
23792				widths = [];
23793
23794			cache.items = {
23795				merge: false,
23796				width: width
23797			};
23798
23799			while (iterator--) {
23800				merge = this._mergers[iterator];
23801				merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
23802
23803				cache.items.merge = merge > 1 || cache.items.merge;
23804
23805				widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
23806			}
23807
23808			this._widths = widths;
23809		}
23810	}, {
23811		filter: [ 'items', 'settings' ],
23812		run: function() {
23813			var clones = [],
23814				items = this._items,
23815				settings = this.settings,
23816				view = Math.max(settings.items * 2, 4),
vendor: 4,968 bytes, lines 23817-23969
23817				size = Math.ceil(items.length / 2) * 2,
23818				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
23819				append = '',
23820				prepend = '';
23821
23822			repeat /= 2;
23823
23824			while (repeat--) {
23825				clones.push(this.normalize(clones.length / 2, true));
23826				append = append + items[clones[clones.length - 1]][0].outerHTML;
23827				clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
23828				prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
23829			}
23830
23831			this._clones = clones;
23832
23833			// var appendVideo = $(append).find('.uncode-video-container');
23834			// if (appendVideo.length) {
23835			// 	appendVideo.attr('data-id', Math.round(Math.random() * 100000));
23836			// }
23837			// var prependVideo = $(prepend).find('.uncode-video-container');
23838			// if (prependVideo.length) {
23839			// 	prependVideo.attr('data-id', Math.round(Math.random() * 100000));
23840			// }
23841			$(append).addClass('cloned').appendTo(this.$stage);
23842			$(prepend).addClass('cloned').prependTo(this.$stage);
23843		}
23844	}, {
23845		filter: [ 'width', 'items', 'settings' ],
23846		run: function() {
23847			var rtl = this.settings.rtl ? 1 : -1,
23848				size = this._clones.length + this._items.length,
23849				iterator = -1,
23850				previous = 0,
23851				current = 0,
23852				coordinates = [];
23853
23854			while (++iterator < size) {
23855				previous = coordinates[iterator - 1] || 0;
23856				current = this._widths[this.relative(iterator)] + this.settings.margin;
23857				coordinates.push(previous + current * rtl);
23858			}
23859
23860			this._coordinates = coordinates;
23861		}
23862	}, {
23863		filter: [ 'width', 'items', 'settings' ],
23864		run: function() {
23865			var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200,
23866				padding = stagePadding,
23867				coordinates = this._coordinates,
23868				css = {
23869					'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
23870					'padding-left': padding || '',
23871					'padding-right': padding || ''
23872				};
23873
23874			this.$stage.css(css);
23875		}
23876	}, {
23877		filter: [ 'width', 'items', 'settings' ],
23878		run: function(cache) {
23879			var iterator = this._coordinates.length,
23880				grid = !this.settings.autoWidth,
23881				items = this.$stage.children();
23882
23883			if (grid && cache.items.merge) {
23884				while (iterator--) {
23885					cache.css.width = this._widths[this.relative(iterator)];
23886					items.eq(iterator).css(cache.css);
23887				}
23888			} else if (grid) {
23889				cache.css.width = cache.items.width;
23890				items.css(cache.css);
23891			}
23892		}
23893	}, {
23894		filter: [ 'items' ],
23895		run: function() {
23896			this._coordinates.length < 1 && this.$stage.removeAttr('style');
23897		}
23898	}, {
23899		filter: [ 'width', 'items', 'settings' ],
23900		run: function(cache) {
23901			cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
23902			cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
23903			this.reset(cache.current);
23904		}
23905	}, {
23906		filter: [ 'position' ],
23907		run: function() {
23908			this.animate(this.coordinates(this._current));
23909		}
23910	}, {
23911		filter: [ 'width', 'position', 'items', 'settings' ],
23912		run: function() {
23913			var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200,
23914				rtl = this.settings.rtl ? 1 : -1,
23915				padding = this.settings.stagePadding * 2,
23916				begin = this.coordinates(this.current()) + padding,
23917				end = begin + this.width() * rtl,
23918				inner, outer, matches = [], i, n;
23919
23920			for (i = 0, n = this._coordinates.length; i < n; i++) {
23921				inner = this._coordinates[i - 1] || 0;
23922				outer = Math.abs(this._coordinates[i]) + padding * rtl;
23923
23924				if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
23925					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
23926					matches.push(i);
23927				}
23928			}
23929
23930			this.$stage.children('.active').removeClass('active');
23931			this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
23932
23933			if (this.settings.center) {
23934				this.$stage.children('.center').removeClass('center');
23935				this.$stage.children().eq(this.current()).addClass('center');
23936			}
23937		}
23938	} ];
23939
23940	/**
23941	 * Initializes the carousel.
23942	 * @protected
23943	 */
23944	Owl.prototype.initialize = function() {
23945		this.enter('initializing');
23946		this.trigger('initialize');
23947
23948		this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
23949
23950		if (this.settings.autoWidth && !this.is('pre-loading')) {
23951			var imgs, nestedSelector, width;
23952			imgs = this.$element.find('img');
23953			nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
23954			width = this.$element.children(nestedSelector).width();
23955
23956			if (imgs.length && width <= 0) {
23957				this.preloadAutoWidthImages(imgs);
23958			}
23959		}
23960
23961		this.$element.addClass(this.options.loadingClass);
23962
23963		// create stage
23964		this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')
23965			.wrap('<div class="' + this.settings.stageOuterClass + '"/>');
23966
23967		//UNCODE edit to exclude hidden items
23968		if ( this.settings.itemSelector ) {
23969			// append stage
23970			this.$element.prepend(this.$stage.parent());
23971			// append content
23972			this.replace(this.$element.find(' > ' + this.settings.itemSelector).not(this.$stage.parent()));
23973		} else {
23974			// append stage
23975			this.$element.append(this.$stage.parent());
23976			// append content
23977			this.replace(this.$element.children().not(this.$stage.parent()));
23978		}
23979
23980		// check visibility
23981		if (this.$element.is(':visible')) {
23982			// update view
23983			this.refresh();
23984		} else {
23985			// invalidate width
23986			this.invalidate('width');
23987		}
23988
23989		this.$element
23990			.removeClass(this.options.loadingClass)
23991			.addClass(this.options.loadedClass);
23992
23993		// register event handlers
23994		this.registerEventHandlers();
23995
23996		this.leave('initializing');
23997		this.trigger('initialized');
23998	};
23999
24000	/**
24001	 * Setups the current settings.
24002	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
24003	 * @todo Support for media queries by using `matchMedia` would be nice.
24004	 * @public
24005	 */
24006	Owl.prototype.setup = function() {
24007		var viewport = this.viewport(),
24008			overwrites = this.options.responsive,
24009			match = -1,
24010			settings = null;
24011
24012		if (!overwrites) {
24013			settings = $.extend({}, this.options);
24014		} else {
24015			$.each(overwrites, function(breakpoint) {
24016				if (breakpoint <= viewport && breakpoint > match) {
24017					match = Number(breakpoint);
24018				}
24019			});
24020
24021			settings = $.extend({}, this.options, overwrites[match]);
24022			delete settings.responsive;
24023
24024			// responsive class
24025			if (settings.responsiveClass) {
24026				this.$element.attr('class',
24027					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
24028				);
24029			}
24030		}
24031
24032		if (this.settings === null || this._breakpoint !== match) {
24033			this.trigger('change', { property: { name: 'settings', value: settings } });
24034			this._breakpoint = match;
24035			this.settings = settings;
24036			this.invalidate('settings');
24037			this.trigger('changed', { property: { name: 'settings', value: this.settings } });
24038		}
24039	};
24040
24041	/**
24042	 * Updates option logic if necessery.
24043	 * @protected
24044	 */
24045	Owl.prototype.optionsLogic = function() {
24046		if (this.settings.autoWidth) {
24047			this.settings.stagePadding = false;
24048			this.settings.merge = false;
24049		}
24050	};
24051
24052	/**
24053	 * Prepares an item before add.
24054	 * @todo Rename event parameter `content` to `item`.
24055	 * @protected
24056	 * @returns {jQuery|HTMLElement} - The item container.
24057	 */
24058	Owl.prototype.prepare = function(item, index) {
24059		var event = this.trigger('prepare', { content: item });
24060		if (!event.data) {
24061			event.data = $('<' + this.settings.itemElement + '/>')
24062				.addClass(this.options.itemClass).attr('data-index', index + 1).append(item)
24063		}
24064
24065		this.trigger('prepared', { content: event.data });
24066
24067		return event.data;
24068	};
24069
24070	/**
24071	 * Updates the view.
24072	 * @public
24073	 */
24074	Owl.prototype.update = function() {
24075		var i = 0,
24076			n = this._pipe.length,
24077			filter = $.proxy(function(p) { return this[p] }, this._invalidated),
24078			cache = {};
24079
24080		while (i < n) {
24081			if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
24082				this._pipe[i].run(cache);
24083			}
24084			i++;
24085		}
24086
24087		this._invalidated = {};
24088
24089		!this.is('valid') && this.enter('valid');
24090	};
24091
24092	/**
24093	 * Gets the width of the view.
24094	 * @public
24095	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
24096	 * @returns {Number} - The width of the view in pixel.
24097	 */
24098	Owl.prototype.width = function(dimension) {
24099		dimension = dimension || Owl.Width.Default;
24100		var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200;
24101		switch (dimension) {
24102			case Owl.Width.Inner:
24103			case Owl.Width.Outer:
24104				return this._width;
24105			default:
24106				return this._width - stagePadding * 2 + this.settings.margin;
24107		}
24108	};
24109
24110	/**
24111	 * Refreshes the carousel primarily for adaptive purposes.
24112	 * @public
24113	 */
24114	Owl.prototype.refresh = function() {
24115		this.enter('refreshing');
24116		this.trigger('refresh');
24117
24118		this.setup();
24119
24120		this.optionsLogic();
24121
24122		this.$element.addClass(this.options.refreshClass);
24123
24124		this.update();
24125
24126		this.$element.removeClass(this.options.refreshClass);
24127
24128		this.leave('refreshing');
24129		this.trigger('refreshed');
24130	};
24131
24132	/**
24133	 * Checks window `resize` event.
24134	 * @protected
24135	 */
24136	Owl.prototype.onThrottledResize = function() {
24137		window.clearTimeout(this.resizeTimer);
24138		this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
24139	};
24140
24141	/**
24142	 * Checks window `resize` event.
24143	 * @protected
24144	 */
24145	Owl.prototype.onResize = function() {
24146		if (!this._items.length) {
24147			return false;
vendor: 15,850 bytes, lines 24148-24704
24148		}
24149
24150		if (this._width === this.$element.width()) {
24151			return false;
24152		}
24153
24154		if (!this.$element.is(':visible')) {
24155			return false;
24156		}
24157
24158		this.enter('resizing');
24159
24160		if (this.trigger('resize').isDefaultPrevented()) {
24161			this.leave('resizing');
24162			return false;
24163		}
24164
24165		this.invalidate('width');
24166
24167		this.refresh();
24168
24169		this.leave('resizing');
24170		this.trigger('resized');
24171	};
24172
24173	/**
24174	 * Registers event handlers.
24175	 * @todo Check `msPointerEnabled`
24176	 * @todo #261
24177	 * @protected
24178	 */
24179	Owl.prototype.registerEventHandlers = function() {
24180		if ($.support.transition) {
24181			this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
24182		}
24183
24184		if (this.settings.responsive !== false) {
24185			this.on(window, 'resize', this._handlers.onThrottledResize);
24186		}
24187
24188		if (this.settings.mouseDrag) {
24189			this.$element.addClass(this.options.dragClass);
24190			this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
24191			this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
24192		}
24193
24194		if (this.settings.touchDrag){
24195			this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
24196			this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
24197		}
24198	};
24199
24200	/**
24201	 * Handles `touchstart` and `mousedown` events.
24202	 * @todo Horizontal swipe threshold as option
24203	 * @todo #261
24204	 * @protected
24205	 * @param {Event} event - The event arguments.
24206	 */
24207	Owl.prototype.onDragStart = function(event) {
24208		var stage = null;
24209
24210		if (event.which === 3) {
24211			return;
24212		}
24213
24214		if ($.support.transform) {
24215			stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
24216			stage = {
24217				x: stage[stage.length === 16 ? 12 : 4],
24218				y: stage[stage.length === 16 ? 13 : 5]
24219			};
24220		} else {
24221			stage = this.$stage.position();
24222			stage = {
24223				x: this.settings.rtl ?
24224					stage.left + this.$stage.width() - this.width() + this.settings.margin :
24225					stage.left,
24226				y: stage.top
24227			};
24228		}
24229
24230		if (this.is('animating')) {
24231			$.support.transform ? this.animate(stage.x) : this.$stage.stop()
24232			this.invalidate('position');
24233		}
24234
24235		this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
24236
24237		this.speed(0);
24238
24239		this._drag.time = new Date().getTime();
24240		this._drag.target = $(event.target);
24241		this._drag.stage.start = stage;
24242		this._drag.stage.current = stage;
24243		this._drag.pointer = this.pointer(event);
24244
24245		$(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
24246
24247		$(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
24248			var delta = this.difference(this._drag.pointer, this.pointer(event));
24249
24250			$(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
24251
24252			if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
24253				return;
24254			}
24255
24256			event.preventDefault();
24257
24258			this.enter('dragging');
24259			this.trigger('drag');
24260		}, this));
24261	};
24262
24263	/**
24264	 * Handles the `touchmove` and `mousemove` events.
24265	 * @todo #261
24266	 * @protected
24267	 * @param {Event} event - The event arguments.
24268	 */
24269	Owl.prototype.onDragMove = function(event) {
24270		var minimum = null,
24271			maximum = null,
24272			pull = null,
24273			delta = this.difference(this._drag.pointer, this.pointer(event)),
24274			stage = this.difference(this._drag.stage.start, delta);
24275
24276		if (!this.is('dragging')) {
24277			return;
24278		}
24279
24280		event.preventDefault();
24281
24282		if (this.settings.loop) {
24283			minimum = this.coordinates(this.minimum());
24284			maximum = this.coordinates(this.maximum() + 1) - minimum;
24285			stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
24286		} else {
24287			minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
24288			maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
24289			pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
24290			stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
24291		}
24292
24293		this._drag.stage.current = stage;
24294
24295		this.animate(stage.x);
24296	};
24297
24298	/**
24299	 * Handles the `touchend` and `mouseup` events.
24300	 * @todo #261
24301	 * @todo Threshold for click event
24302	 * @protected
24303	 * @param {Event} event - The event arguments.
24304	 */
24305	Owl.prototype.onDragEnd = function(event) {
24306		var delta = this.difference(this._drag.pointer, this.pointer(event)),
24307			stage = this._drag.stage.current,
24308			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
24309
24310		$(document).off('.owl.core');
24311
24312		this.$element.removeClass(this.options.grabClass);
24313
24314		if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
24315			this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
24316			this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
24317			this.invalidate('position');
24318			this.update();
24319
24320			this._drag.direction = direction;
24321
24322			if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
24323				this._drag.target.one('click.owl.core', function() { return false; });
24324			}
24325		}
24326
24327		if (!this.is('dragging')) {
24328			return;
24329		}
24330
24331		this.leave('dragging');
24332		this.trigger('dragged');
24333	};
24334
24335	/**
24336	 * Gets absolute position of the closest item for a coordinate.
24337	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
24338	 * @protected
24339	 * @param {Number} coordinate - The coordinate in pixel.
24340	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
24341	 * @return {Number} - The absolute position of the closest item.
24342	 */
24343	Owl.prototype.closest = function(coordinate, direction) {
24344		var position = -1,
24345			pull = 30,
24346			width = this.width(),
24347			coordinates = this.coordinates();
24348
24349		if (!this.settings.freeDrag) {
24350			// check closest item
24351			$.each(coordinates, $.proxy(function(index, value) {
24352				if (coordinate > value - pull && coordinate < value + pull) {
24353					position = index;
24354				} else if (this.op(coordinate, '<', value)
24355					&& this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
24356					position = direction === 'left' ? index + 1 : index;
24357				}
24358				return position === -1;
24359			}, this));
24360		}
24361
24362		if (!this.settings.loop) {
24363			// non loop boundries
24364			if (this.op(coordinate, '>', coordinates[this.minimum()])) {
24365				position = coordinate = this.minimum();
24366			} else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
24367				position = coordinate = this.maximum();
24368			}
24369		}
24370
24371		return position;
24372	};
24373
24374	/**
24375	 * Animates the stage.
24376	 * @todo #270
24377	 * @public
24378	 * @param {Number} coordinate - The coordinate in pixels.
24379	 */
24380	Owl.prototype.animate = function(coordinate) {
24381		var animate = this.speed() > 0;
24382
24383		this.is('animating') && this.onTransitionEnd();
24384
24385		if (animate) {
24386			this.enter('animating');
24387			this.trigger('translate');
24388		}
24389
24390		if ($.support.transform3d && $.support.transition) {
24391			this.$stage.css({
24392				transform: 'translate3d(' + coordinate + 'px,0px,0px)',
24393				transition: (this.speed() / 1000) + 's'
24394			});
24395		} else if (animate) {
24396			this.$stage.animate({
24397				left: coordinate + 'px'
24398			}, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
24399		} else {
24400			this.$stage.css({
24401				left: coordinate + 'px'
24402			});
24403		}
24404	};
24405
24406	/**
24407	 * Checks whether the carousel is in a specific state or not.
24408	 * @param {String} state - The state to check.
24409	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
24410	 */
24411	Owl.prototype.is = function(state) {
24412		return this._states.current[state] && this._states.current[state] > 0;
24413	};
24414
24415	/**
24416	 * Sets the absolute position of the current item.
24417	 * @public
24418	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
24419	 * @returns {Number} - The absolute position of the current item.
24420	 */
24421	Owl.prototype.current = function(position) {
24422		if (position === undefined) {
24423			return this._current;
24424		}
24425
24426		if (this._items.length === 0) {
24427			return undefined;
24428		}
24429
24430		position = this.normalize(position);
24431
24432		if (this._current !== position) {
24433			var event = this.trigger('change', { property: { name: 'position', value: position } });
24434
24435			if (event.data !== undefined) {
24436				position = this.normalize(event.data);
24437			}
24438
24439			this._current = position;
24440
24441			this.invalidate('position');
24442
24443			this.trigger('changed', { property: { name: 'position', value: this._current } });
24444		}
24445
24446		return this._current;
24447	};
24448
24449	/**
24450	 * Invalidates the given part of the update routine.
24451	 * @param {String} [part] - The part to invalidate.
24452	 * @returns {Array.<String>} - The invalidated parts.
24453	 */
24454	Owl.prototype.invalidate = function(part) {
24455		if ($.type(part) === 'string') {
24456			this._invalidated[part] = true;
24457			this.is('valid') && this.leave('valid');
24458		}
24459		return $.map(this._invalidated, function(v, i) { return i });
24460	};
24461
24462	/**
24463	 * Resets the absolute position of the current item.
24464	 * @public
24465	 * @param {Number} position - The absolute position of the new item.
24466	 */
24467	Owl.prototype.reset = function(position) {
24468		position = this.normalize(position);
24469
24470		if (position === undefined) {
24471			return;
24472		}
24473
24474		this._speed = 0;
24475		this._current = position;
24476
24477		this.suppress([ 'translate', 'translated' ]);
24478
24479		this.animate(this.coordinates(position));
24480
24481		this.release([ 'translate', 'translated' ]);
24482	};
24483
24484	/**
24485	 * Normalizes an absolute or a relative position of an item.
24486	 * @public
24487	 * @param {Number} position - The absolute or relative position to normalize.
24488	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
24489	 * @returns {Number} - The normalized position.
24490	 */
24491	Owl.prototype.normalize = function(position, relative) {
24492		var n = this._items.length,
24493			m = relative ? 0 : this._clones.length;
24494
24495		if (!$.isNumeric(position) || n < 1) {
24496			position = undefined;
24497		} else if (position < 0 || position >= n + m) {
24498			position = ((position - m / 2) % n + n) % n + m / 2;
24499		}
24500
24501		return position;
24502	};
24503
24504	/**
24505	 * Converts an absolute position of an item into a relative one.
24506	 * @public
24507	 * @param {Number} position - The absolute position to convert.
24508	 * @returns {Number} - The converted position.
24509	 */
24510	Owl.prototype.relative = function(position) {
24511		position -= this._clones.length / 2;
24512		return this.normalize(position, true);
24513	};
24514
24515	/**
24516	 * Gets the maximum position for the current item.
24517	 * @public
24518	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
24519	 * @returns {Number}
24520	 */
24521	Owl.prototype.maximum = function(relative) {
24522		var settings = this.settings,
24523			maximum = this._coordinates.length,
24524			boundary = Math.abs(this._coordinates[maximum - 1]) - this._width,
24525			i = -1, j;
24526
24527		if (settings.loop) {
24528			maximum = this._clones.length / 2 + this._items.length - 1;
24529		} else if (settings.autoWidth || settings.merge) {
24530			// binary search
24531			while (maximum - i > 1) {
24532				Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary
24533					? i = j : maximum = j;
24534			}
24535		} else if (settings.center) {
24536			maximum = this._items.length - 1;
24537		} else {
24538			maximum = this._items.length - settings.items;
24539		}
24540
24541		if (relative) {
24542			maximum -= this._clones.length / 2;
24543		}
24544
24545		return Math.max(maximum, 0);
24546	};
24547
24548	/**
24549	 * Gets the minimum position for the current item.
24550	 * @public
24551	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
24552	 * @returns {Number}
24553	 */
24554	Owl.prototype.minimum = function(relative) {
24555		return relative ? 0 : this._clones.length / 2;
24556	};
24557
24558	/**
24559	 * Gets an item at the specified relative position.
24560	 * @public
24561	 * @param {Number} [position] - The relative position of the item.
24562	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
24563	 */
24564	Owl.prototype.items = function(position) {
24565		if (position === undefined) {
24566			return this._items.slice();
24567		}
24568
24569		position = this.normalize(position, true);
24570		return this._items[position];
24571	};
24572
24573	/**
24574	 * Gets an item at the specified relative position.
24575	 * @public
24576	 * @param {Number} [position] - The relative position of the item.
24577	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
24578	 */
24579	Owl.prototype.mergers = function(position) {
24580		if (position === undefined) {
24581			return this._mergers.slice();
24582		}
24583
24584		position = this.normalize(position, true);
24585		return this._mergers[position];
24586	};
24587
24588	/**
24589	 * Gets the absolute positions of clones for an item.
24590	 * @public
24591	 * @param {Number} [position] - The relative position of the item.
24592	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
24593	 */
24594	Owl.prototype.clones = function(position) {
24595		var odd = this._clones.length / 2,
24596			even = odd + this._items.length,
24597			map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
24598
24599		if (position === undefined) {
24600			return $.map(this._clones, function(v, i) { return map(i) });
24601		}
24602
24603		return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
24604	};
24605
24606	/**
24607	 * Sets the current animation speed.
24608	 * @public
24609	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
24610	 * @returns {Number} - The current animation speed in milliseconds.
24611	 */
24612	Owl.prototype.speed = function(speed) {
24613		if (speed !== undefined) {
24614			this._speed = speed;
24615		}
24616
24617		return this._speed;
24618	};
24619
24620	/**
24621	 * Gets the coordinate of an item.
24622	 * @todo The name of this method is missleanding.
24623	 * @public
24624	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
24625	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
24626	 */
24627	Owl.prototype.coordinates = function(position) {
24628		var coordinate = null;
24629
24630		if (position === undefined) {
24631			return $.map(this._coordinates, $.proxy(function(coordinate, index) {
24632				return this.coordinates(index);
24633			}, this));
24634		}
24635
24636		if (this.settings.center) {
24637			coordinate = this._coordinates[position];
24638			coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1);
24639		} else {
24640			coordinate = this._coordinates[position - 1] || 0;
24641		}
24642
24643		return coordinate;
24644	};
24645
24646	/**
24647	 * Calculates the speed for a translation.
24648	 * @protected
24649	 * @param {Number} from - The absolute position of the start item.
24650	 * @param {Number} to - The absolute position of the target item.
24651	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
24652	 * @returns {Number} - The time in milliseconds for the translation.
24653	 */
24654	Owl.prototype.duration = function(from, to, factor) {
24655		return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
24656	};
24657
24658	/**
24659	 * Slides to the specified item.
24660	 * @public
24661	 * @param {Number} position - The position of the item.
24662	 * @param {Number} [speed] - The time in milliseconds for the transition.
24663	 */
24664	Owl.prototype.to = function(position, speed) {
24665		var current = this.current(),
24666			revert = null,
24667			distance = position - this.relative(current),
24668			direction = (distance > 0) - (distance < 0),
24669			items = this._items.length,
24670			minimum = this.minimum(),
24671			maximum = this.maximum();
24672
24673		if (this.settings.loop) {
24674			if (!this.settings.rewind && Math.abs(distance) > items / 2) {
24675				distance += direction * -1 * items;
24676			}
24677
24678			position = current + distance;
24679			revert = ((position - minimum) % items + items) % items + minimum;
24680
24681			if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
24682				current = revert - distance;
24683				position = revert;
24684				this.reset(current);
24685			}
24686		} else if (this.settings.rewind) {
24687			maximum += 1;
24688			position = (position % maximum + maximum) % maximum;
24689		} else {
24690			position = Math.max(minimum, Math.min(maximum, position));
24691		}
24692
24693		this.speed(this.duration(current, position, speed));
24694		this.current(position);
24695
24696		if (this.$element.is(':visible')) {
24697			this.update();
24698		}
24699	};
24700
24701	/**
24702	 * Slides to the next item.
24703	 * @public
24704	 * @param {Number}
vendor: 12,284 bytes, lines 24704-25124
24704 [speed] - The time in milliseconds for the transition.
24705	 */
24706	Owl.prototype.next = function(speed) {
24707		speed = speed || false;
24708		this.to(this.relative(this.current()) + 1, speed);
24709	};
24710
24711	/**
24712	 * Slides to the previous item.
24713	 * @public
24714	 * @param {Number} [speed] - The time in milliseconds for the transition.
24715	 */
24716	Owl.prototype.prev = function(speed) {
24717		speed = speed || false;
24718		this.to(this.relative(this.current()) - 1, speed);
24719	};
24720
24721	/**
24722	 * Handles the end of an animation.
24723	 * @protected
24724	 * @param {Event} event - The event arguments.
24725	 */
24726	Owl.prototype.onTransitionEnd = function(event) {
24727
24728		// if css2 animation then event object is undefined
24729		if (event !== undefined) {
24730			event.stopPropagation();
24731
24732			// Catch only owl-stage transitionEnd event
24733			if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
24734				return false;
24735			}
24736		}
24737
24738		this.leave('animating');
24739		this.trigger('translated');
24740	};
24741
24742	/**
24743	 * Gets viewport width.
24744	 * @protected
24745	 * @return {Number} - The width in pixel.
24746	 */
24747	Owl.prototype.viewport = function() {
24748		var width;
24749		if (this.options.responsiveBaseElement !== window) {
24750			width = $(this.options.responsiveBaseElement).width();
24751		} else if (window.innerWidth) {
24752			width = window.innerWidth;
24753		} else if (document.documentElement && document.documentElement.clientWidth) {
24754			width = document.documentElement.clientWidth;
24755		} else {
24756			throw 'Can not detect viewport width.';
24757		}
24758
24759		return width;
24760	};
24761
24762	/**
24763	 * Replaces the current content.
24764	 * @public
24765	 * @param {HTMLElement|jQuery|String} content - The new content.
24766	 */
24767	Owl.prototype.replace = function(content) {
24768		this.$stage.empty();
24769		this._items = [];
24770
24771		if (content) {
24772			content = (content instanceof jQuery) ? content : $(content);
24773		}
24774
24775		if (this.settings.nestedItemSelector) {
24776			content = content.find('.' + this.settings.nestedItemSelector);
24777		}
24778
24779		content.filter(function() {
24780			return this.nodeType === 1;
24781		}).each($.proxy(function(index, item) {
24782			item = this.prepare(item, index);
24783			this.$stage.append(item);
24784			this._items.push(item);
24785			this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
24786		}, this));
24787
24788		this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
24789
24790		this.invalidate('items');
24791	};
24792
24793	/**
24794	 * Adds an item.
24795	 * @todo Use `item` instead of `content` for the event arguments.
24796	 * @public
24797	 * @param {HTMLElement|jQuery|String} content - The item content to add.
24798	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
24799	 */
24800	Owl.prototype.add = function(content, position) {
24801		var current = this.relative(this._current);
24802
24803		position = position === undefined ? this._items.length : this.normalize(position, true);
24804		content = content instanceof jQuery ? content : $(content);
24805
24806		this.trigger('add', { content: content, position: position });
24807
24808		content = this.prepare(content, this._items[current].index());
24809
24810		if (this._items.length === 0 || position === this._items.length) {
24811			this._items.length === 0 && this.$stage.append(content);
24812			this._items.length !== 0 && this._items[position - 1].after(content);
24813			this._items.push(content);
24814			this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
24815		} else {
24816			this._items[position].before(content);
24817			this._items.splice(position, 0, content);
24818			this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
24819		}
24820
24821		this._items[current] && this.reset(this._items[current].index());
24822
24823		this.invalidate('items');
24824
24825		this.trigger('added', { content: content, position: position });
24826	};
24827
24828	/**
24829	 * Removes an item by its position.
24830	 * @todo Use `item` instead of `content` for the event arguments.
24831	 * @public
24832	 * @param {Number} position - The relative position of the item to remove.
24833	 */
24834	Owl.prototype.remove = function(position) {
24835		position = this.normalize(position, true);
24836
24837		if (position === undefined) {
24838			return;
24839		}
24840
24841		this.trigger('remove', { content: this._items[position], position: position });
24842
24843		this._items[position].remove();
24844		this._items.splice(position, 1);
24845		this._mergers.splice(position, 1);
24846
24847		this.invalidate('items');
24848
24849		this.trigger('removed', { content: null, position: position });
24850	};
24851
24852	/**
24853	 * Preloads images with auto width.
24854	 * @todo Replace by a more generic approach
24855	 * @protected
24856	 */
24857	Owl.prototype.preloadAutoWidthImages = function(images) {
24858		images.each($.proxy(function(i, element) {
24859			this.enter('pre-loading');
24860			element = $(element);
24861			$(new Image()).one('load', $.proxy(function(e) {
24862				element.attr('src', e.target.src);
24863				element.css('opacity', 1);
24864				this.leave('pre-loading');
24865				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
24866			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
24867		}, this));
24868	};
24869
24870	/**
24871	 * Destroys the carousel.
24872	 * @public
24873	 */
24874	Owl.prototype.destroy = function() {
24875
24876		this.$element.off('.owl.core');
24877		this.$stage.off('.owl.core');
24878		$(document).off('.owl.core');
24879
24880		if (this.settings.responsive !== false) {
24881			window.clearTimeout(this.resizeTimer);
24882			this.off(window, 'resize', this._handlers.onThrottledResize);
24883		}
24884
24885		for (var i in this._plugins) {
24886			this._plugins[i].destroy();
24887		}
24888
24889		this.$stage.children('.cloned').remove();
24890
24891		this.$stage.unwrap();
24892		this.$stage.children().contents().unwrap();
24893		this.$stage.children().unwrap();
24894
24895		this.$element
24896			.removeClass(this.options.refreshClass)
24897			.removeClass(this.options.loadingClass)
24898			.removeClass(this.options.loadedClass)
24899			.removeClass(this.options.rtlClass)
24900			.removeClass(this.options.dragClass)
24901			.removeClass(this.options.grabClass)
24902			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
24903			.removeData('owl.carousel');
24904	};
24905
24906	/**
24907	 * Operators to calculate right-to-left and left-to-right.
24908	 * @protected
24909	 * @param {Number} [a] - The left side operand.
24910	 * @param {String} [o] - The operator.
24911	 * @param {Number} [b] - The right side operand.
24912	 */
24913	Owl.prototype.op = function(a, o, b) {
24914		var rtl = this.settings.rtl;
24915		switch (o) {
24916			case '<':
24917				return rtl ? a > b : a < b;
24918			case '>':
24919				return rtl ? a < b : a > b;
24920			case '>=':
24921				return rtl ? a <= b : a >= b;
24922			case '<=':
24923				return rtl ? a >= b : a <= b;
24924			default:
24925				break;
24926		}
24927	};
24928
24929	/**
24930	 * Attaches to an internal event.
24931	 * @protected
24932	 * @param {HTMLElement} element - The event source.
24933	 * @param {String} event - The event name.
24934	 * @param {Function} listener - The event handler to attach.
24935	 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
24936	 */
24937	Owl.prototype.on = function(element, event, listener, capture) {
24938		if (element.addEventListener) {
24939			element.addEventListener(event, listener, capture);
24940		} else if (element.attachEvent) {
24941			element.attachEvent('on' + event, listener);
24942		}
24943	};
24944
24945	/**
24946	 * Detaches from an internal event.
24947	 * @protected
24948	 * @param {HTMLElement} element - The event source.
24949	 * @param {String} event - The event name.
24950	 * @param {Function} listener - The attached event handler to detach.
24951	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
24952	 */
24953	Owl.prototype.off = function(element, event, listener, capture) {
24954		if (element.removeEventListener) {
24955			element.removeEventListener(event, listener, capture);
24956		} else if (element.detachEvent) {
24957			element.detachEvent('on' + event, listener);
24958		}
24959	};
24960
24961	/**
24962	 * Triggers a public event.
24963	 * @todo Remove `status`, `relatedTarget` should be used instead.
24964	 * @protected
24965	 * @param {String} name - The event name.
24966	 * @param {*} [data=null] - The event data.
24967	 * @param {String} [namespace=carousel] - The event namespace.
24968	 * @param {String} [state] - The state which is associated with the event.
24969	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
24970	 * @returns {Event} - The event arguments.
24971	 */
24972	Owl.prototype.trigger = function(name, data, namespace, state, enter) {
24973		var status = {
24974			item: { count: this._items.length, index: this.current() }
24975		}, handler = $.camelCase(
24976			$.grep([ 'on', name, namespace ], function(v) { return v })
24977				.join('-').toLowerCase()
24978		), event = $.Event(
24979			[ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
24980			$.extend({ relatedTarget: this }, status, data)
24981		);
24982
24983		if (!this._supress[name]) {
24984			$.each(this._plugins, function(name, plugin) {
24985				if (plugin.onTrigger) {
24986					plugin.onTrigger(event);
24987				}
24988			});
24989
24990			this.register({ type: Owl.Type.Event, name: name });
24991			this.$element.trigger(event);
24992
24993			if (this.settings && typeof this.settings[handler] === 'function') {
24994				this.settings[handler].call(this, event);
24995			}
24996		}
24997
24998		return event;
24999	};
25000
25001	/**
25002	 * Enters a state.
25003	 * @param name - The state name.
25004	 */
25005	Owl.prototype.enter = function(name) {
25006		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
25007			if (this._states.current[name] === undefined) {
25008				this._states.current[name] = 0;
25009			}
25010
25011			this._states.current[name]++;
25012		}, this));
25013	};
25014
25015	/**
25016	 * Leaves a state.
25017	 * @param name - The state name.
25018	 */
25019	Owl.prototype.leave = function(name) {
25020		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
25021			this._states.current[name]--;
25022		}, this));
25023	};
25024
25025	/**
25026	 * Registers an event or state.
25027	 * @public
25028	 * @param {Object} object - The event or state to register.
25029	 */
25030	Owl.prototype.register = function(object) {
25031		if (object.type === Owl.Type.Event) {
25032			if (!$.event.special[object.name]) {
25033				$.event.special[object.name] = {};
25034			}
25035
25036			if (!$.event.special[object.name].owl) {
25037				var _default = $.event.special[object.name]._default;
25038				$.event.special[object.name]._default = function(e) {
25039					if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
25040						return _default.apply(this, arguments);
25041					}
25042					return e.namespace && e.namespace.indexOf('owl') > -1;
25043				};
25044				$.event.special[object.name].owl = true;
25045			}
25046		} else if (object.type === Owl.Type.State) {
25047			if (!this._states.tags[object.name]) {
25048				this._states.tags[object.name] = object.tags;
25049			} else {
25050				this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
25051			}
25052
25053			this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
25054				return $.inArray(tag, this._states.tags[object.name]) === i;
25055			}, this));
25056		}
25057	};
25058
25059	/**
25060	 * Suppresses events.
25061	 * @protected
25062	 * @param {Array.<String>} events - The events to suppress.
25063	 */
25064	Owl.prototype.suppress = function(events) {
25065		$.each(events, $.proxy(function(index, event) {
25066			this._supress[event] = true;
25067		}, this));
25068	};
25069
25070	/**
25071	 * Releases suppressed events.
25072	 * @protected
25073	 * @param {Array.<String>} events - The events to release.
25074	 */
25075	Owl.prototype.release = function(events) {
25076		$.each(events, $.proxy(function(index, event) {
25077			delete this._supress[event];
25078		}, this));
25079	};
25080
25081	/**
25082	 * Gets unified pointer coordinates from event.
25083	 * @todo #261
25084	 * @protected
25085	 * @param {Event} - The `mousedown` or `touchstart` event.
25086	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
25087	 */
25088	Owl.prototype.pointer = function(event) {
25089		var result = { x: null, y: null };
25090
25091		event = event.originalEvent || event || window.event;
25092
25093		event = event.touches && event.touches.length ?
25094			event.touches[0] : event.changedTouches && event.changedTouches.length ?
25095				event.changedTouches[0] : event;
25096
25097		if (event.pageX) {
25098			result.x = event.pageX;
25099			result.y = event.pageY;
25100		} else {
25101			result.x = event.clientX;
25102			result.y = event.clientY;
25103		}
25104
25105		return result;
25106	};
25107
25108	/**
25109	 * Gets the difference of two vectors.
25110	 * @todo #261
25111	 * @protected
25112	 * @param {Object} - The first vector.
25113	 * @param {Object} - The second vector.
25114	 * @returns {Object} - The difference.
25115	 */
25116	Owl.prototype.difference = function(first, second) {
25117		return {
25118			x: first.x - second.x,
25119			y: first.y - second.y
25120		};
25121	};
25122
25123	/**
25124	 * The jQuery Plugin for the Owl Carousel
vendor: 32,250 bytes, lines 25125-26407
25125	 * @todo Navigation plugin `next` and `prev`
25126	 * @public
25127	 */
25128	$.fn.owlCarousel = function(option) {
25129		var args = Array.prototype.slice.call(arguments, 1);
25130
25131		return this.each(function() {
25132			var $this = $(this),
25133				data = $this.data('owl.carousel');
25134
25135			if (!data) {
25136				data = new Owl(this, typeof option == 'object' && option);
25137				$this.data('owl.carousel', data);
25138
25139				$.each([
25140					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
25141				], function(i, event) {
25142					data.register({ type: Owl.Type.Event, name: event });
25143					data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
25144						if (e.namespace && e.relatedTarget !== this) {
25145							this.suppress([ event ]);
25146							data[event].apply(this, [].slice.call(arguments, 1));
25147							this.release([ event ]);
25148						}
25149					}, data));
25150				});
25151			}
25152
25153			if (typeof option == 'string' && option.charAt(0) !== '_') {
25154				data[option].apply(data, args);
25155			}
25156		});
25157	};
25158
25159	/**
25160	 * The constructor for the jQuery Plugin
25161	 * @public
25162	 */
25163	$.fn.owlCarousel.Constructor = Owl;
25164
25165})(window.Zepto || window.jQuery, window, document);
25166
25167/**
25168 * AutoRefresh Plugin
25169 * @version 2.0.0-beta.3
25170 * @author Artus Kolanowski
25171 * @license The MIT License (MIT)
25172 */
25173;(function($, window, document, undefined) {
25174
25175	/**
25176	 * Creates the auto refresh plugin.
25177	 * @class The Auto Refresh Plugin
25178	 * @param {Owl} carousel - The Owl Carousel
25179	 */
25180	var AutoRefresh = function(carousel) {
25181		/**
25182		 * Reference to the core.
25183		 * @protected
25184		 * @type {Owl}
25185		 */
25186		this._core = carousel;
25187
25188		/**
25189		 * Refresh interval.
25190		 * @protected
25191		 * @type {number}
25192		 */
25193		this._interval = null;
25194
25195		/**
25196		 * Whether the element is currently visible or not.
25197		 * @protected
25198		 * @type {Boolean}
25199		 */
25200		this._visible = null;
25201
25202		/**
25203		 * All event handlers.
25204		 * @protected
25205		 * @type {Object}
25206		 */
25207		this._handlers = {
25208			'initialized.owl.carousel': $.proxy(function(e) {
25209				if (e.namespace && this._core.settings.autoRefresh) {
25210					this.watch();
25211				}
25212			}, this)
25213		};
25214
25215		// set default options
25216		this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
25217
25218		// register event handlers
25219		this._core.$element.on(this._handlers);
25220	};
25221
25222	/**
25223	 * Default options.
25224	 * @public
25225	 */
25226	AutoRefresh.Defaults = {
25227		autoRefresh: true,
25228		autoRefreshInterval: 500
25229	};
25230
25231	/**
25232	 * Watches the element.
25233	 */
25234	AutoRefresh.prototype.watch = function() {
25235		if (this._interval) {
25236			return;
25237		}
25238
25239		this._visible = this._core.$element.is(':visible');
25240		this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
25241	};
25242
25243	/**
25244	 * Refreshes the element.
25245	 */
25246	AutoRefresh.prototype.refresh = function() {
25247		if (this._core.$element.is(':visible') === this._visible) {
25248			return;
25249		}
25250
25251		this._visible = !this._visible;
25252
25253		this._core.$element.toggleClass('owl-hidden', !this._visible);
25254
25255		this._visible && (this._core.invalidate('width') && this._core.refresh());
25256	};
25257
25258	/**
25259	 * Destroys the plugin.
25260	 */
25261	AutoRefresh.prototype.destroy = function() {
25262		var handler, property;
25263
25264		window.clearInterval(this._interval);
25265
25266		for (handler in this._handlers) {
25267			this._core.$element.off(handler, this._handlers[handler]);
25268		}
25269		for (property in Object.getOwnPropertyNames(this)) {
25270			typeof this[property] != 'function' && (this[property] = null);
25271		}
25272	};
25273
25274	$.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
25275
25276})(window.Zepto || window.jQuery, window, document);
25277
25278/**
25279 * Lazy Plugin
25280 * @version 2.0.0-beta.3
25281 * @author Bartosz Wojciechowski
25282 * @license The MIT License (MIT)
25283 */
25284;(function($, window, document, undefined) {
25285
25286	/**
25287	 * Creates the lazy plugin.
25288	 * @class The Lazy Plugin
25289	 * @param {Owl} carousel - The Owl Carousel
25290	 */
25291	var Lazy = function(carousel) {
25292
25293		/**
25294		 * Reference to the core.
25295		 * @protected
25296		 * @type {Owl}
25297		 */
25298		this._core = carousel;
25299
25300		/**
25301		 * Already loaded items.
25302		 * @protected
25303		 * @type {Array.<jQuery>}
25304		 */
25305		this._loaded = [];
25306
25307		/**
25308		 * Event handlers.
25309		 * @protected
25310		 * @type {Object}
25311		 */
25312		this._handlers = {
25313			'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) {
25314				if (!e.namespace) {
25315					return;
25316				}
25317
25318				if (!this._core.settings || !this._core.settings.lazyLoad) {
25319					return;
25320				}
25321
25322				if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
25323					var settings = this._core.settings,
25324						n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
25325						i = ((settings.center && n * -1) || 0),
25326						position = ((e.property && e.property.value) || this._core.current()) + i,
25327						clones = this._core.clones().length,
25328						load = $.proxy(function(i, v) { this.load(v) }, this);
25329
25330					while (i++ < n) {
25331						this.load(clones / 2 + this._core.relative(position));
25332						clones && $.each(this._core.clones(this._core.relative(position)), load);
25333						position++;
25334					}
25335				}
25336			}, this)
25337		};
25338
25339		// set the default options
25340		this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
25341
25342		// register event handler
25343		this._core.$element.on(this._handlers);
25344	}
25345
25346	/**
25347	 * Default options.
25348	 * @public
25349	 */
25350	Lazy.Defaults = {
25351		lazyLoad: false
25352	}
25353
25354	/**
25355	 * Loads all resources of an item at the specified position.
25356	 * @param {Number} position - The absolute position of the item.
25357	 * @protected
25358	 */
25359	Lazy.prototype.load = function(position) {
25360		var $item = this._core.$stage.children().eq(position),
25361			$elements = $item && $item.find('.owl-lazy');
25362
25363		if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
25364			return;
25365		}
25366
25367		$elements.each($.proxy(function(index, element) {
25368			var $element = $(element), image,
25369				url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');
25370
25371			this._core.trigger('load', { element: $element, url: url }, 'lazy');
25372
25373			if ($element.is('img')) {
25374				$element.one('load.owl.lazy', $.proxy(function() {
25375					$element.css('opacity', 1);
25376					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
25377				}, this)).attr('src', url);
25378			} else {
25379				image = new Image();
25380				image.onload = $.proxy(function() {
25381					$element.css({
25382						'background-image': 'url(' + url + ')',
25383						'opacity': '1'
25384					});
25385					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
25386				}, this);
25387				image.src = url;
25388			}
25389		}, this));
25390
25391		this._loaded.push($item.get(0));
25392	}
25393
25394	/**
25395	 * Destroys the plugin.
25396	 * @public
25397	 */
25398	Lazy.prototype.destroy = function() {
25399		var handler, property;
25400
25401		for (handler in this.handlers) {
25402			this._core.$element.off(handler, this.handlers[handler]);
25403		}
25404		for (property in Object.getOwnPropertyNames(this)) {
25405			typeof this[property] != 'function' && (this[property] = null);
25406		}
25407	};
25408
25409	$.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
25410
25411})(window.Zepto || window.jQuery, window, document);
25412
25413/**
25414 * AutoHeight Plugin
25415 * @version 2.0.0-beta.3
25416 * @author Bartosz Wojciechowski
25417 * @license The MIT License (MIT)
25418 */
25419;(function($, window, document, undefined) {
25420
25421	/**
25422	 * Creates the auto height plugin.
25423	 * @class The Auto Height Plugin
25424	 * @param {Owl} carousel - The Owl Carousel
25425	 */
25426	var AutoHeight = function(carousel) {
25427		/**
25428		 * Reference to the core.
25429		 * @protected
25430		 * @type {Owl}
25431		 */
25432		this._core = carousel;
25433
25434		/**
25435		 * All event handlers.
25436		 * @protected
25437		 * @type {Object}
25438		 */
25439		this._handlers = {
25440			'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {
25441				if (e.namespace && this._core.settings.autoHeight) {
25442					this.update();
25443				}
25444			}, this),
25445			'changed.owl.carousel': $.proxy(function(e) {
25446				if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){
25447					this.update();
25448				}
25449			}, this),
25450			'loaded.owl.lazy': $.proxy(function(e) {
25451				if (e.namespace && this._core.settings.autoHeight
25452					&& e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
25453					this.update();
25454				}
25455			}, this)
25456		};
25457
25458		// set default options
25459		this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
25460
25461		// register event handlers
25462		this._core.$element.on(this._handlers);
25463	};
25464
25465	/**
25466	 * Default options.
25467	 * @public
25468	 */
25469	AutoHeight.Defaults = {
25470		autoHeight: false,
25471		autoHeightClass: 'owl-height'
25472	};
25473
25474	/**
25475	 * Updates the view.
25476	 */
25477	AutoHeight.prototype.update = function() {
25478		var start = this._core._current,
25479			end = start + this._core.settings.items,
25480			visible = this._core.$stage.children().toArray().slice(start, end);
25481			heights = [],
25482			maxheight = 0;
25483
25484		$.each(visible, function(index, item) {
25485			heights.push($(item).height());
25486		});
25487
25488		maxheight = Math.max.apply(null, heights);
25489
25490		this._core.$stage.parent()
25491			.height(maxheight)
25492			.addClass(this._core.settings.autoHeightClass);
25493	};
25494
25495	AutoHeight.prototype.destroy = function() {
25496		var handler, property;
25497
25498		for (handler in this._handlers) {
25499			this._core.$element.off(handler, this._handlers[handler]);
25500		}
25501		for (property in Object.getOwnPropertyNames(this)) {
25502			typeof this[property] != 'function' && (this[property] = null);
25503		}
25504	};
25505
25506	$.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
25507
25508})(window.Zepto || window.jQuery, window, document);
25509
25510/**
25511 * Video Plugin
25512 * @version 2.0.0-beta.3
25513 * @author Bartosz Wojciechowski
25514 * @license The MIT License (MIT)
25515 */
25516;(function($, window, document, undefined) {
25517
25518	/**
25519	 * Creates the video plugin.
25520	 * @class The Video Plugin
25521	 * @param {Owl} carousel - The Owl Carousel
25522	 */
25523	var Video = function(carousel) {
25524		/**
25525		 * Reference to the core.
25526		 * @protected
25527		 * @type {Owl}
25528		 */
25529		this._core = carousel;
25530
25531		/**
25532		 * Cache all video URLs.
25533		 * @protected
25534		 * @type {Object}
25535		 */
25536		this._videos = {};
25537
25538		/**
25539		 * Current playing item.
25540		 * @protected
25541		 * @type {jQuery}
25542		 */
25543		this._playing = null;
25544
25545		/**
25546		 * All event handlers.
25547		 * @todo The cloned content removale is too late
25548		 * @protected
25549		 * @type {Object}
25550		 */
25551		this._handlers = {
25552			'initialized.owl.carousel': $.proxy(function(e) {
25553				if (e.namespace) {
25554					this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });
25555				}
25556			}, this),
25557			'resize.owl.carousel': $.proxy(function(e) {
25558				if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
25559					e.preventDefault();
25560				}
25561			}, this),
25562			'refreshed.owl.carousel': $.proxy(function(e) {
25563				if (e.namespace && this._core.is('resizing')) {
25564					this._core.$stage.find('.cloned .owl-video-frame').remove();
25565				}
25566			}, this),
25567			'changed.owl.carousel': $.proxy(function(e) {
25568				if (e.namespace && e.property.name === 'position' && this._playing) {
25569					this.stop();
25570				}
25571			}, this),
25572			'prepared.owl.carousel': $.proxy(function(e) {
25573				if (!e.namespace) {
25574					return;
25575				}
25576
25577				var $element = $(e.content).find('.owl-video');
25578
25579				if ($element.length) {
25580					$element.css('display', 'none');
25581					this.fetch($element, $(e.content));
25582				}
25583			}, this)
25584		};
25585
25586		// set default options
25587		this._core.options = $.extend({}, Video.Defaults, this._core.options);
25588
25589		// register event handlers
25590		this._core.$element.on(this._handlers);
25591
25592		this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
25593			this.play(e);
25594		}, this));
25595	};
25596
25597	/**
25598	 * Default options.
25599	 * @public
25600	 */
25601	Video.Defaults = {
25602		video: false,
25603		videoHeight: false,
25604		videoWidth: false
25605	};
25606
25607	/**
25608	 * Gets the video ID and the type (YouTube/Vimeo only).
25609	 * @protected
25610	 * @param {jQuery} target - The target containing the video data.
25611	 * @param {jQuery} item - The item containing the video.
25612	 */
25613	Video.prototype.fetch = function(target, item) {
25614		var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube',
25615			id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'),
25616			width = target.attr('data-width') || this._core.settings.videoWidth,
25617			height = target.attr('data-height') || this._core.settings.videoHeight,
25618			url = target.attr('href');
25619
25620		if (url) {
25621			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+)?/);
25622
25623			if (id[3].indexOf('youtu') > -1) {
25624				type = 'youtube';
25625			} else if (id[3].indexOf('vimeo') > -1) {
25626				type = 'vimeo';
25627			} else {
25628				throw new Error('Video URL not supported.');
25629			}
25630			id = id[6];
25631		} else {
25632			throw new Error('Missing video URL.');
25633		}
25634
25635		this._videos[url] = {
25636			type: type,
25637			id: id,
25638			width: width,
25639			height: height
25640		};
25641
25642		item.attr('data-video', url);
25643
25644		this.thumbnail(target, this._videos[url]);
25645	};
25646
25647	/**
25648	 * Creates video thumbnail.
25649	 * @protected
25650	 * @param {jQuery} target - The target containing the video data.
25651	 * @param {Object} info - The video info object.
25652	 * @see `fetch`
25653	 */
25654	Video.prototype.thumbnail = function(target, video) {
25655		var tnLink,
25656			icon,
25657			path,
25658			dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
25659			customTn = target.find('img'),
25660			srcType = 'src',
25661			lazyClass = '',
25662			settings = this._core.settings,
25663			create = function(path) {
25664				icon = '<div class="owl-video-play-icon"></div>';
25665
25666				if (settings.lazyLoad) {
25667					tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';
25668				} else {
25669					tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';
25670				}
25671				target.after(tnLink);
25672				target.after(icon);
25673			};
25674
25675		// wrap video content into owl-video-wrapper div
25676		target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');
25677
25678		if (this._core.settings.lazyLoad) {
25679			srcType = 'data-src';
25680			lazyClass = 'owl-lazy';
25681		}
25682
25683		// custom thumbnail
25684		if (customTn.length) {
25685			create(customTn.attr(srcType));
25686			customTn.remove();
25687			return false;
25688		}
25689
25690		if (video.type === 'youtube') {
25691			path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
25692			create(path);
25693		} else if (video.type === 'vimeo') {
25694			$.ajax({
25695				type: 'GET',
25696				url: '//vimeo.com/api/v2/video/' + video.id + '.json',
25697				jsonp: 'callback',
25698				dataType: 'jsonp',
25699				success: function(data) {
25700					path = data[0].thumbnail_large;
25701					create(path);
25702				}
25703			});
25704		}
25705	};
25706
25707	/**
25708	 * Stops the current video.
25709	 * @public
25710	 */
25711	Video.prototype.stop = function() {
25712		this._core.trigger('stop', null, 'video');
25713		this._playing.find('.owl-video-frame').remove();
25714		this._playing.removeClass('owl-video-playing');
25715		this._playing = null;
25716		this._core.leave('playing');
25717		this._core.trigger('stopped', null, 'video');
25718	};
25719
25720	/**
25721	 * Starts the current video.
25722	 * @public
25723	 * @param {Event} event - The event arguments.
25724	 */
25725	Video.prototype.play = function(event) {
25726		var target = $(event.target),
25727			item = target.closest('.' + this._core.settings.itemClass),
25728			video = this._videos[item.attr('data-video')],
25729			width = video.width || '100%',
25730			height = video.height || this._core.$stage.height(),
25731			html;
25732
25733		if (this._playing) {
25734			return;
25735		}
25736
25737		this._core.enter('playing');
25738		this._core.trigger('play', null, 'video');
25739
25740		item = this._core.items(this._core.relative(item.index()));
25741
25742		this._core.reset(item.index());
25743
25744		if (video.type === 'youtube') {
25745			html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' +
25746				video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';
25747		} else if (video.type === 'vimeo') {
25748			html = '<iframe src="//player.vimeo.com/video/' + video.id +
25749				'?autoplay=1" width="' + width + '" height="' + height +
25750				'" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
25751		}
25752
25753		$('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video'));
25754
25755		this._playing = item.addClass('owl-video-playing');
25756	};
25757
25758	/**
25759	 * Checks whether an video is currently in full screen mode or not.
25760	 * @todo Bad style because looks like a readonly method but changes members.
25761	 * @protected
25762	 * @returns {Boolean}
25763	 */
25764	Video.prototype.isInFullScreen = function() {
25765		var element = document.fullscreenElement || document.mozFullScreenElement ||
25766				document.webkitFullscreenElement;
25767
25768		return element && $(element).parent().hasClass('owl-video-frame');
25769	};
25770
25771	/**
25772	 * Destroys the plugin.
25773	 */
25774	Video.prototype.destroy = function() {
25775		var handler, property;
25776
25777		this._core.$element.off('click.owl.video');
25778
25779		for (handler in this._handlers) {
25780			this._core.$element.off(handler, this._handlers[handler]);
25781		}
25782		for (property in Object.getOwnPropertyNames(this)) {
25783			typeof this[property] != 'function' && (this[property] = null);
25784		}
25785	};
25786
25787	$.fn.owlCarousel.Constructor.Plugins.Video = Video;
25788
25789})(window.Zepto || window.jQuery, window, document);
25790
25791/**
25792 * Animate Plugin
25793 * @version 2.0.0-beta.3
25794 * @author Bartosz Wojciechowski
25795 * @license The MIT License (MIT)
25796 */
25797;(function($, window, document, undefined) {
25798
25799	/**
25800	 * Creates the animate plugin.
25801	 * @class The Navigation Plugin
25802	 * @param {Owl} scope - The Owl Carousel
25803	 */
25804	var Animate = function(scope) {
25805		this.core = scope;
25806		this.core.options = $.extend({}, Animate.Defaults, this.core.options);
25807		this.swapping = true;
25808		this.previous = undefined;
25809		this.next = undefined;
25810
25811		this.handlers = {
25812			'change.owl.carousel': $.proxy(function(e) {
25813				if (e.namespace && e.property.name == 'position') {
25814					this.previous = this.core.current();
25815					this.next = e.property.value;
25816				}
25817			}, this),
25818			'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
25819				if (e.namespace) {
25820					this.swapping = e.type == 'translated';
25821				}
25822			}, this),
25823			'translate.owl.carousel': $.proxy(function(e) {
25824				if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
25825					this.swap();
25826				}
25827			}, this)
25828		};
25829
25830		this.core.$element.on(this.handlers);
25831	};
25832
25833	/**
25834	 * Default options.
25835	 * @public
25836	 */
25837	Animate.Defaults = {
25838		animateOut: false,
25839		animateIn: false
25840	};
25841
25842	/**
25843	 * Toggles the animation classes whenever an translations starts.
25844	 * @protected
25845	 * @returns {Boolean|undefined}
25846	 */
25847	Animate.prototype.swap = function() {
25848
25849		if (this.core.settings.items !== 1) {
25850			return;
25851		}
25852
25853		if (!$.support.animation || !$.support.transition) {
25854			return;
25855		}
25856
25857		this.core.speed(0);
25858
25859		var left,
25860			clear = $.proxy(this.clear, this),
25861			previous = this.core.$stage.children().eq(this.previous),
25862			next = this.core.$stage.children().eq(this.next),
25863			incoming = this.core.settings.animateIn,
25864			outgoing = this.core.settings.animateOut;
25865
25866		if (this.core.current() === this.previous) {
25867			return;
25868		}
25869
25870		if (outgoing) {
25871			left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
25872			previous.css( { 'left': left + 'px' } )
25873				.addClass('animated owl-animated-out')
25874				.addClass(outgoing)
25875				.on($.support.animation.end, clear);
25876		}
25877
25878		if (incoming) {
25879			next.addClass('animated owl-animated-in')
25880				.addClass(incoming)
25881				.on($.support.animation.end, clear);
25882		}
25883	};
25884
25885	Animate.prototype.clear = function(e) {
25886		if ($(e.target).hasClass('animated')) {
25887			$(e.target).css( { 'left': '' } )
25888				.removeClass('animated owl-animated-out owl-animated-in')
25889				.removeClass(this.core.settings.animateIn)
25890				.removeClass(this.core.settings.animateOut);
25891			this.core.onTransitionEnd();
25892		}
25893	};
25894
25895	/**
25896	 * Destroys the plugin.
25897	 * @public
25898	 */
25899	Animate.prototype.destroy = function() {
25900		var handler, property;
25901
25902		for (handler in this.handlers) {
25903			this.core.$element.off(handler, this.handlers[handler]);
25904		}
25905		for (property in Object.getOwnPropertyNames(this)) {
25906			typeof this[property] != 'function' && (this[property] = null);
25907		}
25908	};
25909
25910	$.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
25911
25912})(window.Zepto || window.jQuery, window, document);
25913
25914/**
25915 * Autoplay Plugin
25916 * @version 2.0.0-beta.3
25917 * @author Bartosz Wojciechowski
25918 * @author Artus Kolanowski
25919 * @license The MIT License (MIT)
25920 */
25921;(function($, window, document, undefined) {
25922
25923	/**
25924	 * Creates the autoplay plugin.
25925	 * @class The Autoplay Plugin
25926	 * @param {Owl} scope - The Owl Carousel
25927	 */
25928	var Autoplay = function(carousel) {
25929		/**
25930		 * Reference to the core.
25931		 * @protected
25932		 * @type {Owl}
25933		 */
25934		this._core = carousel;
25935
25936		/**
25937		 * The autoplay interval.
25938		 * @type {Number}
25939		 */
25940		this._interval = null;
25941
25942		/**
25943		 * Indicates whenever the autoplay is paused.
25944		 * @type {Boolean}
25945		 */
25946		this._paused = false;
25947
25948		/**
25949		 * All event handlers.
25950		 * @protected
25951		 * @type {Object}
25952		 */
25953		this._handlers = {
25954			'changed.owl.carousel': $.proxy(function(e) {
25955				if (e.namespace && e.property.name === 'settings') {
25956					if (this._core.settings.autoplay) {
25957						this.play();
25958					} else {
25959						this.stop();
25960					}
25961				}
25962			}, this),
25963			'initialized.owl.carousel': $.proxy(function(e) {
25964				if (e.namespace && this._core.settings.autoplay) {
25965					this.play();
25966				}
25967			}, this),
25968			'play.owl.autoplay': $.proxy(function(e, t, s) {
25969				if (e.namespace) {
25970					this.play(t, s);
25971				}
25972			}, this),
25973			'stop.owl.autoplay': $.proxy(function(e) {
25974				if (e.namespace) {
25975					this.stop();
25976				}
25977			}, this),
25978			'mouseover.owl.autoplay': $.proxy(function() {
25979				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
25980					this.pause();
25981				}
25982			}, this),
25983			'mouseleave.owl.autoplay': $.proxy(function() {
25984				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
25985					this.play();
25986				}
25987			}, this)
25988		};
25989
25990		// register event handlers
25991		this._core.$element.on(this._handlers);
25992
25993		// set default options
25994		this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
25995	};
25996
25997	/**
25998	 * Default options.
25999	 * @public
26000	 */
26001	Autoplay.Defaults = {
26002		autoplay: false,
26003		autoplayTimeout: 5000,
26004		autoplayHoverPause: false,
26005		autoplaySpeed: false
26006	};
26007
26008	/**
26009	 * Starts the autoplay.
26010	 * @public
26011	 * @param {Number} [timeout] - The interval before the next animation starts.
26012	 * @param {Number} [speed] - The animation speed for the animations.
26013	 */
26014	Autoplay.prototype.play = function(timeout, speed) {
26015		this._paused = false;
26016
26017		if (this._core.is('rotating')) {
26018			return;
26019		}
26020
26021		this._core.enter('rotating');
26022
26023		this._interval = window.setInterval($.proxy(function() {
26024			if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) {
26025				return;
26026			}
26027			this._core.next(speed || this._core.settings.autoplaySpeed);
26028		}, this), timeout || this._core.settings.autoplayTimeout);
26029	};
26030
26031	/**
26032	 * Stops the autoplay.
26033	 * @public
26034	 */
26035	Autoplay.prototype.stop = function() {
26036		if (!this._core.is('rotating')) {
26037			return;
26038		}
26039
26040		window.clearInterval(this._interval);
26041		this._core.leave('rotating');
26042	};
26043
26044	/**
26045	 * Stops the autoplay.
26046	 * @public
26047	 */
26048	Autoplay.prototype.pause = function() {
26049		if (!this._core.is('rotating')) {
26050			return;
26051		}
26052
26053		this._paused = true;
26054	};
26055
26056	/**
26057	 * Destroys the plugin.
26058	 */
26059	Autoplay.prototype.destroy = function() {
26060		var handler, property;
26061
26062		this.stop();
26063
26064		for (handler in this._handlers) {
26065			this._core.$element.off(handler, this._handlers[handler]);
26066		}
26067		for (property in Object.getOwnPropertyNames(this)) {
26068			typeof this[property] != 'function' && (this[property] = null);
26069		}
26070	};
26071
26072	$.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
26073
26074})(window.Zepto || window.jQuery, window, document);
26075
26076/**
26077 * Navigation Plugin
26078 * @version 2.0.0-beta.3
26079 * @author Artus Kolanowski
26080 * @license The MIT License (MIT)
26081 */
26082;(function($, window, document, undefined) {
26083	'use strict';
26084
26085	/**
26086	 * Creates the navigation plugin.
26087	 * @class The Navigation Plugin
26088	 * @param {Owl} carousel - The Owl Carousel.
26089	 */
26090	var Navigation = function(carousel) {
26091		/**
26092		 * Reference to the core.
26093		 * @protected
26094		 * @type {Owl}
26095		 */
26096		this._core = carousel;
26097
26098		/**
26099		 * Indicates whether the plugin is initialized or not.
26100		 * @protected
26101		 * @type {Boolean}
26102		 */
26103		this._initialized = false;
26104
26105		/**
26106		 * The current paging indexes.
26107		 * @protected
26108		 * @type {Array}
26109		 */
26110		this._pages = [];
26111
26112		/**
26113		 * All DOM elements of the user interface.
26114		 * @protected
26115		 * @type {Object}
26116		 */
26117		this._controls = {};
26118
26119		/**
26120		 * Markup for an indicator.
26121		 * @protected
26122		 * @type {Array.<String>}
26123		 */
26124		this._templates = [];
26125
26126		/**
26127		 * The carousel element.
26128		 * @type {jQuery}
26129		 */
26130		this.$element = this._core.$element;
26131
26132		/**
26133		 * Overridden methods of the carousel.
26134		 * @protected
26135		 * @type {Object}
26136		 */
26137		this._overrides = {
26138			next: this._core.next,
26139			prev: this._core.prev,
26140			to: this._core.to
26141		};
26142
26143		/**
26144		 * All event handlers.
26145		 * @protected
26146		 * @type {Object}
26147		 */
26148		this._handlers = {
26149			'prepared.owl.carousel': $.proxy(function(e) {
26150				if (e.namespace && this._core.settings.dotsData) {
26151					this._templates.push('<div class="' + this._core.settings.dotClass + '">' +
26152						$(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>');
26153				}
26154			}, this),
26155			'added.owl.carousel': $.proxy(function(e) {
26156				if (e.namespace && this._core.settings.dotsData) {
26157					this._templates.splice(e.position, 0, this._templates.pop());
26158				}
26159			}, this),
26160			'remove.owl.carousel': $.proxy(function(e) {
26161				if (e.namespace && this._core.settings.dotsData) {
26162					this._templates.splice(e.position, 1);
26163				}
26164			}, this),
26165			'changed.owl.carousel': $.proxy(function(e) {
26166				if (e.namespace && e.property.name == 'position') {
26167					this.draw();
26168				}
26169			}, this),
26170			'initialized.owl.carousel': $.proxy(function(e) {
26171				if (e.namespace && !this._initialized) {
26172					this._core.trigger('initialize', null, 'navigation');
26173					this.initialize();
26174					this.update();
26175					this.draw();
26176					this._initialized = true;
26177					this._core.trigger('initialized', null, 'navigation');
26178				}
26179			}, this),
26180			'refreshed.owl.carousel': $.proxy(function(e) {
26181				if (e.namespace && this._initialized) {
26182					this._core.trigger('refresh', null, 'navigation');
26183					this.update();
26184					this.draw();
26185					this._core.trigger('refreshed', null, 'navigation');
26186				}
26187			}, this)
26188		};
26189
26190		// set default options
26191		this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
26192
26193		// register event handlers
26194		this.$element.on(this._handlers);
26195	};
26196
26197	/**
26198	 * Default options.
26199	 * @public
26200	 * @todo Rename `slideBy` to `navBy`
26201	 */
26202	Navigation.Defaults = {
26203		nav: false,
26204		navText: [ 'prev', 'next' ],
26205		navSpeed: false,
26206		navElement: 'button type="button"',
26207		navContainer: false,
26208		navContainerClass: 'owl-nav',
26209		navClass: [ 'owl-prev', 'owl-next' ],
26210		slideBy: 1,
26211		dotClass: 'owl-dot',
26212		dotsClass: 'owl-dots',
26213		dots: true,
26214		dotsEach: false,
26215		dotsData: false,
26216		dotsSpeed: false,
26217		dotsContainer: false
26218	};
26219
26220	/**
26221	 * Initializes the layout of the plugin and extends the carousel.
26222	 * @protected
26223	 */
26224	Navigation.prototype.initialize = function() {
26225		var override,
26226			settings = this._core.settings;
26227
26228		// create DOM structure for relative navigation
26229		this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
26230			: $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');
26231
26232		this._controls.$previous = $('<' + settings.navElement[0] + '>')
26233			.addClass(settings.navClass[0])
26234			.html(settings.navText[0])
26235			.prependTo(this._controls.$relative)
26236			.on('click', $.proxy(function(e) {
26237				this.prev(settings.navSpeed);
26238			}, this));
26239		this._controls.$next = $('<' + settings.navElement[1] + '>')
26240			.addClass(settings.navClass[1])
26241			.html(settings.navText[1])
26242			.appendTo(this._controls.$relative)
26243			.on('click', $.proxy(function(e) {
26244				this.next(settings.navSpeed);
26245			}, this));
26246
26247		// create DOM structure for absolute navigation
26248		if (!settings.dotsData) {
26249			this._templates = [ $('<button>')
26250				.addClass(settings.dotClass)
26251				.append($('<span>'))
26252				.prop('outerHTML') ];
26253		}
26254
26255		this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
26256			: $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');
26257
26258		this._controls.$absolute.on('click', 'div, button', $.proxy(function(e) {
26259			var index = $(e.target).parent().is(this._controls.$absolute)
26260				? $(e.target).index() : $(e.target).parent().index();
26261
26262			e.preventDefault();
26263
26264			this.to(index, settings.dotsSpeed);
26265		}, this));
26266
26267		// override public methods of the carousel
26268		for (override in this._overrides) {
26269			this._core[override] = $.proxy(this[override], this);
26270		}
26271	};
26272
26273	/**
26274	 * Destroys the plugin.
26275	 * @protected
26276	 */
26277	Navigation.prototype.destroy = function() {
26278		var handler, control, property, override;
26279
26280		for (handler in this._handlers) {
26281			this.$element.off(handler, this._handlers[handler]);
26282		}
26283		for (control in this._controls) {
26284			this._controls[control].remove();
26285		}
26286		for (override in this.overides) {
26287			this._core[override] = this._overrides[override];
26288		}
26289		for (property in Object.getOwnPropertyNames(this)) {
26290			typeof this[property] != 'function' && (this[property] = null);
26291		}
26292	};
26293
26294	/**
26295	 * Updates the internal state.
26296	 * @protected
26297	 */
26298	Navigation.prototype.update = function() {
26299		var i, j, k,
26300			lower = this._core.clones().length / 2,
26301			upper = lower + this._core.items().length,
26302			maximum = this._core.maximum(true),
26303			settings = this._core.settings,
26304			size = settings.center || settings.autoWidth || settings.dotsData
26305				? 1 : settings.dotsEach || settings.items;
26306
26307		if (settings.slideBy !== 'page') {
26308			settings.slideBy = Math.min(settings.slideBy, settings.items);
26309		}
26310
26311		if (settings.dots || settings.slideBy == 'page') {
26312			this._pages = [];
26313
26314			for (i = lower, j = 0, k = 0; i < upper; i++) {
26315				if (j >= size || j === 0) {
26316					this._pages.push({
26317						start: Math.min(maximum, i - lower),
26318						end: i - lower + size - 1
26319					});
26320					if (Math.min(maximum, i - lower) === maximum) {
26321						break;
26322					}
26323					j = 0, ++k;
26324				}
26325				j += this._core.mergers(this._core.relative(i));
26326			}
26327		}
26328	};
26329
26330	/**
26331	 * Draws the user interface.
26332	 * @todo The option `dotsData` wont work.
26333	 * @protected
26334	 */
26335	Navigation.prototype.draw = function() {
26336		var difference,
26337			settings = this._core.settings,
26338			disabled = this._core.items().length <= settings.items,
26339			index = this._core.relative(this._core.current()),
26340			loop = settings.loop || settings.rewind;
26341
26342		this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);
26343
26344		if (settings.nav) {
26345			this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
26346			this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
26347		}
26348
26349		this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);
26350
26351		if (settings.dots) {
26352			difference = this._pages.length - this._controls.$absolute.children().length;
26353
26354			if (settings.dotsData && difference !== 0) {
26355				this._controls.$absolute.html(this._templates.join(''));
26356			} else if (difference > 0) {
26357				this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
26358			} else if (difference < 0) {
26359				this._controls.$absolute.children().slice(difference).remove();
26360			}
26361
26362			this._controls.$absolute.find('.active').removeClass('active');
26363			this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
26364		}
26365	};
26366
26367	/**
26368	 * Extends event data.
26369	 * @protected
26370	 * @param {Event} event - The event object which gets thrown.
26371	 */
26372	Navigation.prototype.onTrigger = function(event) {
26373		var settings = this._core.settings;
26374
26375		event.page = {
26376			index: $.inArray(this.current(), this._pages),
26377			count: this._pages.length,
26378			size: settings && (settings.center || settings.autoWidth || settings.dotsData
26379				? 1 : settings.dotsEach || settings.items)
26380		};
26381	};
26382
26383	/**
26384	 * Gets the current page position of the carousel.
26385	 * @protected
26386	 * @returns {Number}
26387	 */
26388	Navigation.prototype.current = function() {
26389		var current = this._core.relative(this._core.current());
26390		return $.grep(this._pages, $.proxy(function(page, index) {
26391			return page.start <= current && page.end >= current;
26392		}, this)).pop();
26393	};
26394
26395	/**
26396	 * Gets the current succesor/predecessor position.
26397	 * @protected
26398	 * @returns {Number}
26399	 */
26400	Navigation.prototype.getPosition = function(successor) {
26401		var position, length,
26402			settings = this._core.settings;
26403
26404		if (settings.slideBy == 'page') {
26405			position = $.inArray(this.current(), this._pages);
26406			length = this._pages.length;
26407			successor ? ++position : --position;
vendor: 5,674 bytes, lines 26408-26632
26408			position = this._pages[((position % length) + length) % length].start;
26409		} else {
26410			position = this._core.relative(this._core.current());
26411			length = this._core.items().length;
26412			successor ? position += settings.slideBy : position -= settings.slideBy;
26413		}
26414
26415		return position;
26416	};
26417
26418	/**
26419	 * Slides to the next item or page.
26420	 * @public
26421	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
26422	 */
26423	Navigation.prototype.next = function(speed) {
26424		$.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
26425	};
26426
26427	/**
26428	 * Slides to the previous item or page.
26429	 * @public
26430	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
26431	 */
26432	Navigation.prototype.prev = function(speed) {
26433		$.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
26434	};
26435
26436	/**
26437	 * Slides to the specified item or page.
26438	 * @public
26439	 * @param {Number} position - The position of the item or page.
26440	 * @param {Number} [speed] - The time in milliseconds for the transition.
26441	 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
26442	 */
26443	Navigation.prototype.to = function(position, speed, standard) {
26444		var length;
26445
26446		if (!standard) {
26447			length = this._pages.length;
26448			$.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
26449		} else {
26450			$.proxy(this._overrides.to, this._core)(position, speed);
26451		}
26452	};
26453
26454	$.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
26455
26456})(window.Zepto || window.jQuery, window, document);
26457
26458/**
26459 * Hash Plugin
26460 * @version 2.0.0-beta.3
26461 * @author Artus Kolanowski
26462 * @license The MIT License (MIT)
26463 */
26464;(function($, window, document, undefined) {
26465	'use strict';
26466
26467	/**
26468	 * Creates the hash plugin.
26469	 * @class The Hash Plugin
26470	 * @param {Owl} carousel - The Owl Carousel
26471	 */
26472	var Hash = function(carousel) {
26473		/**
26474		 * Reference to the core.
26475		 * @protected
26476		 * @type {Owl}
26477		 */
26478		this._core = carousel;
26479
26480		/**
26481		 * Hash index for the items.
26482		 * @protected
26483		 * @type {Object}
26484		 */
26485		this._hashes = {};
26486
26487		/**
26488		 * The carousel element.
26489		 * @type {jQuery}
26490		 */
26491		this.$element = this._core.$element;
26492
26493		/**
26494		 * All event handlers.
26495		 * @protected
26496		 * @type {Object}
26497		 */
26498		this._handlers = {
26499			'initialized.owl.carousel': $.proxy(function(e) {
26500				if (e.namespace && this._core.settings.startPosition === 'URLHash') {
26501					$(window).trigger('hashchange.owl.navigation');
26502				}
26503			}, this),
26504			'prepared.owl.carousel': $.proxy(function(e) {
26505				if (e.namespace) {
26506					var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');
26507
26508					if (!hash) {
26509						return;
26510					}
26511
26512					this._hashes[hash] = e.content;
26513				}
26514			}, this),
26515			'changed.owl.carousel': $.proxy(function(e) {
26516				if (e.namespace && e.property.name === 'position') {
26517					var current = this._core.items(this._core.relative(this._core.current())),
26518						hash = $.map(this._hashes, function(item, hash) {
26519							return item === current ? hash : null;
26520						}).join();
26521
26522					if (!hash || window.location.hash.slice(1) === hash) {
26523						return;
26524					}
26525
26526					window.location.hash = hash;
26527				}
26528			}, this)
26529		};
26530
26531		// set default options
26532		this._core.options = $.extend({}, Hash.Defaults, this._core.options);
26533
26534		// register the event handlers
26535		this.$element.on(this._handlers);
26536
26537		// register event listener for hash navigation
26538		/*$(window).on('hashchange.owl.navigation', $.proxy(function(e) {
26539			var hash = window.location.hash.substring(1),
26540				items = this._core.$stage.children(),
26541				position = this._hashes[hash] && items.index(this._hashes[hash]);
26542
26543			if (position === undefined || position === this._core.current()) {
26544				return;
26545			}
26546
26547			this._core.to(this._core.relative(position), false, true);
26548		}, this));*/
26549	};
26550
26551	/**
26552	 * Default options.
26553	 * @public
26554	 */
26555	Hash.Defaults = {
26556		URLhashListener: false
26557	};
26558
26559	/**
26560	 * Destroys the plugin.
26561	 * @public
26562	 */
26563	Hash.prototype.destroy = function() {
26564		var handler, property;
26565
26566		$(window).off('hashchange.owl.navigation');
26567
26568		for (handler in this._handlers) {
26569			this._core.$element.off(handler, this._handlers[handler]);
26570		}
26571		for (property in Object.getOwnPropertyNames(this)) {
26572			typeof this[property] != 'function' && (this[property] = null);
26573		}
26574	};
26575
26576	$.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
26577
26578})(window.Zepto || window.jQuery, window, document);
26579
26580/**
26581 * Support Plugin
26582 *
26583 * @version 2.0.0-beta.3
26584 * @author Vivid Planet Software GmbH
26585 * @author Artus Kolanowski
26586 * @license The MIT License (MIT)
26587 */
26588;(function($, window, document, undefined) {
26589
26590	var style = $('<support>').get(0).style,
26591		prefixes = 'Webkit Moz O ms'.split(' '),
26592		events = {
26593			transition: {
26594				end: {
26595					WebkitTransition: 'webkitTransitionEnd',
26596					MozTransition: 'transitionend',
26597					OTransition: 'oTransitionEnd',
26598					transition: 'transitionend'
26599				}
26600			},
26601			animation: {
26602				end: {
26603					WebkitAnimation: 'webkitAnimationEnd',
26604					MozAnimation: 'animationend',
26605					OAnimation: 'oAnimationEnd',
26606					animation: 'animationend'
26607				}
26608			}
26609		},
26610		tests = {
26611			csstransforms: function() {
26612				return !!test('transform');
26613			},
26614			csstransforms3d: function() {
26615				return !!test('perspective');
26616			},
26617			csstransitions: function() {
26618				return !!test('transition');
26619			},
26620			cssanimations: function() {
26621				return !!test('animation');
26622			}
26623		};
26624
26625	function test(property, prefixed) {
26626		var result = false,
26627			upper = property.charAt(0).toUpperCase() + property.slice(1);
26628
26629		$.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {
26630			if (style[property] !== undefined) {
26631				result = prefixed ? property : true;
26632				return false;
26633			}
26634		});
26635
26636		return result;
26637	}
26638
26639	function prefixed(property) {
26640		return test(property, true);
26641	}
26642
26643	if (tests.csstransitions()) {
26644		/* jshint -W053 */
26645		$.support.transition = new String(prefixed('transition'))
26646		$.support.transition.end = events.transition.end[ $.support.transition ];
26647	}
26648
26649	if (tests.cssanimations()) {
26650		/* jshint -W053 */
26651		$.support.animation = new String(prefixed('animation'))
26652		$.support.animation.end = events.animation.end[ $.support.animation ];
26653	}
26654
26655	if (tests.csstransforms()) {
26656		/* jshint -W053 */
26657		$.support.transform = new String(prefixed('transform'));
26658		$.support.transform3d = tests.csstransforms3d();
26659	}
26660
26661})(window.Zepto || window.jQuery, window, document);
26662
26663(function(window, document, undefined) {
26664
26665	/**
26666	 * Find the absolute position of an element
26667	 */
26668	var absPos = function(element) {
26669		var offsetLeft, offsetTop;
26670		offsetLeft = offsetTop = 0;
26671		if (element.offsetParent) {
26672			do {
26673				offsetLeft += element.offsetLeft;
26674				offsetTop += element.offsetTop;
26675			} while (element = element.offsetParent);
26676		}
26677		return [offsetLeft, offsetTop];
26678	};
26679
26680	/**
26681	 * @constructor Progress Circle class
26682	 * @param params.canvas Canvas on which the circles will be drawn.
26683	 * @param params.minRadius Inner radius of the innermost circle, in px.
26684	 * @param params.arcWidth Width of each circle(to be more accurate, ring).
26685	 * @param params.gapWidth Space between each circle.
26686	 * @param params.centerX X coordinate of the center of circles.
26687	 * @param params.centerY Y coordinate of the center of circles.
26688	 * @param params.infoLineBaseAngle Base angle of the info line.
26689	 * @param params.infoLineAngleInterval Angles between the info lines.
26690	 */
26691	var ProgressCircle = function(params) {
26692		this.canvas = params.canvas;
26693		this.minRadius = params.minRadius || 15;
26694		this.arcWidth = params.arcWidth || 5;
26695		this.gapWidth = params.gapWidth || 3;
26696		this.centerX = params.centerX || this.canvas.width / 2;
26697		this.centerY = params.centerY || this.canvas.height / 2;
26698		this.infoLineLength = params.infoLineLength || 60;
26699		this.horizLineLength = params.horizLineLength || 10;
26700		this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8;
26701		this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6;
26702
26703		this.context = this.canvas.getContext('2d');
26704
26705		this.width = this.canvas.width;
26706		this.height = this.canvas.height;
26707
26708		this.circles = [];
26709		this.runningCount = 0;
26710	};
26711
26712	ProgressCircle.prototype = {
26713		constructor: ProgressCircle,
26714
26715		/**
26716		 * @method Adds an progress monitor entry.
26717		 * @param params.fillColor Color to fill in the circle.
26718		 * @param params.outlineColor Color to outline the circle.
26719		 * @param params.progressListener Callback function to fetch the progress.
26720		 * @param params.infoListener Callback function to fetch the info.
26721		 * @returns this
26722		 */
26723		addEntry: function(params) {
26724			this.circles.push(new Circle({
26725				canvas: this.canvas,
26726				context: this.context,
26727				centerX: this.centerX,
26728				centerY: this.centerY,
26729				innerRadius: this.minRadius + this.circles.length *
26730					(this.gapWidth + this.arcWidth),
26731				arcWidth: this.arcWidth,
26732				infoLineLength: this.infoLineLength,
26733				horizLineLength: this.horizLineLength,
26734
26735				id: this.circles.length,
26736				fillColor: params.fillColor,
26737				outlineColor: params.outlineColor,
26738				progressListener: params.progressListener,
26739				infoListener: params.infoListener,
26740				infoLineAngle: this.infoLineBaseAngle +
26741					this.circles.length * this.infoLineAngleInterval,
26742			}));
26743
26744			return this;
26745		},
26746
26747		/**
26748		 * @method Starts the monitor and updates with the given interval.
26749		 * @param interval Interval between updates, in millisecond.
26750		 * @returns this
26751		 */
26752		start: function(interval) {
26753			var self = this;
26754			this.timer = setInterval(function() {
26755				self._update();
26756			}, interval || 33);
26757
26758			return this;
26759		},
26760
26761		/**
26762		 * @method Stop the animation.
26763		 */
26764		stop: function() {
26765			clearTimeout(this.timer);
26766		},
26767
26768		/**
26769		 * @private
26770		 * @method Call update on each circle and redraw them.
26771		 * @returns this
26772		 */
26773		_update: function() {
26774			this._clear();
26775			this.circles.forEach(function(circle, idx, array) {
26776				circle.update();
26777			});
26778
26779			return this;
26780		},
26781
26782		/**
26783		 * @private
26784		 * @method Clear the canvas.
26785		 * @returns this
26786		 */
26787		_clear: function() {
26788			this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
26789
26790			return this;
26791		},
26792
26793	};
26794
26795	/**
26796	 * @private
26797	 * @class Individual progress circle.
26798	 * @param params.canvas Canvas on which the circle will be drawn.
26799	 * @param params.context Context of the canvas.
26800	 * @param params.innerRadius Inner radius of the circle, in px.
26801	 * @param params.arcWidth Width of each arc(circle).
26802	 * @param params.gapWidth Distance between each arc.
26803	 * @param params.centerX X coordinate of the center of circles.
26804	 * @param params.centerY Y coordinate of the center of circles.
26805	 * @param params.fillColor Color to fill in the circle.
26806	 * @param params.outlineColor Color to outline the circle.
26807	 * @param params.progressListener Callback function to fetch the progress.
26808	 * @param params.infoListener Callback function to fetch the info.
26809	 * @param params.infoLineAngle Angle of info line.
26810	 */
26811	var Circle = function(params) {
26812		this.id = params.id;
26813		this.canvas = params.canvas;
26814		this.context = params.context;
26815		this.centerX = params.centerX;
26816		this.centerY = params.centerY;
26817		this.arcWidth = params.arcWidth;
26818		this.innerRadius = params.innerRadius || 0;
26819		this.fillColor = params.fillColor || '#fff';
26820		this.outlineColor = params.outlineColor || this.fillColor;
26821		this.progressListener = params.progressListener;
26822		this.infoLineLength = params.infoLineLength || 250;
26823		this.horizLineLength = params.horizLineLength || 50;
26824		this.infoListener = params.infoListener;
26825		this.infoLineAngle = params.infoLineAngle;
26826
26827		this.outerRadius = this.innerRadius + this.arcWidth;
26828
26829		// If the info listener is not registered, then don't calculate
26830		// the related coordinates
26831		if (!this.infoListener) return;
26832
26833		// calculate the info-line turning points
26834		var angle = this.infoLineAngle,
26835			arcDistance = (this.innerRadius + this.outerRadius) / 2,
26836
26837			sinA = Math.sin(angle),
26838			cosA = Math.cos(angle);
26839
26840		this.infoLineStartX = this.centerX + sinA * arcDistance;
26841		this.infoLineStartY = this.centerY - cosA * arcDistance;
26842
26843		this.infoLineMidX = this.centerX + sinA * this.infoLineLength;
26844		this.infoLineMidY = this.centerY - cosA * this.infoLineLength;
26845
26846		this.infoLineEndX = this.infoLineMidX +
26847			 (sinA < 0 ? -this.horizLineLength : this.horizLineLength);
26848		this.infoLineEndY = this.infoLineMidY;
26849
26850		var infoText = document.createElement('div'),
26851			style = infoText.style;
26852
26853		style.color = this.fillColor;
26854		style.position = 'absolute';
26855		style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px';
26856		// style.top will be calculated in the `drawInfo` method. Since
26857		// user may want to change the size of the font, so the top offset
26858		// must be updated in each loop.
26859		infoText.className = 'ProgressCircleInfo'; // For css styling
26860		infoText.id = 'progress_circle_info_' + this.id;
26861		document.body.appendChild(infoText);
26862		this.infoText = infoText;
26863	};
26864
26865	Circle.prototype = {
26866		constructor: Circle,
26867
26868		update: function() {
26869			this.progress = this.progressListener();
26870			this._draw();
26871
26872			if (this.infoListener) {
26873				this.info = this.infoListener();
26874				this._drawInfo();
26875			}
26876		},
26877
26878		/**
26879		 * @private
26880		 * @method Draw the circle on the canvas.
26881		 * @returns this
26882		 */
26883		_draw: function() {
26884			var ctx = this.context,
26885
26886				ANGLE_OFFSET = -Math.PI / 2,
26887
26888				startAngle = 0 + ANGLE_OFFSET,
26889				endAngle= startAngle + this.progress * Math.PI * 2,
26890
26891				x = this.centerX,
26892				y = this.centerY,
26893
26894				innerRadius = this.innerRadius - this.arcWidth - 1,
26895				outerRadius = this.outerRadius - this.arcWidth - 1;
26896
26897			if ( innerRadius < 0 )
26898				return;
26899
26900			ctx.fillStyle = this.fillColor;
26901			ctx.strokeStyle = this.outlineColor;
26902
26903			ctx.beginPath();
26904			ctx.arc(x, y, innerRadius, startAngle, endAngle, false);
26905			ctx.arc(x, y, outerRadius, endAngle, startAngle, true);
26906			ctx.closePath();
26907			ctx.stroke();
26908			ctx.fill();
26909
26910			return this;
26911		},
26912
26913		/**
26914		 * @private
26915		 * @method Draw the info lines and info text.
26916		 * @returns this
26917		 */
26918		_drawInfo: function() {
26919
26920			var pointList, lineHeight;
26921
26922			pointList = [
26923				[this.infoLineStartX, this.infoLineStartY],
26924				[this.infoLineMidX, this.infoLineMidY],
26925				[this.infoLineEndX, this.infoLineEndY],
26926			];
26927			this._drawSegments(pointList, false);
26928
26929			this.infoText.innerHTML = this.info;
26930
26931			lineHeight = this.infoText.offsetHeight;
26932			this.infoText.style.top = this.infoLineEndY +
26933				absPos(this.canvas)[1] - lineHeight / 2 + 'px';
26934
26935			return this;
26936		},
26937
26938		/**
26939		 * @private
26940		 * @method Helper function to draw the segments
26941		 * @param pointList An array of points in the form of [x, y].
26942		 * @param close Whether to connect the first and last point.
26943		 */
26944		_drawSegments: function(pointList, close) {
26945			var ctx = this.context;
26946
26947			ctx.beginPath();
26948			ctx.moveTo(pointList[0][0], pointList[0][1]);
26949			for (var i = 1; i < pointList.length; ++i) {
26950				ctx.lineTo(pointList[i][0], pointList[i][1]);
26951			}
26952
26953			if (close) {
26954				ctx.closePath();
26955			}
26956			ctx.stroke();
26957		},
26958	};
26959
26960	window.ProgressCircle = ProgressCircle;
26961
26962})(window, document);
26963
26964
26965
26966
26967/* =========================================================
26968 * jquery.vc_chart.js v1.0
26969 * =========================================================
26970 * Copyright 2013 Wpbakery
26971 *
26972 * Jquery chart plugin for the Visual Composer.
26973 * ========================================================= */
26974(function($){
26975	/**
26976	 * Pie chart animated.
26977	 * @param element - DOM element
26978	 * @param options - settings object.
26979	 * @constructor
26980	 */
26981	var VcChart = function(element, options) {
26982		this.el = element;
26983		this.$el = $(this.el);
26984		var $this = this;
26985		$this.options = $.extend({
26986			color: 'wpb_button',
26987			units: '',
26988			width: '',
26989			label_selector: '.vc_pie_chart_value',
26990			back_selector: '.vc_pie_chart_back',
26991			responsive: true
26992		}, options);
26993		$this.init();
26994	};
26995	VcChart.prototype = {
26996		constructor: VcChart,
26997		_progress_v: 0,
26998		animated: false,
26999		colors: {
27000			'wpb_button': 'rgba(247, 247, 247, 1)',
27001			'btn-primary': 'rgba(0, 136, 204, 1)',
27002			'btn-info': 'rgba(88, 185, 218, 1)',
27003			'btn-success': 'rgba(106, 177, 101, 1)',
27004			'btn-warning': 'rgba(255, 153, 0, 1)',
27005			'btn-danger': 'rgba(255, 103, 91, 1)',
27006			'btn-inverse': 'rgba(85, 85, 85, 1)'
27007		},
27008		init: function() {
27009			this.setupColor();
27010			this.value = this.$el.data('pie-value')/100;
27011			this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value');
27012			this.$wrapper = $('.vc_pie_wrapper', this.$el);
27013			this.$label = $(this.options.label_selector, this.$el);
27014			this.$back = $(this.options.back_selector, this.$el);
27015			this.$canvas = this.$el.find('canvas');
27016			this.arcWidth = this.$el.data('pie-width') * 2;
27017			this.draw();
27018			this.setWayPoint();
27019			if(this.options.responsive === true) this.setResponsive();
27020			if (UNCODE.isMobile) this._progress_v = this.value;
27021		},
27022		setupColor: function() {
27023			// if(typeof this.colors[this.options.color] !== 'undefined') {
27024			//     this.color = this.colors[this.options.color];
27025			// } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) {
27026			//     this.color = this.options.color;
27027			// } else {
27028			//     this.color = 'rgba(247, 247, 247, 0.2)';
27029			// }
27030			if(typeof this.options.color !== 'undefined') {
27031				this.color = this.options.color;
27032			} else this.color = 'rgba(247, 247, 247, 0.2)';
27033
27034		},
27035		setResponsive: function() {
27036			var that = this;
27037			if (!UNCODE.isMobile) {
27038				$(window).resize(function(){
27039					if(that.animated === true) that.circle.stop();
27040					that.draw(true);
27041				});
27042			}
27043		},
27044		draw: function(redraw) {
27045			var w = this.$el.addClass('vc_ready').width() * 2,
27046				border_w = this.arcWidth,
27047				radius;
27048			if(!w) w = this.$el.parents(':visible').first().width()-2;
27049			//w = Math.round(w/100*80);
27050			//if (w < 250) w = 250;
27051			radius = w/2;
27052			this.$wrapper.css({"width" : (w / 2) + "px"});
27053			this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"});
27054			this.$back.css({"width" : (w / 2), "height" : (w / 2)});
27055			this.$canvas.attr({"width" : w + "px", "height" : w + "px"});
27056			this.$el.addClass('vc_ready');
27057			this.circle = new ProgressCircle({
27058				canvas: this.$canvas.get(0),
27059				minRadius: radius,
27060				arcWidth: border_w
27061			});
27062			if(redraw === true && this.animated === true) {
27063				this._progress_v = this.value;
27064				this.circle.addEntry({
27065					fillColor: this.color,
27066					progressListener: $.proxy(this.setProgress, this)
27067				}).start();
27068			}
27069		},
27070		setProgress: function() {
27071			if (this._progress_v >= this.value) {
27072				this.circle.stop();
27073				this.animated = true;
27074				this.$label.html(this.label_value + this.options.units);
27075				return this._progress_v;
27076			}
27077			this._progress_v += 0.01;
27078			if (!isNaN(this.label_value)) {
27079				var label_value = this._progress_v/this.value*this.label_value;
27080				var val = Math.round(label_value) + this.options.units;
27081				this.$label.html(val);
27082			} else this.$label.html(this.label_value + this.options.units);
27083			return this._progress_v;
27084		},
27085		animate: function() {
27086			if(this.animated !== true) {
27087				this.circle.addEntry({
27088					fillColor: this.color,
27089					progressListener: $.proxy(this.setProgress, this)
27090				}).start(10);
27091			}
27092		},
27093		setWayPoint: function() {
27094			if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) {
27095				this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' });
27096			} else {
27097				this.animate();
27098			}
27099		}
27100	};
27101	/**
27102	 * jQuery plugin
27103	 * @param option - object with settings
27104	 * @return {*}
27105	 */
27106	$.fn.vcChat = function(option, value) {
27107		return this.each(function () {
27108			var $this = $(this),
27109				data = $this.data('vc_chart'),
27110				options = typeof option === 'object' ? option : {
27111					color: $this.data('pie-color'),
27112					units: $this.data('pie-units')
27113				};
27114			if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options)));
27115			if (typeof option == 'string') data[option](value);
27116		});
27117	};
27118	/**
27119	 * Allows users to rewrite function inside theme.
27120	 */
27121	if ( typeof window['vc_pieChart'] !== 'function' ) {
27122		window.vc_pieChart = function() {
27123			$('.vc_pie_chart:visible:not(.vc_ready)').vcChat();
27124		}
27125	}
27126	$(document).ready(function(){
27127		!window.vc_iframe && vc_pieChart();
27128
27129		/**
27130		* Tab and collapse integration.
27131		*/
27132		$('.nav-tabs a').on('shown.bs.tab', function(e){
27133			var $cont = $(e.target).closest('.tab-container'),
27134				$active = $('.tab-pane.active', $cont);
27135			$('.vc_pie_chart:not(.vc_ready)', $active).vcChat();
27136		});
27137
27138		$('.panel-collapse').on('shown.bs.collapse', function (e) {
27139			$('.vc_pie_chart:not(.vc_ready)', e.target).vcChat();
27140		})
27141	});
27142
27143})(window.jQuery);
27144
27145/* Progress bar
27146 ---------------------------------------------------------- */
27147function uncode_progress_bar() {
27148	jQuery.each(jQuery('.vc_progress_bar'), function(index, val) {
27149		if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) {
27150			return;
27151		}
27152		if (!UNCODE.isMobile) {
27153			new Waypoint({
27154				context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window,
27155				element: val,
27156				handler: function() {
27157					var element = jQuery(this.element);
27158					element.find('.vc_single_bar').each(function(index) {
27159						var $this = jQuery(this),
27160							bar = $this.find('.vc_bar'),
27161							val = bar.data('percentage-value');
27162						setTimeout(function() {
27163							bar.css({
27164								"width": val + '%'
27165							});
27166						}, index * 200);
27167					});
27168				},
27169				offset: '80%'
27170			});
27171		} else {
27172			var element = jQuery(val);
27173			element.find('.vc_single_bar').each(function(index) {
27174				var $this = jQuery(this),
27175					bar = $this.find('.vc_bar'),
27176					val = bar.data('percentage-value');
27177				setTimeout(function() {
27178					bar.css({
27179						"width": val + '%'
27180					});
27181				}, index * 200);
27182			});
27183		}
27184	});
27185};
27186uncode_progress_bar();
27187
27188/*!
27189 * jquery.counterup.js 1.0
27190 *
27191 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal
27192 * Released under the GPL v2 License
27193 *
27194 * Date: Nov 26, 2013
27195 */
27196(function($) {
27197	"use strict";
27198	$.fn.counterUp = function(options) {
27199		// Defaults
27200		var settings = $.extend({
27201			'time': 400,
27202			'delay': 10
27203		}, options);
27204		return this.each(function() {
27205			// Store the object
27206			var $this = $(this);
27207			var $settings = settings;
27208			var counterUpper = function() {
27209				var nums = [];
27210				var divisions = $settings.time / $settings.delay;
27211				var numReal = $this.attr('data-val'),
27212				num = numReal;
27213				var isComma = /[0-9]+,[0-9]+/.test(num);
27214				num = num.replace(/,/g, '');
27215				var isInt = /^[0-9]+$/.test(num);
27216				var isFloat = /^[0-9]+\.[0-9]+$/.test(num);
27217				var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;
27218				// Generate list of incremental numbers to display
27219				for (var i = divisions; i >= 1; i--) {
27220					// Preserve as int if input was int
27221					var newNum = parseInt(num / divisions * i);
27222					// Preserve float if input was float
27223					if (isFloat) {
27224						newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces);
27225					}
27226					// Preserve commas if input had commas
27227					if (isComma) {
27228						while (/(\d+)(\d{3})/.test(newNum.toString())) {
27229							newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
27230						}
27231					}
27232					nums.unshift(newNum);
27233				}
27234				nums.push(numReal);
27235				$this.data('counterup-nums', nums);
27236				$this.text('0');
27237				// Updates the number until we're done
27238				var f = function() {
27239					if ($this.data('counterup-nums') != null) {
27240						$this.text($this.data('counterup-nums').shift());
27241						if ($this.data('counterup-nums').length) {
27242							setTimeout($this.data('counterup-func'), $settings.delay);
27243						} else {
27244							delete $this.data('counterup-nums');
27245							$this.data('counterup-nums', null);
27246							$this.data('counterup-func', null);
27247						}
27248					}
27249				};
27250				$this.data('counterup-func', f);
27251				// Start the count up
27252				setTimeout($this.data('counterup-func'), $settings.delay);
27253			};
27254			// Perform counts when the element gets into view
27255			new Waypoint({
27256				context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window,
27257				element: this,
27258				handler: function() {
27259					counterUpper();
27260					if (!UNCODE.isUnmodalOpen) {
27261						this.destroy();
27262					}
27263				},
27264				offset: '100%'
27265			});
27266		});
27267	};
27268})(jQuery);
27269
27270/*!
27271 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/)
27272 * Copyright (c) 2016 Edson Hilios
27273 *
27274 * Permission is hereby granted, free of charge, to any person obtaining a copy of
27275 * this software and associated documentation files (the "Software"), to deal in
27276 * the Software without restriction, including without limitation the rights to
27277 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
27278 * the Software, and to permit persons to whom the Software is furnished to do so,
27279 * subject to the following conditions:
27280 *
27281 * The above copyright notice and this permission notice shall be included in all
27282 * copies or substantial portions of the Software.
27283 *
27284 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27285 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
27286 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
27287 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
27288 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27289 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27290 */
27291(function(factory) {
27292	"use strict";
27293	if (typeof define === "function" && define.amd) {
27294		define([ "jquery" ], factory);
27295	} else {
27296		factory(jQuery);
27297	}
27298})(function($) {
27299	"use strict";
27300	var instances = [], matchers = [], defaultOptions = {
27301		precision: 100,
27302		elapse: false,
27303		defer: false
27304	};
27305	matchers.push(/^[0-9]*$/.source);
27306	matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
27307	matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
27308	matchers = new RegExp(matchers.join("|"));
27309	function parseDateString(dateString) {
27310		if (dateString instanceof Date) {
27311			return dateString;
27312		}
27313		if (String(dateString).match(matchers)) {
27314			if (String(dateString).match(/^[0-9]*$/)) {
27315				dateString = Number(dateString);
27316			}
27317			if (String(dateString).match(/\-/)) {
27318				dateString = String(dateString).replace(/\-/g, "/");
27319			}
27320			return new Date(dateString);
27321		} else {
27322			throw new Error("Couldn't cast `" + dateString + "` to a date object.");
27323		}
27324	}
27325	var DIRECTIVE_KEY_MAP = {
27326		Y: "years",
27327		m: "months",
27328		n: "daysToMonth",
27329		d: "daysToWeek",
27330		w: "weeks",
27331		W: "weeksToMonth",
27332		H: "hours",
27333		M: "minutes",
27334		S: "seconds",
27335		D: "totalDays",
27336		I: "totalHours",
27337		N: "totalMinutes",
27338		T: "totalSeconds"
27339	};
27340	function escapedRegExp(str) {
27341		var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
27342		return new RegExp(sanitize);
27343	}
27344	function strftime(offsetObject) {
27345		return function(format) {
27346			var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);
27347			if (directives) {
27348				for (var i = 0, len = directives.length; i < len; ++i) {
27349					var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null;
27350					directive = directive[2];
27351					if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) {
27352						value = DIRECTIVE_KEY_MAP[directive];
27353						value = Number(offsetObject[value]);
27354					}
27355					if (value !== null) {
27356						if (modifier === "!") {
27357							value = pluralize(plural, value);
27358						}
27359						if (modifier === "") {
27360							if (value < 10) {
27361								value = "0" + value.toString();
27362							}
27363						}
27364						format = format.replace(regexp, value.toString());
27365					}
27366				}
27367			}
27368			format = format.replace(/%%/, "%");
27369			return format;
27370		};
27371	}
27372	function pluralize(format, count) {
27373		var plural = "s", singular = "";
27374		if (format) {
27375			format = format.rep
vendor: 8,618 bytes, lines 27375-27519
27375lace(/(:|;|\s)/gi, "").split(/\,/);
27376			if (format.length === 1) {
27377				plural = format[0];
27378			} else {
27379				singular = format[0];
27380				plural = format[1];
27381			}
27382		}
27383		if (Math.abs(count) > 1) {
27384			return plural;
27385		} else {
27386			return singular;
27387		}
27388	}
27389	var Countdown = function(el, finalDate, options) {
27390		this.el = el;
27391		this.$el = $(el);
27392		this.interval = null;
27393		this.offset = {};
27394		this.options = $.extend({}, defaultOptions);
27395		this.instanceNumber = instances.length;
27396		instances.push(this);
27397		this.$el.data("countdown-instance", this.instanceNumber);
27398		if (options) {
27399			if (typeof options === "function") {
27400				this.$el.on("update.countdown", options);
27401				this.$el.on("stoped.countdown", options);
27402				this.$el.on("finish.countdown", options);
27403			} else {
27404				this.options = $.extend({}, defaultOptions, options);
27405			}
27406		}
27407		this.setFinalDate(finalDate);
27408		if (this.options.defer === false) {
27409			this.start();
27410		}
27411	};
27412	$.extend(Countdown.prototype, {
27413		start: function() {
27414			if (this.interval !== null) {
27415				clearInterval(this.interval);
27416			}
27417			var self = this;
27418			this.update();
27419			this.interval = setInterval(function() {
27420				self.update.call(self);
27421			}, this.options.precision);
27422		},
27423		stop: function() {
27424			clearInterval(this.interval);
27425			this.interval = null;
27426			this.dispatchEvent("stoped");
27427		},
27428		toggle: function() {
27429			if (this.interval) {
27430				this.stop();
27431			} else {
27432				this.start();
27433			}
27434		},
27435		pause: function() {
27436			this.stop();
27437		},
27438		resume: function() {
27439			this.start();
27440		},
27441		remove: function() {
27442			this.stop.call(this);
27443			instances[this.instanceNumber] = null;
27444			delete this.$el.data().countdownInstance;
27445		},
27446		setFinalDate: function(value) {
27447			this.finalDate = parseDateString(value);
27448		},
27449		update: function() {
27450			if (this.$el.closest("html").length === 0) {
27451				this.remove();
27452				return;
27453			}
27454			var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft;
27455			newTotalSecsLeft = this.finalDate.getTime() - now.getTime();
27456			newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3);
27457			newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft);
27458			if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) {
27459				return;
27460			} else {
27461				this.totalSecsLeft = newTotalSecsLeft;
27462			}
27463			this.elapsed = now >= this.finalDate;
27464			this.offset = {
27465				seconds: this.totalSecsLeft % 60,
27466				minutes: Math.floor(this.totalSecsLeft / 60) % 60,
27467				hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24,
27468				days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7,
27469				daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7,
27470				daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368),
27471				weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7),
27472				weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4,
27473				months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368),
27474				years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()),
27475				totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24),
27476				totalHours: Math.floor(this.totalSecsLeft / 60 / 60),
27477				totalMinutes: Math.floor(this.totalSecsLeft / 60),
27478				totalSeconds: this.totalSecsLeft
27479			};
27480			if (!this.options.elapse && this.totalSecsLeft === 0) {
27481				this.stop();
27482				this.dispatchEvent("finish");
27483			} else {
27484				this.dispatchEvent("update");
27485			}
27486		},
27487		dispatchEvent: function(eventName) {
27488			var event = $.Event(eventName + ".countdown");
27489			event.finalDate = this.finalDate;
27490			event.elapsed = this.elapsed;
27491			event.offset = $.extend({}, this.offset);
27492			event.strftime = strftime(this.offset);
27493			this.$el.trigger(event);
27494		}
27495	});
27496	$.fn.countdown = function() {
27497		var argumentsArray = Array.prototype.slice.call(arguments, 0);
27498		return this.each(function() {
27499			var instanceNumber = $(this).data("countdown-instance");
27500			if (instanceNumber !== undefined) {
27501				var instance = instances[instanceNumber], method = argumentsArray[0];
27502				if (Countdown.prototype.hasOwnProperty(method)) {
27503					instance[method].apply(instance, argumentsArray.slice(1));
27504				} else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) {
27505					instance.setFinalDate.call(instance, method);
27506					instance.start();
27507				} else {
27508					$.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method));
27509				}
27510			} else {
27511				new Countdown(this, argumentsArray[0], argumentsArray[1]);
27512			}
27513		});
27514	};
27515});
27516
27517!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;
27518function getStyles(config){
27519  // 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;
27519left: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+"}"
27520};
27521  var ShareUtils;
27522
27523if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") {
27524  Object.defineProperty(HTMLElement.prototype, "classList", {
27525    get: function() {
27526      var ret, self, update;
27527      update = function(fn) {
27528        return function(value) {
27529          var classes, index;
27530          classes = self.className.split(/\s+/);
27531          index = classes.indexOf(value);
27532          fn(classes, index, value);
27533          self.className = classes.join(" ");
27534        };
27535      };
27536      self = this;
27537      ret = {
27538        add: update(function(classes, index, value) {
27539          ~index || classes.push(value);
27540        }),
27541        remove: update(function(classes, index) {
27542          ~index && classes.splice(index, 1);
27543        }),
27544        toggle: update(function(classes, index, value) {
27545          if (~index) {
27546            classes.splice(index, 1);
27547          } else {
27548            classes.push(value);
27549          }
27550        }),
27551        contains: function(value) {
27552          return !!~self.className.split(/\s+/).indexOf(value);
27553        },
27554        item: function(i) {
27555          return self.className.split(/\s+/)[i] || null;
27556        }
27557      };
27558      Object.defineProperty(ret, "length", {
27559        get: function() {
27560          return self.className.split(/\s+/).length;
27561        }
27562      });
27563      return ret;
27564    }
27565  });
27566}
27567
27568String.prototype.to_rfc3986 = function() {
27569  var tmp;
27570  tmp = encodeURIComponent(this);
27571  return tmp.replace(/[!'()*]/g, function(c) {
27572    return "%" + c.charCodeAt(0).toString(16);
27573  });
27574};
27575
27576ShareUtils = (function() {
27577  function ShareUtils() {}
27578
27579  ShareUtils.prototype.extend = function(to, from, overwrite) {
27580    var hasProp, prop;
27581    for (prop in from) {
27582      hasProp = to[prop] !== undefined;
27583      if (hasProp && typeof from[prop] === "object") {
27584        this.extend(to[prop], from[prop], overwrite);
27585      } else {
27586        if (overwrite || !hasProp) {
27587          to[prop] = from[prop];
27588        }
27589      }
27590    }
27591  };
27592
27593  ShareUtils.prototype.hide = function(el) {
27594    return el.style.display = "none";
27595  };
27596
27597  ShareUtils.prototype.show = function(el) {
27598    return el.style.display = "block";
27599  };
27600
27601  ShareUtils.prototype.has_class = function(el, class_name) {
27602    return el.classList.contains(class_name);
27603  };
27604
27605  ShareUtils.prototype.add_class = function(el, class_name) {
27606    return el.classList.add(class_name);
27607  };
27608
27609  ShareUtils.prototype.remove_class = function(el, class_name) {
27610    return el.classList.remove(class_name);
27611  };
27612
27613  ShareUtils.prototype.is_encoded = function(str) {
27614    str = str.to_rfc3986();
27615    return decodeURIComponent(str) !== str;
27616  };
27617
27618  ShareUtils.prototype.encode = function(str) {
27619    if (typeof str === "undefined" || this.is_encoded(str)) {
27620      return str;
27621    } else {
27622      return str.to_rfc3986();
27623    }
27624  };
27625
27626  ShareUtils.prototype.popup = function(url, params) {
27627    var k, popup, qs, v;
27628    if (params == null) {
27629      params = {};
27630    }
27631    popup = {
27632      width: 500,
27633      height: 350
27634    };
27635    popup.top = (screen.height / 2) - (popup.height / 2);
27636    popup.left = (screen.width / 2) - (popup.width / 2);
27637    qs = ((function() {
27638      var _results;
27639      _results = [];
27640      for (k in params) {
27641        v = params[k];
27642        _results.push("" + k + "=" + (this.encode(v)));
27643      }
27644      return _results;
27645    }).call(this)).join('&');
27646    if (qs) {
27647      qs = "?" + qs;
27648    }
27649    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=" 
27649+ popup.width + ",height=" + popup.height);
27650  };
27651
27652  return ShareUtils;
27653
27654})();
27655var Share,
27656  __hasProp = {}.hasOwnProperty,
27657  __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; };
27658
27659Share = (function(_super) {
27660  __extends(Share, _super);
27661
27662  function Share(element, options) {
27663    this.element = element;
27664    this.el = {
27665      head: document.getElementsByTagName('head')[0],
27666      body: document.getElementsByTagName('body')[0]
27667    };
27668    this.config = {
27669      enabled_networks: 0,
27670      protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//',
27671      url: window.location.href.replace("&", "%26"),
27672      caption: null,
27673      title: this.default_title(),
27674      image: this.default_image(),
27675      description: this.default_description(),
27676      ui: {
27677        flyout: 'top center',
27678        button_text: 'Share',
27679        button_font: true,
27680        icon_font: true
27681      },
27682      networks: {
27683        twitter: {
27684          enabled: true,
27685          url: null,
27686          title: null,
27687          description: null
27688        },
27689        facebook: {
27690          enabled: true,
27691          load_sdk: true,
27692          url: null,
27693          app_id: null,
27694          title: null,
27695          caption: null,
27696          description: null,
27697          image: null
27698        },
27699        threads: {
27700          enabled: true,
27701          url: null,
27702          title: null,
27703          description: null
27704        },
27705        bluesky: {
27706          enabled: true,
27707          url: null,
27708          title: null,
27709          description: null
27710        },
27711        pinterest: {
27712          enabled: true,
27713          url: null,
27714          image: null,
27715          description: null
27716        },
27717        reddit: {
27718          enabled: true,
27719          url: null,
27720          title: null
27721        },
27722        linkedin: {
27723          enabled: true,
27724          url: null,
27725          title: null,
27726          description: null
27727        },
27728        xing: {
27729          enabled: true,
27730          url: null,
27731          title: null,
27732          image: null,
27733          description: null
27734        },
27735        whatsapp: {
27736          enabled: true,
27737          title: null,
27738          url: null
27739        },
27740        email: {
27741          enabled: true,
27742          title: null,
27743          description: null,
27744          url: null
27745        }
27746      }
27747    };
27748    this.setup(element, options);
27749    return this;
27750  }
27751
27752  Share.prototype.setup = function(element, opts) {
27753    var index, instance, instances, _i, _len;
27754    instances = document.querySelectorAll(element);
27755    this.extend(this.config, opts, true);
27756    this.set_global_configuration();
27757    this.normalize_network_configuration();
27758    if (this.config.ui.icon_font) {
27759      this.inject_icons();
27760    }
27761    if (this.config.ui.button_font) {
27762      this.inject_fonts();
27763    }
27764    if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) {
27765      this.inject_facebook_sdk();
27766    }
27767    for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) {
27768      instance = instances[index];
27769      this.setup_instance(element, index);
27770    }
27771  };
27772
27773  Share.prototype.setup_instance = function(element, index) {
27774    var button, instance, label, network, networks, _i, _len, _results,
27775      _this = this;
27776    instance = document.querySelectorAll(element)[index];
27777    this.hide(instance);
27778    this.add_class(instance, "sharer-" + index);
27779    instance = document.querySelectorAll(element)[index];
27780    this.inject_css(instance);
27781    this.inject_html(instance);
27782    this.show(instance);
27783    label = instance.getElementsByTagName("label")[0];
27784    button = instance.getElementsByClassName("social")[0];
27785    networks = instance.getElementsByTagName('li');
27786    this.add_class(button, "networks-" + this.config.enabled_networks);
27787    label.addEventListener("click", function() {
27788      return _this.event_toggle(button);
27789    });
27790    _this = this;
27791    _results = [];
27792    for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) {
27793      network = networks[index];
27794      _results.push(network.addEventListener("click", function() {
27795        _this.event_network(instance, this);
27796        return _this.event_close(button);
27797      }));
27798    }
27799    return _results;
27800  };
27801
27802  Share.prototype.event_toggle = function(button) {
27803    if (this.has_class(button, "active")) {
27804      return this.event_close(button);
27805    } else {
27806      return this.event_open(button);
27807    }
27808  };
27809
27810  Share.prototype.event_open = function(button) {
27811    if (this.has_class(button, "load")) {
27812      this.remove_class(button, "load");
27813    }
27814    return this.add_class(button, "active");
27815  };
27816
27817  Share.prototype.event_close = function(button) {
27818    return this.remove_class(button, "active");
27819  };
27820
27821  Share.prototype.event_network = function(instance, network) {
27822    var name;
27823    name = network.getAttribute("data-network");
27824    this.hook("before", name, instance);
27825    this["network_" + name]();
27826    return this.hook("after", name, instance);
27827  };
27828
27829  Share.prototype.open = function() {
27830    return this["public"]("open");
27831  };
27832
27833  Share.prototype.close = function() {
27834    return this["public"]("close");
27835  };
27836
27837  Share.prototype.toggle = function() {
27838    return this["public"]("toggle");
27839  };
27840
27841  Share.prototype["public"] = function(action) {
27842    var button, index, instance, _i, _len, _ref, _results;
27843    _ref = document.querySelectorAll(this.element);
27844    _results = [];
27845    for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
27846      instance = _ref[index];
27847      button = instance.getElementsByClassName("social")[0];
27848      _results.push(this["event_" + action](button));
27849    }
27850    return _results;
27851  };
27852
27853  Share.prototype.network_facebook = function() {
27854    if (this.config.networks.facebook.load_sdk) {
27855      if (!window.FB) {
27856        return console.error("The Facebook JS SDK hasn't loaded yet.");
27857      }
27858      return FB.ui({
27859        method: 'feed',
27860        name: this.config.networks.facebook.title,
27861        link: this.config.networks.facebook.url,
27862        picture: this.config.networks.facebook.image,
27863        caption: this.config.networks.facebook.caption,
27864        description: this.config.networks.facebook.description
27865      });
27866    } else {
27867      return this.popup('https://www.facebook.com/sharer/sharer.php', {
27868        u: this.config.networks.facebook.url
27869      });
27870    }
27871  };
27872
27873  Share.prototype.network_threads = function() {
27874    return this.popup('https://threads.net/intent/post', {
27875      text: this.config.networks.threads.title,
27876      url: this.config.networks.threads.url
27877    });
27878  };
27879
27880  Share.prototype.network_bluesky = function() {
27881    return this.popup('https://bsky.app/intent/compose', {
27882      text: this.config.networks.bluesky.title + ' ' + this.config.networks.bluesky.url
27883    });
27884  };
27885
27886  Share.prototype.network_twitter = function() {
27887    return this.popup('https://twitter.com/intent/tweet', {
27888      text: this.config.networks.twitter.title,
27889      url: this.config.networks.twitter.url
27890    });
27891  };
27892
27893  Share.prototype.network_pinterest = function() {
27894    return this.popup('https://www.pinterest.com/pin/create/button', {
27895      url: this.config.networks.pinterest.url,
27896      media: this.config.networks.pinterest.image,
27897      description: this.config.networks.pinterest.description
27898    });
27899  };
27900
27901  Share.prototype.network_linkedin = function() {
27902    return this.popup('https://www.linkedin.com/shareArticle', {
27903      url: this.config.networks.linkedin.url,
27904      title: this.config.networks.linkedin.title,
27905      summary: this.config.networks.linkedin.description
27906    });
27907  }
27908
27909  Share.prototype.network_xing = function() {
27910    return this.popup('https://www.xing.com/spi/shares/new', {
27911      url: this.config.networks.xing.url,
27912      image: this.config.networks.xing.image,
27913      title: this.config.networks.xing.title,
27914      summary: this.config.networks.xing.description
27915    });
27916  }
27917
27918  Share.prototype.network_whatsapp = function() {
27919    return this.popup('https://api.whatsapp.com/send', {
27920      text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url,
27921    });
27922  }
27923
27924  Share.prototype.network_email = function() {
27925    return this.popup('mailto:', {
27926      subject: this.config.networks.email.title,
27927      body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description,
27928    });
27929  };
27930
27931  Share.prototype.inject_icons = function() {
27932  //  return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css");
27933  };
27934
27935  Share.prototype.inject_fonts = function() {
27936   // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text);
27937  };
27938
27939  Share.prototype.inject_stylesheet = function(url) {
27940    var link;
27941    if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) {
27942      link = document.createElement("link");
27943      link.setAttribute("rel", "stylesheet");
27944      link.setAttribute("href", url);
27945      return this.el.head.appendChild(link);
27946    }
27947  };
27948
27949  Share.prototype.inject_css = function(instance) {
27950    var css, meta, selector, style;
27951    selector = "." + (instance.getAttribute('class').split(" ").join("."));
27952    if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) {
27953      this.config.selector = selector;
27954      css = getStyles(this.config);
27955      style = document.createElement("style");
27956      style.type = "text/css";
27957      if (style.styleSheet) {
27958        style.styleSheet.cssText = css;
27959      } else {
27960        style.appendChild(document.createTextNode(css));
27961      }
27962      this.el.head.appendChild(style);
27963      delete this.config.selector;
27964      meta = document.createElement("meta");
27965      meta.setAttribute("name", "sharer" + selector);
27966      return this.el.head.appendChild(meta);
27967    }
27968  };
27969
27970  Share.prototype.inject_html = function(instance) {
27971    // 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>";
27972    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-threads' data-network='threads' 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-whatsapp' data-network='whatsapp' tabindex='0'></li><li class='social-bluesky' data-network='bluesky' 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>";
27973  };
27974
27975  Share.prototype.inject_facebook_sdk = function() {
27976    var fb_root, script;
27977    if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) {
27978      script = document.createElement("script");
27979      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')";
27980      fb_root = document.createElement("div");
27981      fb_root.id = "fb-root";
27982      this.el.body.appendChild(fb_root);
27983      return this.el.body.appendChild(script);
27984    }
27985  };
27986
27987  Share.prototype.hook = function(type, network, instance) {
27988    var fn, opts;
27989    fn = this.config.networks[network][type];
27990    if (typeof fn === "function") {
27991      opts = fn.call(this.config.networks[network], instance);
27992      if (opts !== void 0) {
27993        opts = this.normalize_filter_config_updates(opts);
27994        this.extend(this.config.networks[network], opts, true);
27995        this.normalize_network_configuration();
27996      }
27997    }
27998  };
27999
28000  Share.prototype.default_title = function() {
28001    var content;
28002    if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) {
28003      return encodeURIComponent(content.getAttribute('content'));
28004    } else if (content = document.querySelector('title')) {
28005      return encodeURIComponent(content.innerText);
28006    }
28007  };
28008
28009  Share.prototype.default_image = function() {
28010    var content;
28011    if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) {
28012      return content.getAttribute('content');
28013    }
28014  };
28015
28016  Share.prototype.default_description = function() {
28017    var content;
28018    if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) {
28019      return encodeURIComponent(content.getAttribute('content'));
28020    } else {
28021      return '';
28022    }
28023  };
28024
28025  Share.prototype.set_global_configuration = function() {
28026    var display, network, option, options, _ref, _results;
28027    _ref = this.config.networks;
28028    _results = [];
28029    for (network in _ref) {
28030      options = _ref[network];
28031      for (option in options) {
28032        if (this.config.networks[network][option] == null) {
28033          this.config.networks[network][option] = this.config[option];
28034        }
28035      }
28036      if (this.config.networks[network].enabled) {
28037        display = 'block';
28038        this.config.enabled_networks += 1;
28039      } else {
28040        display = 'none';
28041      }
28042      _results.push(this.config.networks[network].display = display);
28043    }
28044    return _results;
28045  };
28046
28047  Share.prototype.normalize_network_configuration = function() {
28048    if (!this.config.networks.facebook.app_id) {
28049      this.config.networks.facebook.load_sdk = false;
28050    }
28051    if (!this.is_encoded(this.config.networks.twitter.description)) {
28052      this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description);
28053    }
28054    if (typeof this.config.networks.facebook.app_id === 'number') {
28055      return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString();
28056    }
28057  };
28058
28059  Share.prototype.normalize_filter_config_updates = function(opts) {
28060    if (this.config.networks.facebook.app_id !== opts.app_id) {
28061      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.");
28062      delete opts.app_id;
28063    }
28064    if (this.config.networks.facebook.load_sdk !== opts.load_sdk) {
28065      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.");
28066      delete opts.app_id;
28067    }
28068    return opts;
28069  };
28070
28071  return Share;
28072
28073})(ShareUtils);
28074 return Share;
28075});
28076
28077// Generated by CoffeeScript 1.9.2
28078
28079// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net
28080
28081(function() {
28082  var $, win;
28083
28084  $ = this.jQuery || window.jQuery;
28085
28086  win = $(window);
28087
28088  $.fn.stick_in_parent = function(opts) {
28089    var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class;
28090    if (opts == null) {
28091      opts = {};
28092    }
28093    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;
28094    if (offset_top == null) {
28095      offset_top = 0;
28096    }
28097    if (parent_selector == null) {
28098      parent_selector = void 0;
28099    }
28100    if (inner_scrolling == null) {
28101      inner_scrolling = true;
28102    }
28103    if (sticky_class == null) {
28104      sticky_class = "is_stuck";
28105    }
28106    doc = $(document);
28107    if (enable_bottoming == null) {
28108      enable_bottoming = true;
28109    }
28110    outer_width = function(el) {
28111      var _el, computed, w;
28112      if (window.getComputedStyle) {
28113        _el = el[0];
28114        computed = window.getComputedStyle(el[0]);
28115        w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right"));
28116        if (computed.getPropertyValue("box-sizing") !== "border-box") {
28117          w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right"));
28118        }
28119        return w;
28120      } else {
28121        return el.outerWidth(true);
28122      }
28123    };
28124    fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) {
28125      var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick;
28126      if (elm.data("sticky_kit")) {
28127        return;
28128      }
28129      elm.data("sticky_kit", true);
28130      last_scroll_height = doc.height();
28131      parent = elm.parent();
28132      if (parent_selector != null) {
28133        parent = parent.closest(parent_selector);
28134      }
28135      if (!parent.length) {
28136        throw "failed to find stick parent";
28137      }
28138      fixed = false;
28139      bottomed = false;
28140      spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />");
28141      if (spacer) {
28142        spacer.css('position', elm.css('position'));
28143      }
28144      recalc = function() {
28145        var border_top, padding_top, restore;
28146        if (detached) {
28147          return;
28148        }
28149        last_scroll_height = doc.height();
28150        border_top = parseInt(parent.css("border-top-width"), 10);
28151        padding_top = parseInt(parent.css("padding-top"), 10);
28152        padding_bottom = parseInt(parent.css("padding-bottom"), 10);
28153        parent_top = parent.offset().top + border_top + padding_top;
28154        parent_height = parent.height();
28155        if (fixed) {
28156          fixed = false;
vendor: 6,068 bytes, lines 28157-28351
28157          bottomed = false;
28158          if (manual_spacer == null) {
28159            elm.insertAfter(spacer);
28160            spacer.detach();
28161          }
28162          elm.css({
28163            position: "",
28164            top: "",
28165            width: "",
28166            bottom: ""
28167          }).removeClass(sticky_class);
28168          restore = true;
28169        }
28170        top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top;
28171        height = elm.outerHeight(true);
28172        el_float = elm.css("float");
28173        if (spacer) {
28174          spacer.css({
28175            width: outer_width(elm),
28176            height: height,
28177            display: elm.css("display"),
28178            "vertical-align": elm.css("vertical-align"),
28179            "float": el_float
28180          });
28181        }
28182        if (restore) {
28183          return tick();
28184        }
28185      };
28186      recalc();
28187      if (height === parent_height) {
28188        return;
28189      }
28190      last_pos = void 0;
28191      offset = offset_top;
28192      recalc_counter = recalc_every;
28193      tick = function() {
28194        var css, delta, recalced, scroll, will_bottom, win_height;
28195        if (detached) {
28196          return;
28197        }
28198        recalced = false;
28199        if (recalc_counter != null) {
28200          recalc_counter -= 1;
28201          if (recalc_counter <= 0) {
28202            recalc_counter = recalc_every;
28203            recalc();
28204            recalced = true;
28205          }
28206        }
28207        if (!recalced && doc.height() !== last_scroll_height) {
28208          recalc();
28209          recalced = true;
28210        }
28211        scroll = win.scrollTop();
28212        if (last_pos != null) {
28213          delta = scroll - last_pos;
28214        }
28215        last_pos = scroll;
28216        if (fixed) {
28217          if (enable_bottoming) {
28218            will_bottom = scroll + height + offset > parent_height + parent_top;
28219            if (bottomed && !will_bottom) {
28220              bottomed = false;
28221              elm.css({
28222                position: "fixed",
28223                bottom: "",
28224                top: offset
28225              }).trigger("sticky_kit:unbottom");
28226            }
28227          }
28228          if (scroll < top) {
28229            fixed = false;
28230            offset = offset_top;
28231            if (manual_spacer == null) {
28232              if (el_float === "left" || el_float === "right") {
28233                elm.insertAfter(spacer);
28234              }
28235              spacer.detach();
28236            }
28237            css = {
28238              position: "",
28239              width: "",
28240              top: ""
28241            };
28242            elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick");
28243          }
28244          if (inner_scrolling) {
28245            win_height = win.height();
28246            if (height + offset_top > win_height) {
28247              if (!bottomed) {
28248                offset -= delta;
28249                offset = Math.max(win_height - height, offset);
28250                offset = Math.min(offset_top, offset);
28251                if (fixed) {
28252                  elm.css({
28253                    top: offset + "px"
28254                  });
28255                }
28256              }
28257            }
28258          }
28259        } else {
28260          if (scroll > top) {
28261            fixed = true;
28262            css = {
28263              position: "fixed",
28264              top: offset
28265            };
28266            css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px";
28267            elm.css(css).addClass(sticky_class);
28268            if (manual_spacer == null) {
28269              elm.after(spacer);
28270              if (el_float === "left" || el_float === "right") {
28271                spacer.append(elm);
28272              }
28273            }
28274            elm.trigger("sticky_kit:stick");
28275          }
28276        }
28277        if (fixed && enable_bottoming) {
28278          if (will_bottom == null) {
28279            will_bottom = scroll + height + offset > parent_height + parent_top;
28280          }
28281          if (!bottomed && will_bottom) {
28282            bottomed = true;
28283            if (parent.css("position") === "static") {
28284              parent.css({
28285                position: "relative"
28286              });
28287            }
28288            return elm.css({
28289              position: "absolute",
28290              bottom: padding_bottom,
28291              top: "auto"
28292            }).trigger("sticky_kit:bottom");
28293          }
28294        }
28295      };
28296      recalc_and_tick = function() {
28297        recalc();
28298        return tick();
28299      };
28300      detach = function() {
28301        detached = true;
28302        win.off("touchmove", tick);
28303        win.off("scroll", tick);
28304        win.off("resize", recalc_and_tick);
28305        $(document.body).off("sticky_kit:recalc", recalc_and_tick);
28306        elm.off("sticky_kit:detach", detach);
28307        elm.removeData("sticky_kit");
28308        elm.css({
28309          position: "",
28310          bottom: "",
28311          top: "",
28312          width: ""
28313        });
28314        parent.position("position", "");
28315        if (fixed) {
28316          if (manual_spacer == null) {
28317            if (el_float === "left" || el_float === "right") {
28318              elm.insertAfter(spacer);
28319            }
28320            spacer.remove();
28321          }
28322          return elm.removeClass(sticky_class);
28323        }
28324      };
28325      win.on("touchmove", tick);
28326      win.on("scroll", tick);
28327      win.on("resize", recalc_and_tick);
28328      $(document.body).on("sticky_kit:recalc", recalc_and_tick);
28329      elm.on("sticky_kit:detach", detach);
28330      return setTimeout(tick, 0);
28331    };
28332    for (i = 0, len = this.length; i < len; i++) {
28333      elm = this[i];
28334      fn($(elm));
28335    }
28336    return this;
28337  };
28338
28339}).call(this);
28340/* ==========================================================================
28341 * bootstrap-tab-history.js
28342 * Author: Michael Narayan <[email protected]>
28343 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/
28344 * ==========================================================================
28345 * Licensed under the Apache License, Version 2.0 (the "License"); you may
28346 * not use this file except in compliance with the License. You may obtain a
28347 * copy of the License at
28348 *
28349 * http://www.apache.org/licenses/LICENSE-2.0
28350 *
28351 * Unless required by applicable law or agreed to in writing, softw
28351are
28352 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
28353 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
28354 * License for the specific language governing permissions and limitations
28355 * under the License.
28356 * ========================================================================== */
28357
28358/* ========================================================================== */
28359/* JSHint directives                                                          */
28360/*                                                                            */
28361/* global BootstrapTabHistory: true                                           */
28362/*                                                                            */
28363/* global document                                                            */
28364/* global jQuery                                                              */
28365/* global history                                                             */
28366/* global window                                                              */
28367/* ========================================================================== */
28368
28369/**
28370 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history)
28371 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set
28372 * the `data-tab-history` attribute to true (or a string denoting a tab grouping).
28373 *
28374 * See the README for additional information.
28375 *
28376 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes.
28377 */
28378
28379BootstrapTabHistory = {
28380  options: {
28381    /**
28382     * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the
28383     * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true.
28384     *
28385     * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`.
28386     *
28387     * @public
28388     * @type {?number}
28389     */
28390    defaultAnchorYOffset: 0,
28391    /**
28392     * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp.
28393     *
28394     * May be overriden on a per-element basis by the attribute `data-tab-history-changer`.
28395     *
28396     * @public
28397     * @type {string}
28398     */
28399    defaultChanger: 'replace',
28400    /**
28401     * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise,
28402     * `null` is passed as the third parameter to these calls.
28403     *
28404     * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`.
28405     *
28406     * @public
28407     * @type {boolean}
28408     */
28409    defaultUpdateURL: false,
28410    /**
28411     * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page
28412     * load.
28413     *
28414     * @public
28415     * @type {boolean}
28416     */
28417    showTabsBasedOnAnchor: true
28418  }
28419};
28420
28421(function () {
28422  'use strict';
28423
28424  jQuery(function () {
28425    if(history && history.pushState && history.replaceState) {
28426      var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory;
28427
28428      if(bootstrapTabHistory) {
28429        showTabsBasedOnState(bootstrapTabHistory);
28430      } else {
28431        showTabsBasedOnAnchor();
28432      }
28433
28434      backfillHistoryState();
28435
28436      jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab);
28437      jQuery(window).on('popstate', onPopState);
28438    } else {
28439      showTabsBasedOnAnchor();
28440    }
28441  });
28442
28443  /**
28444   * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState.
28445   *
28446   * @type {boolean}
28447   */
28448  var showingTabsBasedOnState = false;
28449
28450  /**
28451   * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper
28452   * `history.back` handling when `data-tab-history-update-url` is true.
28453   */
28454  function backfillHistoryState() {
28455    var newState = null;
28456
28457    jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode
28458      var $activeTabElement = jQuery(this);
28459      var selector = getTabSelector($activeTabElement);
28460
28461      if(selector) {
28462        var tabGroup = getTabGroup($activeTabElement);
28463
28464        if(tabGroup) {
28465          newState = createNewHistoryState(newState || history.state, tabGroup, selector);
28466        }
28467      }
28468    });
28469
28470    if(newState) {
28471      history.replaceState(newState, '', null);
28472    }
28473  }
28474
28475  /**
28476   * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to
28477   * said bootstrapTabHistory attribute.
28478   *
28479   * @param {?object} existingState
28480   * @param {!string} tabGroup
28481   * @param {!string} selector
28482   * @returns {!object}
28483   */
28484  function createNewHistoryState(existingState, tabGroup, selector) {
28485    // Clone history.state and ensure it has a bootstrapTabHistory entry.
28486    var newState = jQuery.extend(true, {}, existingState, {
28487      bootstrapTabHistory: {}
28488    });
28489
28490    newState.bootstrapTabHistory[tabGroup] = selector;
28491
28492    return newState;
28493  }
28494
28495  /**
28496   * @param {jQuery} $tab
28497   * @returns {?string}
28498   */
28499  function getTabGroup($tab) {
28500    return parseTruthyAttributeValue($tab.data('tab-history'));
28501  }
28502
28503  /**
28504   * @param {jQuery} $tab
28505   * @returns {?string}
28506   */
28507  function getTabSelector($tab) {
28508    return $tab.data('target') || $tab.attr('href');
28509  }
28510
28511  /**
28512   * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate.
28513   *
28514   * @param {jQuery.Event} shownEvt
28515   */
28516  function onShownTab(shownEvt) {
28517    if(!showingTabsBasedOnState) {
28518      var $activatedTab = jQuery(shownEvt.target);
28519      if ( $activatedTab.hasClass('panel-collapse') )
28520        $activatedTab = $activatedTab.closest('.panel').find('a');
28521      var selector = getTabSelector($activatedTab);
28522
28523      if(selector) {
28524        var tabGroup = getTabGroup($activatedTab);
28525
28526        if(tabGroup) {
28527          var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger;
28528          var newState = createNewHistoryState(history.state, tabGroup, selector);
28529          var updateURL = (function ($activatedTab) {
28530            if(selector[0] === '#') {
28531              var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url'));
28532
28533              if(elementUpdateURLOption === undefined) {
28534                return BootstrapTabHistory.options.defaultUpdateURL;
28535              } else {
28536                return elementUpdateURLOption;
28537              }
28538            } else {
28539              return false;
28540            }
28541          })($activatedTab);
28542
28543          switch(historyChanger) {
28544            case 'push':
28545              history.pushState(newState, '', updateURL ? selector : null);
28546              break;
28547            case 'replace':
28548              history.replaceState(newState, '', updateURL ? selector : null);
28549              break;
28550            default:
28551              throw new Error('Unknown tab-history-changer: ' + historyChanger);
28552          }
28553        }
28554      }
28555    }
28556  }
28557
28558  /**
28559   * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate.
28560   */
28561  function onPopState() {
28562    var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory;
28563
28564    if(bootstrapTabHistory) {
28565      showTabsBasedOnState(bootstrapTabHistory);
28566    }
28567  }
28568
28569  /**
28570   * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned.
28571   *
28572   * Rationale: HAML data attributes which are set to `true` are rendered as a blank string.
28573   *
28574   * @param {*} value
28575   * @returns {*}
28576   */
28577  function parseTruthyAttributeValue(value) {
28578    if(value) {
28579      return value;
28580    } else if(value === '') {
28581      return true;
28582    } else {
28583      return value;
28584    }
28585  }
28586
28587  /**
28588   * Show tabs based upon the anchor component of `window.location`.
28589   */
28590  function showTabsBasedOnAnchor() {
28591    if(BootstrapTabHistory.options.showTabsBasedOnAnchor) {
28592      var anchor = window.location && window.location.hash;
28593
28594      if(anchor) {
28595        var $tabElement = showTabForSelector(anchor);
28596
28597        if($tabElement && window.addEventListener && window.removeEventListener) {
28598          var anchorYOffset = (function ($tabElement) {
28599            var elementSetting = $tabElement.data('tab-history-anchor-y-offset');
28600
28601            if(elementSetting === undefined) {
28602              return BootstrapTabHistory.options.defaultAnchorYOffset;
28603            } else {
28604              return elementSetting;
28605            }
28606          })($tabElement);
28607
28608          // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get
28609          //   here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the
28610          //   `history.state` object should have been used (unless the browser did not support the modern History API).
28611          if(anchorYOffset || anchorYOffset === 0) {
28612            var scrollListener = function resetAnchorScroll () {
28613              window.removeEventListener('scroll', scrollListener);
28614              window.scrollTo(0, anchorYOffset);
28615            };
28616
28617            window.addEventListener('scroll', scrollListener);
28618          }
28619        }
28620      }
28621    }
28622  }
28623
28624  /**
28625   * Show a tab which corresponds to the provided selector.
28626   *
28627   * @param {string} selector - A CSS selector.
28628   * @returns {?jQuery} - The tab which was found to show (even if said tab was already active).
28629   */
28630  function showTabForSelector(selector) {
28631    var $tabElement = (function (selector) {
28632      var $ret = null;
28633
28634      jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () {
28635        var $potentialTab = jQuery(this);
28636
28637        if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) {
28638          $ret = $potentialTab;
28639          return false;
vendor: 43,483 bytes, lines 28640-29856
28640        } else {
28641         return null;
28642        }
28643      });
28644
28645      return $ret;
28646    })(selector);
28647
28648    if($tabElement) {
28649      if ( !$tabElement.parent().hasClass('active') ) {
28650        $tabElement.trigger('click');
28651      }
28652      //$tabElement.tab('show');
28653    }
28654
28655    return $tabElement;
28656  }
28657
28658  /**
28659   * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors.
28660   *
28661   * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant.
28662   */
28663  function showTabsBasedOnState(bootstrapTabHistory) {
28664    showingTabsBasedOnState = true;
28665
28666    try {
28667      for(var k in bootstrapTabHistory) {
28668        if(bootstrapTabHistory.hasOwnProperty(k)) {
28669          showTabForSelector(bootstrapTabHistory[k]);
28670        }
28671      }
28672    } finally {
28673      showingTabsBasedOnState = false;
28674    }
28675  }
28676})();
28677
28678/*!
28679 * justifiedGallery - v3.8.1
28680 * http://miromannino.github.io/Justified-Gallery/
28681 * Copyright (c) 2020 Miro Mannino
28682 * Licensed under the MIT license.
28683 */
28684(function (factory) {
28685  if (typeof define === 'function' && define.amd) {
28686    // AMD. Register as an anonymous module.
28687    define(['jquery'], factory);
28688  } else if (typeof module === 'object' && module.exports) {
28689    // Node/CommonJS
28690    module.exports = function (root, jQuery) {
28691      if (jQuery === undefined) {
28692        // require('jQuery') returns a factory that requires window to
28693        // build a jQuery instance, we normalize how we use modules
28694        // that require this pattern but the window provided is a noop
28695        // if it's defined (how jquery works)
28696        if (typeof window !== 'undefined') {
28697          jQuery = require('jquery');
28698        }
28699        else {
28700          jQuery = require('jquery')(root);
28701        }
28702      }
28703      factory(jQuery);
28704      return jQuery;
28705    };
28706  } else {
28707    // Browser globals
28708    factory(jQuery);
28709  }
28710}(function ($) {
28711
28712  /**
28713   * Justified Gallery controller constructor
28714   *
28715   * @param $gallery the gallery to build
28716   * @param settings the settings (the defaults are in JustifiedGallery.defaults)
28717   * @constructor
28718   */
28719  var JustifiedGallery = function ($gallery, settings) {
28720
28721    this.settings = settings;
28722    this.checkSettings();
28723
28724    this.imgAnalyzerTimeout = null;
28725    this.entries = null;
28726    this.buildingRow = {
28727      entriesBuff: [],
28728      width: 0,
28729      height: 0,
28730      aspectRatio: 0
28731    };
28732    this.lastFetchedEntry = null;
28733    this.lastAnalyzedIndex = -1;
28734    this.yield = {
28735      every: 2, // do a flush every n flushes (must be greater than 1)
28736      flushed: 0 // flushed rows without a yield
28737    };
28738    this.border = settings.border >= 0 ? settings.border : settings.margins;
28739    this.maxRowHeight = this.retrieveMaxRowHeight();
28740    this.suffixRanges = this.retrieveSuffixRanges();
28741    this.offY = this.border;
28742    this.rows = 0;
28743    this.spinner = {
28744      phase: 0,
28745      timeSlot: 150,
28746      $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'),
28747      intervalId: null
28748    };
28749    this.scrollBarOn = false;
28750    this.checkWidthIntervalId = null;
28751    this.galleryWidth = $gallery.width();
28752    this.$gallery = $gallery;
28753
28754  };
28755
28756  /** @returns {String} the best suffix given the width and the height */
28757  JustifiedGallery.prototype.getSuffix = function (width, height) {
28758    var longestSide, i;
28759    longestSide = (width > height) ? width : height;
28760    for (i = 0; i < this.suffixRanges.length; i++) {
28761      if (longestSide <= this.suffixRanges[i]) {
28762        return this.settings.sizeRangeSuffixes[this.suffixRanges[i]];
28763      }
28764    }
28765    return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]];
28766  };
28767
28768  /**
28769   * Remove the suffix from the string
28770   *
28771   * @returns {string} a new string without the suffix
28772   */
28773  JustifiedGallery.prototype.removeSuffix = function (str, suffix) {
28774    return str.substring(0, str.length - suffix.length);
28775  };
28776
28777  /**
28778   * @returns {boolean} a boolean to say if the suffix is contained in the str or not
28779   */
28780  JustifiedGallery.prototype.endsWith = function (str, suffix) {
28781    return str.indexOf(suffix, str.length - suffix.length) !== -1;
28782  };
28783
28784  /**
28785   * Get the used suffix of a particular url
28786   *
28787   * @param str
28788   * @returns {String} return the used suffix
28789   */
28790  JustifiedGallery.prototype.getUsedSuffix = function (str) {
28791    for (var si in this.settings.sizeRangeSuffixes) {
28792      if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) {
28793        if (this.settings.sizeRangeSuffixes[si].length === 0) continue;
28794        if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si];
28795      }
28796    }
28797    return '';
28798  };
28799
28800  /**
28801   * Given an image src, with the width and the height, returns the new image src with the
28802   * best suffix to show the best quality thumbnail.
28803   *
28804   * @returns {String} the suffix to use
28805   */
28806  JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) {
28807    var newImageSrc;
28808
28809    if (this.settings.thumbnailPath) {
28810      newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image);
28811    } else {
28812      var matchRes = imageSrc.match(this.settings.extension);
28813      var ext = (matchRes !== null) ? matchRes[0] : '';
28814      newImageSrc = imageSrc.replace(this.settings.extension, '');
28815      newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc));
28816      newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext;
28817    }
28818
28819    return newImageSrc;
28820  };
28821
28822  /**
28823   * Shows the images that is in the given entry
28824   *
28825   * @param $entry the entry
28826   * @param callback the callback that is called when the show animation is finished
28827   */
28828  JustifiedGallery.prototype.showImg = function ($entry, callback) {
28829    if (this.settings.cssAnimation) {
28830      $entry.addClass('jg-entry-visible');
28831      if (callback) callback();
28832    } else {
28833      $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
28834      $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
28835    }
28836  };
28837
28838  /**
28839   * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the
28840   * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src.
28841   *
28842   * @param $image the image to analyze
28843   * @returns {String} the extracted src
28844   */
28845  JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) {
28846    var imageSrc = $image.data('safe-src');
28847    var imageSrcLoc = 'data-safe-src';
28848    // Begin Uncode edit
28849    if (typeof imageSrc === 'undefined') {
28850    	var imageCurrentSrc = $image[0].currentSrc;
28851    	if (imageCurrentSrc) {
28852    		imageSrc = imageCurrentSrc;
28853    	} else {
28854    		imageSrc = $image.attr('src');
28855    	}
28856		imageSrcLoc = 'src';
28857    }
28858    // End Uncode edit
28859    $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method
28860    $image.data('jg.src', imageSrc); // this will change overtime
28861    $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method
28862    return imageSrc;
28863  };
28864
28865  /** @returns {jQuery} the image in the given entry */
28866  JustifiedGallery.prototype.imgFromEntry = function ($entry) {
28867    var $img = $entry.find(this.settings.imgSelector);
28868    if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode
28869    return $img.length === 0 ? null : $img;
28870  };
28871
28872  /** @returns {jQuery} the caption in the given entry */
28873  JustifiedGallery.prototype.captionFromEntry = function ($entry) {
28874    var $caption = $entry.find('> .jg-caption');
28875    return $caption.length === 0 ? null : $caption;
28876  };
28877
28878  /**
28879   * Display the entry
28880   *
28881   * @param {jQuery} $entry the entry to display
28882   * @param {int} x the x position where the entry must be positioned
28883   * @param y the y position where the entry must be positioned
28884   * @param imgWidth the image width
28885   * @param imgHeight the image height
28886   * @param rowHeight the row height of the row that owns the entry
28887   */
28888  JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) {
28889    $entry.width(imgWidth);
28890    $entry.height(Math.floor(rowHeight));//hacked by Uncode
28891    $entry.css('top', Math.floor(y));//hacked by Uncode
28892    $entry.css('left', x);
28893
28894    var $image = this.imgFromEntry($entry);
28895    if ($image !== null) {
28896      $image.css('width', imgWidth);
28897      $image.css('height', imgHeight);
28898      $image.css('margin-left', - imgWidth / 2);
28899      $image.css('margin-top', - imgHeight / 2);
28900
28901      // Image reloading for an high quality of thumbnails
28902      var imageSrc = $image.data('jg.src');
28903      if (imageSrc) {
28904        imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]);
28905
28906        $image.one('error', function () {
28907           this.resetImgSrc($image); //revert to the original thumbnail
28908        });
28909
28910        var loadNewImage = function () {
28911          // if (imageSrc !== newImageSrc) {
28912            $image.attr('src', imageSrc);
28913          // }
28914        };
28915
28916        if ($entry.data('jg.loaded') === 'skipped' && imageSrc) {
28917          this.onImageEvent(imageSrc, (function() {
28918            this.showImg($entry, loadNewImage); //load the new image after the fadeIn
28919            $entry.data('jg.loaded', true);
28920          }).bind(this));
28921        } else {
28922          this.showImg($entry, loadNewImage); //load the new image after the fadeIn
28923        }
28924
28925      }
28926
28927    } else {
28928      this.showImg($entry);
28929    }
28930
28931    this.displayEntryCaption($entry);
28932  };
28933
28934  /**
28935   * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt'
28936   * or the 'title' attributes.
28937   *
28938   * @param {jQuery} $entry the entry to process
28939   */
28940  JustifiedGallery.prototype.displayEntryCaption = function ($entry) {
28941    var $image = this.imgFromEntry($entry);
28942    if ($image !== null && this.settings.captions) {
28943      var $imgCaption = this.captionFromEntry($entry);
28944
28945      // Create it if it doesn't exists
28946      if ($imgCaption === null) {
28947        var caption = $image.attr('alt');
28948        if (!this.isValidCaption(caption)) caption = $entry.attr('title');
28949        if (this.isValidCaption(caption)) { // Create only we found something
28950          $imgCaption = $('<div class="jg-caption">' + caption + '</div>');
28951          $entry.append($imgCaption);
28952          $entry.data('jg.createdCaption', true);
28953        }
28954      }
28955
28956      // Create events (we check again the $imgCaption because it can be still inexistent)
28957      if ($imgCaption !== null) {
28958        if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity);
28959        this.addCaptionEventsHandlers($entry);
28960      }
28961    } else {
28962      this.removeCaptionEventsHandlers($entry);
28963    }
28964  };
28965
28966  /**
28967   * Validates the caption
28968   *
28969   * @param caption The caption that should be validated
28970   * @return {boolean} Validation result
28971   */
28972  JustifiedGallery.prototype.isValidCaption = function (caption) {
28973    return (typeof caption !== 'undefined' && caption.length > 0);
28974  };
28975
28976  /**
28977   * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry.
28978   * It shows the caption using jQuery (or using CSS if it is configured so)
28979   *
28980   * @param {Event} eventObject the event object
28981   */
28982  JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) {
28983    var $caption = this.captionFromEntry($(eventObject.currentTarget));
28984    if (this.settings.cssAnimation) {
28985      $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden');
28986    } else {
28987      $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
28988        this.settings.captionSettings.visibleOpacity);
28989    }
28990  };
28991
28992  /**
28993   * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry.
28994   * It hides the caption using jQuery (or using CSS if it is configured so)
28995   *
28996   * @param {Event} eventObject the event object
28997   */
28998  JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) {
28999    var $caption = this.captionFromEntry($(eventObject.currentTarget));
29000    if (this.settings.cssAnimation) {
29001      $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden');
29002    } else {
29003      $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
29004        this.settings.captionSettings.nonVisibleOpacity);
29005    }
29006  };
29007
29008  /**
29009   * Add the handlers of the entry for the caption
29010   *
29011   * @param $entry the entry to modify
29012   */
29013  JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) {
29014    var captionMouseEvents = $entry.data('jg.captionMouseEvents');
29015    if (typeof captionMouseEvents === 'undefined') {
29016      captionMouseEvents = {
29017        mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this),
29018        mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this)
29019      };
29020      $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter);
29021      $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave);
29022      $entry.data('jg.captionMouseEvents', captionMouseEvents);
29023    }
29024  };
29025
29026  /**
29027   * Remove the handlers of the entry for the caption
29028   *
29029   * @param $entry the entry to modify
29030   */
29031  JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) {
29032    var captionMouseEvents = $entry.data('jg.captionMouseEvents');
29033    if (typeof captionMouseEvents !== 'undefined') {
29034      $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter);
29035      $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave);
29036      $entry.removeData('jg.captionMouseEvents');
29037    }
29038  };
29039
29040  /**
29041   * Clear the building row data to be used for a new row
29042   */
29043  JustifiedGallery.prototype.clearBuildingRow = function () {
29044    this.buildingRow.entriesBuff = [];
29045    this.buildingRow.aspectRatio = 0;
29046    this.buildingRow.width = 0;
29047  };
29048
29049  /**
29050   * Justify the building row, preparing it to
29051   *
29052   * @param isLastRow
29053   * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row.
29054   * @returns a boolean to know if the row has been justified or not
29055   */
29056  JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) {
29057    var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true;
29058    var minHeight = 0;
29059    var availableWidth = this.galleryWidth - 2 * this.border - (
29060      (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
29061    var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode
29062    var defaultRowHeight = this.settings.rowHeight;
29063    var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold;
29064
29065    //Skip the last row if we can't justify it and the lastRow == 'hide'
29066    if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) {
29067      for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29068        $entry = this.buildingRow.entriesBuff[i];
29069        if (this.settings.cssAnimation)
29070          $entry.removeClass('jg-entry-visible');
29071        else {
29072          $entry.stop().fadeTo(0, 0.1);
29073          $entry.find('> img, > a > img').fadeTo(0, 0);
29074        }
29075      }
29076      return -1;
29077    }
29078
29079    // With lastRow = nojustify, justify if is justificable (the images will not become too big)
29080    if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') {
29081      justify = false;
29082
29083      if (this.rows > 0) {
29084        defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows;
29085        justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold;
29086      }
29087    }
29088
29089    for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29090      $entry = this.buildingRow.entriesBuff[i];
29091      imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
29092
29093      if (justify) {
29094        newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio;
29095        newImgH = rowHeight;
29096      } else {
29097        newImgW = defaultRowHeight * imgAspectRatio;
29098        newImgH = defaultRowHeight;
29099      }
29100
29101      availableWidth -= Math.round(newImgW);
29102      $entry.data('jg.jwidth', Math.round(newImgW));
29103      $entry.data('jg.jheight', Math.ceil(newImgH));
29104      if (i === 0 || minHeight > newImgH) minHeight = newImgH;
29105    }
29106
29107    this.buildingRow.height = minHeight;
29108    return justify;
29109  };
29110
29111  /**
29112   * Flush a row: justify it, modify the gallery height accordingly to the row height
29113   *
29114   * @param isLastRow
29115   * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row.
29116   */
29117  JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) {
29118    var settings = this.settings;
29119    var $entry, buildingRowRes, offX = this.border, i;
29120
29121    buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow);
29122    if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) {
29123      this.clearBuildingRow();
29124      return;
29125    }
29126
29127    if (this.maxRowHeight) {
29128      if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight;
29129    }
29130
29131    //Align last (unjustified) row
29132    if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) {
29133      var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins;
29134
29135      for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29136        $entry = this.buildingRow.entriesBuff[i];
29137        availableWidth -= $entry.data('jg.jwidth');
29138      }
29139
29140      if (settings.lastRow === 'center')
29141        offX += Math.round(availableWidth / 2);
29142      else if (settings.lastRow === 'right')
29143        offX += availableWidth;
29144    }
29145
29146    var lastEntryIdx = this.buildingRow.entriesBuff.length - 1;
29147    for (i = 0; i <= lastEntryIdx; i++) {
29148      $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i];
29149      this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height);
29150      offX += $entry.data('jg.jwidth') + settings.margins;
29151    }
29152
29153    //Gallery Height
29154    this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border;
29155    this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight());
29156
29157    if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) {
29158      //Ready for a new row
29159      this.offY += this.buildingRow.height + settings.margins;
29160      this.rows += 1;
29161      this.clearBuildingRow();
29162      this.settings.triggerEvent.call(this, 'jg.rowflush');
29163    }
29164  };
29165
29166
29167  // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221
29168  var galleryPrevStaticHeight = 0;
29169
29170  JustifiedGallery.prototype.rememberGalleryHeight = function () {
29171    galleryPrevStaticHeight = this.$gallery.height();
29172    this.$gallery.height(galleryPrevStaticHeight);
29173  };
29174
29175  // grow only
29176  JustifiedGallery.prototype.setGalleryTempHeight = function (height) {
29177    galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight);
29178    this.$gallery.height(galleryPrevStaticHeight);
29179  };
29180
29181  JustifiedGallery.prototype.setGalleryFinalHeight = function (height) {
29182    galleryPrevStaticHeight = height;
29183    this.$gallery.height(height);
29184  };
29185
29186  /**
29187   * Checks the width of the gallery container, to know if a new justification is needed
29188   */
29189  JustifiedGallery.prototype.checkWidth = function () {
29190    this.checkWidthIntervalId = setInterval($.proxy(function () {
29191
29192      // if the gallery is not currently visible, abort.
29193      if (!this.$gallery.is(":visible")) return;
29194
29195      var galleryWidth = parseFloat(this.$gallery.width());
29196      if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) {
29197        this.galleryWidth = galleryWidth;
29198        this.rewind();
29199
29200        this.rememberGalleryHeight();
29201
29202        // Restart to analyze
29203        this.startImgAnalyzer(true);
29204      }
29205    }, this), this.settings.refreshTime);
29206  };
29207
29208  /**
29209   * @returns {boolean} a boolean saying if the spinner is active or not
29210   */
29211  JustifiedGallery.prototype.isSpinnerActive = function () {
29212    return this.spinner.intervalId !== null;
29213  };
29214
29215  /**
29216   * @returns {int} the spinner height
29217   */
29218  JustifiedGallery.prototype.getSpinnerHeight = function () {
29219    return this.spinner.$el.innerHeight();
29220  };
29221
29222  /**
29223   * Stops the spinner animation and modify the gallery height to exclude the spinner
29224   */
29225  JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () {
29226    clearInterval(this.spinner.intervalId);
29227    this.spinner.intervalId = null;
29228    this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight());
29229    this.spinner.$el.detach();
29230  };
29231
29232  /**
29233   * Starts the spinner animation
29234   */
29235  JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () {
29236    var spinnerContext = this.spinner;
29237    var $spinnerPoints = spinnerContext.$el.find('span');
29238    clearInterval(spinnerContext.intervalId);
29239    this.$gallery.append(spinnerContext.$el);
29240    this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight());
29241    spinnerContext.intervalId = setInterval(function () {
29242      if (spinnerContext.phase < $spinnerPoints.length) {
29243        $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1);
29244      } else {
29245        $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0);
29246      }
29247      spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2);
29248    }, spinnerContext.timeSlot);
29249  };
29250
29251  /**
29252   * Rewind the image analysis to start from the first entry.
29253   */
29254  JustifiedGallery.prototype.rewind = function () {
29255    this.lastFetchedEntry = null;
29256    this.lastAnalyzedIndex = -1;
29257    this.offY = this.border;
29258    this.rows = 0;
29259    this.clearBuildingRow();
29260  };
29261
29262  /**
29263   * @returns {String} `settings.selector` rejecting spinner element
29264   */
29265  JustifiedGallery.prototype.getSelectorWithoutSpinner = function () {
29266    return this.settings.selector + ', div:not(.jg-spinner)';
29267  };
29268
29269  /**
29270   * @returns {Array} all entries matched by `settings.selector`
29271   */
29272  JustifiedGallery.prototype.getAllEntries = function () {
29273    var selector = this.getSelectorWithoutSpinner();
29274    return this.$gallery.children(selector).toArray();
29275  };
29276
29277  /**
29278   * Update the entries searching it from the justified gallery HTML element
29279   *
29280   * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered)
29281   * @returns {boolean} true if some entries has been founded
29282   */
29283  JustifiedGallery.prototype.updateEntries = function (norewind) {
29284    var newEntries;
29285
29286    if (norewind && this.lastFetchedEntry != null) {
29287      var selector = this.getSelectorWithoutSpinner();
29288      newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray();
29289    } else {
29290      this.entries = [];
29291      newEntries = this.getAllEntries();
29292    }
29293
29294    if (newEntries.length > 0) {
29295
29296      // Sort or randomize
29297      if ($.isFunction(this.settings.sort)) {
29298        newEntries = this.sortArray(newEntries);
29299      } else if (this.settings.randomize) {
29300        newEntries = this.shuffleArray(newEntries);
29301      }
29302      this.lastFetchedEntry = newEntries[newEntries.length - 1];
29303
29304      // Filter
29305      if (this.settings.filter) {
29306        newEntries = this.filterArray(newEntries);
29307      } else {
29308        this.resetFilters(newEntries);
29309      }
29310
29311    }
29312
29313    this.entries = this.entries.concat(newEntries);
29314    return true;
29315  };
29316
29317  /**
29318   * Apply the entries order to the DOM, iterating the entries and appending the images
29319   *
29320   * @param entries the entries that has been modified and that must be re-ordered in the DOM
29321   */
29322  JustifiedGallery.prototype.insertToGallery = function (entries) {
29323    var that = this;
29324    $.each(entries, function () {
29325      $(this).appendTo(that.$gallery);
29326    });
29327  };
29328
29329  /**
29330   * Shuffle the array using the Fisher-Yates shuffle algorithm
29331   *
29332   * @param a the array to shuffle
29333   * @return the shuffled array
29334   */
29335  JustifiedGallery.prototype.shuffleArray = function (a) {
29336    var i, j, temp;
29337    for (i = a.length - 1; i > 0; i--) {
29338      j = Math.floor(Math.random() * (i + 1));
29339      temp = a[i];
29340      a[i] = a[j];
29341      a[j] = temp;
29342    }
29343    this.insertToGallery(a);
29344    return a;
29345  };
29346
29347  /**
29348   * Sort the array using settings.comparator as comparator
29349   *
29350   * @param a the array to sort (it is sorted)
29351   * @return the sorted array
29352   */
29353  JustifiedGallery.prototype.sortArray = function (a) {
29354    a.sort(this.settings.sort);
29355    this.insertToGallery(a);
29356    return a;
29357  };
29358
29359  /**
29360   * Reset the filters removing the 'jg-filtered' class from all the entries
29361   *
29362   * @param a the array to reset
29363   */
29364  JustifiedGallery.prototype.resetFilters = function (a) {
29365    for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered');
29366  };
29367
29368  /**
29369   * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering.
29370   *
29371   * @param a the array to filter
29372   * @return the filtered array
29373   */
29374  JustifiedGallery.prototype.filterArray = function (a) {
29375    var settings = this.settings;
29376    if ($.type(settings.filter) === 'string') {
29377      // Filter only keeping the entries passed in the string
29378      return a.filter(function (el) {
29379        var $el = $(el);
29380        if ($el.is(settings.filter)) {
29381          $el.removeClass('jg-filtered');
29382          return true;
29383        } else {
29384          $el.addClass('jg-filtered').removeClass('jg-visible');
29385          return false;
29386        }
29387      });
29388    } else if ($.isFunction(settings.filter)) {
29389      // Filter using the passed function
29390      var filteredArr = a.filter(settings.filter);
29391      for (var i = 0; i < a.length; i++) {
29392        if (filteredArr.indexOf(a[i]) === -1) {
29393          $(a[i]).addClass('jg-filtered').removeClass('jg-visible');
29394        } else {
29395          $(a[i]).removeClass('jg-filtered');
29396        }
29397      }
29398      return filteredArr;
29399    }
29400  };
29401
29402  /**
29403   * Revert the image src to the default value.
29404   */
29405  JustifiedGallery.prototype.resetImgSrc = function ($img) {
29406    if ($img.data('jg.originalSrcLoc') === 'src') {
29407      $img.attr('src', $img.data('jg.originalSrc'));
29408    } else {
29409      $img.attr('src', '');
29410    }
29411  };
29412
29413  /**
29414   * Destroy the Justified Gallery instance.
29415   *
29416   * It clears all the css properties added in the style attributes. We doesn't backup the original
29417   * values for those css attributes, because it costs (performance) and because in general one
29418   * shouldn't use the style attribute for an uniform set of images (where we suppose the use of
29419   * classes). Creating a backup is also difficult because JG could be called multiple times and
29420   * with different style attributes.
29421   */
29422  JustifiedGallery.prototype.destroy = function () {
29423    clearInterval(this.checkWidthIntervalId);
29424    this.stopImgAnalyzerStarter();
29425
29426    // Get fresh entries list since filtered entries are absent in `this.entries`
29427    $.each(this.getAllEntries(), $.proxy(function (_, entry) {
29428      var $entry = $(entry);
29429
29430      // Reset entry style
29431      $entry.css('width', '');
29432      $entry.css('height', '');
29433      $entry.css('top', '');
29434      $entry.css('left', '');
29435      $entry.data('jg.loaded', undefined);
29436      $entry.removeClass('jg-entry jg-filtered jg-entry-visible');
29437
29438      // Reset image style
29439      var $img = this.imgFromEntry($entry);
29440      if ($img) {
29441        $img.css('width', '');
29442        $img.css('height', '');
29443        $img.css('margin-left', '');
29444        $img.css('margin-top', '');
29445        this.resetImgSrc($img);
29446        $img.data('jg.originalSrc', undefined);
29447        $img.data('jg.originalSrcLoc', undefined);
29448        $img.data('jg.src', undefined);
29449      }
29450
29451      // Remove caption
29452      this.removeCaptionEventsHandlers($entry);
29453      var $caption = this.captionFromEntry($entry);
29454      if ($entry.data('jg.createdCaption')) {
29455        // remove also the caption element (if created by jg)
29456        $entry.data('jg.createdCaption', undefined);
29457        if ($caption !== null) $caption.remove();
29458      } else {
29459        if ($caption !== null) $caption.fadeTo(0, 1);
29460      }
29461
29462    }, this));
29463
29464    this.$gallery.css('height', '');
29465    this.$gallery.removeClass('justified-gallery');
29466    this.$gallery.data('jg.controller', undefined);
29467    this.settings.triggerEvent.call(this, 'jg.destroy');
29468  };
29469
29470  /**
29471   * Analyze the images and builds the rows. It returns if it found an image that is not loaded.
29472   *
29473   * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end
29474   */
29475  JustifiedGallery.prototype.analyzeImages = function (isForResize) {
29476    for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) {
29477      var $entry = $(this.entries[i]);
29478      if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') {
29479        var availableWidth = this.galleryWidth - 2 * this.border - (
29480          (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
29481        var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
29482
29483        this.buildingRow.entriesBuff.push($entry);
29484        this.buildingRow.aspectRatio += imgAspectRatio;
29485        this.buildingRow.width += imgAspectRatio * this.settings.rowHeight;
29486        this.lastAnalyzedIndex = i;
29487
29488        if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) {
29489          this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount);
29490
29491          if (++this.yield.flushed >= this.yield.every) {
29492            this.startImgAnalyzer(isForResize);
29493            return;
29494          }
29495        }
29496      } else if ($entry.data('jg.loaded') !== 'error') {
29497        return;
29498      }
29499    }
29500
29501    // Last row flush (the row is not full)
29502    if (this.buildingRow.entriesBuff.length > 0) {
29503      this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount);
29504    }
29505
29506    if (this.isSpinnerActive()) {
29507      this.stopLoadingSpinnerAnimation();
29508    }
29509
29510    /* Stop, if there is, the timeout to start the analyzeImages.
29511     This is because an image can be set loaded, and the timeout can be set,
29512     but this image can be analyzed yet.
29513     */
29514    this.stopImgAnalyzerStarter();
29515
29516    this.setGalleryFinalHeight(this.galleryHeightToSet);
29517
29518    //On complete callback
29519    this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete');
29520  };
29521
29522  /**
29523   * Stops any ImgAnalyzer starter (that has an assigned timeout)
29524   */
29525  JustifiedGallery.prototype.stopImgAnalyzerStarter = function () {
29526    this.yield.flushed = 0;
29527    if (this.imgAnalyzerTimeout !== null) {
29528      clearTimeout(this.imgAnalyzerTimeout);
29529      this.imgAnalyzerTimeout = null;
29530    }
29531  };
29532
29533  /**
29534   * Starts the image analyzer. It is not immediately called to let the browser to update the view
29535   *
29536   * @param isForResize specifies if the image analyzer must be called for resizing or not
29537   */
29538  JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) {
29539    var that = this;
29540    this.stopImgAnalyzerStarter();
29541    this.imgAnalyzerTimeout = setTimeout(function () {
29542      that.analyzeImages(isForResize);
29543    }, 0.001); // we can't start it immediately due to a IE different behaviour
29544  };
29545
29546  /**
29547   * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property,
29548   * because some browsers, with a 404 set complete = true.
29549   *
29550   * @param imageSrc the image src to load
29551   * @param onLoad callback that is called when the image has been loaded
29552   * @param onError callback that is called in case of an error
29553   */
29554  JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) {
29555    if (!onLoad && !onError) return;
29556
29557    var memImage = new Image();
29558    var $memImage = $(memImage);
29559    if (onLoad) {
29560      $memImage.one('load', function () {
29561        $memImage.off('load error');
29562        onLoad(memImage);
29563      });
29564    }
29565    if (onError) {
29566      $memImage.one('error', function () {
29567        $memImage.off('load error');
29568        onError(memImage);
29569      });
29570    }
29571    memImage.src = imageSrc;
29572  };
29573
29574  /**
29575   * Init of Justified Gallery controlled
29576   * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images)
29577   */
29578  JustifiedGallery.prototype.init = function () {
29579    var imagesToLoad = false, skippedImages = false, that = this;
29580    $.each(this.entries, function (index, entry) {
29581      var $entry = $(entry);
29582      var $image = that.imgFromEntry($entry);
29583
29584      $entry.addClass('jg-entry');
29585
29586      if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') {
29587
29588        // Link Rel global overwrite
29589        if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel);
29590
29591        // Link Target global overwrite
29592        if (that.settings.target !== null) $entry.attr('target', that.settings.target);
29593
29594        if ($image !== null) {
29595
29596          // Image src
29597          var imageSrc = that.extractImgSrcFromImage($image);
29598
29599          /* If we have the height and the width, we don't wait that the image is loaded,
29600             but we start directly with the justification */
29601          if (that.settings.waitThumbnailsLoad === false || !imageSrc) {
29602            var width = parseFloat($image.attr('width'));
29603            var height = parseFloat($image.attr('height'));
29604            if ($image.prop('tagName') === 'svg') {
29605              width = parseFloat($image[0].getBBox().width);
29606              height = parseFloat($image[0].getBBox().height);
29607            }
29608            if (!isNaN(width) && !isNaN(height)) {
29609              $entry.data('jg.width', width);
29610              $entry.data('jg.height', height);
29611              $entry.data('jg.loaded', 'skipped');
29612              skippedImages = true;
29613              that.startImgAnalyzer(false);
29614              return true; // continue
29615            }
29616          }
29617
29618          $entry.data('jg.loaded', false);
29619          imagesToLoad = true;
29620
29621          // Spinner start
29622          if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation();
29623
29624          that.onImageEvent(imageSrc, function (loadImg) { // image loaded
29625            $entry.data('jg.width', loadImg.width);
29626            $entry.data('jg.height', loadImg.height);
29627            $entry.data('jg.loaded', true);
29628            that.startImgAnalyzer(false);
29629          }, function () { // image load error
29630            $entry.data('jg.loaded', 'error');
29631            that.startImgAnalyzer(false);
29632          });
29633
29634        } else {
29635          $entry.data('jg.loaded', true);
29636          $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1);
29637          $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1);
29638        }
29639
29640      }
29641
29642    });
29643
29644    if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false);
29645    this.checkWidth();
29646  };
29647
29648  /**
29649   * Checks that it is a valid number. If a string is passed it is converted to a number
29650   *
29651   * @param settingContainer the object that contains the setting (to allow the conversion)
29652   * @param settingName the setting name
29653   */
29654  JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) {
29655    if ($.type(settingContainer[settingName]) === 'string') {
29656      settingContainer[settingName] = parseFloat(settingContainer[settingName]);
29657    }
29658
29659    if ($.type(settingContainer[settingName]) === 'number') {
29660      if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName;
29661    } else {
29662      throw settingName + ' must be a number';
29663    }
29664  };
29665
29666  /**
29667   * Checks the sizeRangeSuffixes and, if necessary, converts
29668   * its keys from string (e.g. old settings with 'lt100') to int.
29669   */
29670  JustifiedGallery.prototype.checkSizeRangesSuffixes = function () {
29671    if ($.type(this.settings.sizeRangeSuffixes) !== 'object') {
29672      throw 'sizeRangeSuffixes must be defined and must be an object';
29673    }
29674
29675    var suffixRanges = [];
29676    for (var rangeIdx in this.settings.sizeRangeSuffixes) {
29677      if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx);
29678    }
29679
29680    var newSizeRngSuffixes = { 0: '' };
29681    for (var i = 0; i < suffixRanges.length; i++) {
29682      if ($.type(suffixRanges[i]) === 'string') {
29683        try {
29684          var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10);
29685          newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
29686        } catch (e) {
29687          throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')';
29688        }
29689      } else {
29690        newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
29691      }
29692    }
29693
29694    this.settings.sizeRangeSuffixes = newSizeRngSuffixes;
29695  };
29696
29697  /**
29698   * check and convert the maxRowHeight setting
29699   * requires rowHeight to be already set
29700   * TODO: should be always called when only rowHeight is changed
29701   * @return number or null
29702   */
29703  JustifiedGallery.prototype.retrieveMaxRowHeight = function () {
29704    var newMaxRowHeight = null;
29705    var rowHeight = this.settings.rowHeight;
29706
29707    if ($.type(this.settings.maxRowHeight) === 'string') {
29708      if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) {
29709        newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100;
29710      } else {
29711        newMaxRowHeight = parseFloat(this.settings.maxRowHeight);
29712      }
29713    } else if ($.type(this.settings.maxRowHeight) === 'number') {
29714      newMaxRowHeight = this.settings.maxRowHeight;
29715    } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) {
29716      return null;
29717    } else {
29718      throw 'maxRowHeight must be a number or a percentage';
29719    }
29720
29721    // check if the converted value is not a number
29722    if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight';
29723
29724    // check values, maxRowHeight must be >= rowHeight
29725    if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight;
29726
29727    return newMaxRowHeight;
29728  };
29729
29730  /**
29731   * Checks the settings
29732   */
29733  JustifiedGallery.prototype.checkSettings = function () {
29734    this.checkSizeRangesSuffixes();
29735
29736    this.checkOrConvertNumber(this.settings, 'rowHeight');
29737    this.checkOrConvertNumber(this.settings, 'margins');
29738    this.checkOrConvertNumber(this.settings, 'border');
29739    this.checkOrConvertNumber(this.settings, 'maxRowsCount');
29740
29741    var lastRowModes = [
29742      'justify',
29743      'nojustify',
29744      'left',
29745      'center',
29746      'right',
29747      'hide'
29748    ];
29749    if (lastRowModes.indexOf(this.settings.lastRow) === -1) {
29750      throw 'lastRow must be one of: ' + lastRowModes.join(', ');
29751    }
29752
29753    this.checkOrConvertNumber(this.settings, 'justifyThreshold');
29754    if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) {
29755      throw 'justifyThreshold must be in the interval [0,1]';
29756    }
29757    if ($.type(this.settings.cssAnimation) !== 'boolean') {
29758      throw 'cssAnimation must be a boolean';
29759    }
29760
29761    if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean';
29762    this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration');
29763
29764    this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity');
29765    if (this.settings.captionSettings.visibleOpacity < 0 ||
29766      this.settings.captionSettings.visibleOpacity > 1) {
29767      throw 'captionSettings.visibleOpacity must be in the interval [0, 1]';
29768    }
29769
29770    this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity');
29771    if (this.settings.captionSettings.nonVisibleOpacity < 0 ||
29772      this.settings.captionSettings.nonVisibleOpacity > 1) {
29773      throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]';
29774    }
29775
29776    this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration');
29777    this.checkOrConvertNumber(this.settings, 'refreshTime');
29778    this.checkOrConvertNumber(this.settings, 'refreshSensitivity');
29779    if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean';
29780    if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string';
29781
29782    if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) {
29783      throw 'sort must be false or a comparison function';
29784    }
29785
29786    if (this.settings.filter !== false && !$.isFunction(this.settings.filter) &&
29787      $.type(this.settings.filter) !== 'string') {
29788      throw 'filter must be false, a string or a filter function';
29789    }
29790  };
29791
29792  /**
29793   * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned.
29794   * @returns {Array} sorted suffix ranges
29795   */
29796  JustifiedGallery.prototype.retrieveSuffixRanges = function () {
29797    var suffixRanges = [];
29798    for (var rangeIdx in this.settings.sizeRangeSuffixes) {
29799      if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10));
29800    }
29801    suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; });
29802    return suffixRanges;
29803  };
29804
29805  /**
29806   * Update the existing settings only changing some of them
29807   *
29808   * @param newSettings the new settings (or a subgroup of them)
29809   */
29810  JustifiedGallery.prototype.updateSettings = function (newSettings) {
29811    // In this case Justified Gallery has been called again changing only some options
29812    this.settings = $.extend({}, this.settings, newSettings);
29813    this.checkSettings();
29814
29815    // As reported in the settings: negative value = same as margins, 0 = disabled
29816    this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins;
29817
29818    this.maxRowHeight = this.retrieveMaxRowHeight();
29819    this.suffixRanges = this.retrieveSuffixRanges();
29820  };
29821
29822  JustifiedGallery.prototype.defaults = {
29823    sizeRangeSuffixes: {}, /* e.g. Flickr configuration
29824        {
29825          100: '_t',  // used when longest is less than 100px
29826          240: '_m',  // used when longest is between 101px and 240px
29827          320: '_n',  // ...
29828          500: '',
29829          640: '_z',
29830          1024: '_b'  // used as else case because it is the last
29831        }
29832    */
29833    thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the
29834    path relative to a specific thumbnail size. The function should accept respectively three arguments:
29835    current path, width and height */
29836    rowHeight: 120, // required? required to be > 0?
29837    maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels,
29838    // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height
29839    // can't exceed 3 * rowHeight)
29840    maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled)
29841    margins: 1,
29842    border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border
29843
29844    lastRow: 'nojustify', // … which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide'
29845
29846    justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified
29847                             * (i.e. lastRow setting is not considered) */
29848    waitThumbnailsLoad: true,
29849    captions: true,
29850    cssAnimation: true,
29851    imagesAnimationDuration: 500, // ignored with css animations
29852    captionSettings: { // ignored with css animations
29853      animationDuration: 500,
29854      visibleOpacity: 0.7,
29855      nonVisibleOpacity: 0.0
29856    },
29857    rel: null, // rewrite the rel of each analyzed links
29858    target: null, // rewrite the target of all links
29859    extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image
29860    refreshTime: 200, // time interval (in ms) to check if the page changes its width
29861    refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery
29862    randomize: false,
29863    rtl: false, // right-to-left mode
29864    sort: false, /*
29865      - false: to do not sort
29866      - function: to sort them using the function as comparator (see Array.prototype.sort())
29867    */
29868    filter: false, /*
29869      - false, null or undefined: for a disabled filter
29870      - a string: an entry is kept if entry.is(filter string) returns true
29871                  see jQuery's .is() function for further information
29872      - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise.
29873                    It follows the specifications of the Array.prototype.filter() function of JavaScript.
29874    */
29875    selector: 'a', // The selector that is used to know what are the entries of the gallery
29876    imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry
29877    triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger
29878      this.$gallery.trigger(event);  // Consider that 'this' is this set to the JustifiedGallery object, so it can
29879    }                                // access to fields such as $gallery, useful to trigger events with jQuery.
29880  };
29881
29882
29883  /**
29884   * Justified Gallery plugin for jQuery
29885   *
29886   * Events
29887   *  - jg.complete : called when all the gallery has been created
29888   *  - jg.resize : called when the gallery has been resized
29889   *  - jg.rowflush : when a new row appears
29890   *
29891   * @param arg the action (or the settings) passed when the plugin is called
29892   * @returns {*} the object itself
29893   */
29894  $.fn.justifiedGallery = function (arg) {
29895    return this.each(function (index, gallery) {
29896
29897      var $gallery = $(gallery);
29898      $gallery.addClass('justified-gallery');
29899
29900      var controller = $gallery.data('jg.controller');
29901      if (typeof controller === 'undefined') {
29902        // Create controller and assign it to the object data
29903        if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') {
29904          if (arg === 'destroy') return; // Just a call to an unexisting object
29905          throw 'The argument must be an object';
29906        }
29907        controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg));
29908        $gallery.data('jg.controller', controller);
29909      } else if (arg === 'norewind') {
29910        // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row
29911        // ... left to be more readable
29912      } else if (arg === 'destroy') {
29913        controller.destroy();
29914        return;
29915      } else {
29916        // In this case Justified Gallery has been called again changing only some options
29917        controller.updateSettings(arg);
29918        controller.rewind();
29919      }
29920
29921      // Update the entries list
29922      if (!controller.updateEntries(arg === 'norewind')) return;
29923
29924      // Init justified gallery
29925      controller.init();
29926
29927    });
29928  };
29929
29930}));
29931
29932/*!
29933* Customized version of iScroll.js 0.0.1
29934* It fixes bugs affecting its integration with fullpage.js
29935*/
29936/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */
29937(function (window, document, Math) {
29938var rAF = window.requestAnimationFrame  ||
29939    window.webkitRequestAnimationFrame  ||
29940    window.mozRequestAnimationFrame     ||
29941    window.oRequestAnimationFrame       ||
29942    window.msRequestAnimationFrame      ||
29943    function (callback) { window.setTimeout(callback, 1000 / 60); };
29944
29945var utils = (function () {
29946    var me = {};
29947
29948    var _elementStyle = document.createElement('div').style;
29949    var _vendor = (function () {
29950        var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'],
29951            transform,
29952            i = 0,
29953            l = vendors.length;
29954
29955        for ( ; i < l; i++ ) {
29956            transform = vendors[i] + 'ransform';
29957            if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1);
29958        }
29959
29960        return false;
vendor: 5,154 bytes, lines 29961-30113
29961    })();
29962
29963    function _prefixStyle (style) {
29964        if ( _vendor === false ) return false;
29965        if ( _vendor === '' ) return style;
29966        return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
29967    }
29968
29969    me.getTime = Date.now || function getTime () { return new Date().getTime(); };
29970
29971    me.extend = function (target, obj) {
29972        for ( var i in obj ) {
29973            target[i] = obj[i];
29974        }
29975    };
29976
29977    me.addEvent = function (el, type, fn, capture) {
29978        el.addEventListener(type, fn, !!capture);
29979    };
29980
29981    me.removeEvent = function (el, type, fn, capture) {
29982        el.removeEventListener(type, fn, !!capture);
29983    };
29984
29985    me.prefixPointerEvent = function (pointerEvent) {
29986        return window.MSPointerEvent ?
29987            'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8):
29988            pointerEvent;
29989    };
29990
29991    me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
29992        var distance = current - start,
29993            speed = Math.abs(distance) / time,
29994            destination,
29995            duration;
29996
29997        deceleration = deceleration === undefined ? 0.0006 : deceleration;
29998
29999        destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
30000        duration = speed / deceleration;
30001
30002        if ( destination < lowerMargin ) {
30003            destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;
30004            distance = Math.abs(destination - current);
30005            duration = distance / speed;
30006        } else if ( destination > 0 ) {
30007            destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
30008            distance = Math.abs(current) + destination;
30009            duration = distance / speed;
30010        }
30011
30012        return {
30013            destination: Math.round(destination),
30014            duration: duration
30015        };
30016    };
30017
30018    var _transform = _prefixStyle('transform');
30019
30020    me.extend(me, {
30021        hasTransform: _transform !== false,
30022        hasPerspective: _prefixStyle('perspective') in _elementStyle,
30023        hasTouch: 'ontouchstart' in window,
30024        hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
30025        hasTransition: _prefixStyle('transition') in _elementStyle
30026    });
30027
30028    /*
30029    This should find all Android browsers lower than build 535.19 (both stock browser and webview)
30030    - galaxy S2 is ok
30031    - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
30032    - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30033   - galaxy S3 is badAndroid (stock brower, webview)
30034     `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30035   - galaxy S4 is badAndroid (stock brower, webview)
30036     `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30037   - galaxy S5 is OK
30038     `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
30039   - galaxy S6 is OK
30040     `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
30041  */
30042    me.isBadAndroid = (function() {
30043        var appVersion = window.navigator.appVersion;
30044        // Android browser is not a chrome browser.
30045        if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) {
30046            var safariVersion = appVersion.match(/Safari\/(\d+.\d)/);
30047            if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) {
30048                return parseFloat(safariVersion[1]) < 535.19;
30049            } else {
30050                return true;
30051            }
30052        } else {
30053            return false;
30054        }
30055    })();
30056
30057    me.extend(me.style = {}, {
30058        transform: _transform,
30059        transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
30060        transitionDuration: _prefixStyle('transitionDuration'),
30061        transitionDelay: _prefixStyle('transitionDelay'),
30062        transformOrigin: _prefixStyle('transformOrigin')
30063    });
30064
30065    me.hasClass = function (e, c) {
30066        var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
30067        return re.test(e.className);
30068    };
30069
30070    me.addClass = function (e, c) {
30071        if ( me.hasClass(e, c) ) {
30072            return;
30073        }
30074
30075        var newclass = e.className.split(' ');
30076        newclass.push(c);
30077        e.className = newclass.join(' ');
30078    };
30079
30080    me.removeClass = function (e, c) {
30081        if ( !me.hasClass(e, c) ) {
30082            return;
30083        }
30084
30085        var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g');
30086        e.className = e.className.replace(re, ' ');
30087    };
30088
30089    me.offset = function (el) {
30090        var left = -el.offsetLeft,
30091            top = -el.offsetTop;
30092
30093        // jshint -W084
30094        while (el = el.offsetParent) {
30095            left -= el.offsetLeft;
30096            top -= el.offsetTop;
30097        }
30098        // jshint +W084
30099
30100        return {
30101            left: left,
30102            top: top
30103        };
30104    };
30105
30106    me.preventDefaultException = function (el, exceptions) {
30107        for ( var i in exceptions ) {
30108            if ( exceptions[i].test(el[i]) ) {
30109                return true;
30110            }
30111        }
30112
30113        return false;
vendor: 5,660 bytes, lines 30114-30279
30114    };
30115
30116    me.extend(me.eventType = {}, {
30117        touchstart: 1,
30118        touchmove: 1,
30119        touchend: 1,
30120
30121        mousedown: 2,
30122        mousemove: 2,
30123        mouseup: 2,
30124
30125        pointerdown: 3,
30126        pointermove: 3,
30127        pointerup: 3,
30128
30129        MSPointerDown: 3,
30130        MSPointerMove: 3,
30131        MSPointerUp: 3
30132    });
30133
30134    me.extend(me.ease = {}, {
30135        quadratic: {
30136            style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
30137            fn: function (k) {
30138                return k * ( 2 - k );
30139            }
30140        },
30141        circular: {
30142            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)
30143            fn: function (k) {
30144                return Math.sqrt( 1 - ( --k * k ) );
30145            }
30146        },
30147        back: {
30148            style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
30149            fn: function (k) {
30150                var b = 4;
30151                return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
30152            }
30153        },
30154        bounce: {
30155            style: '',
30156            fn: function (k) {
30157                if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
30158                    return 7.5625 * k * k;
30159                } else if ( k < ( 2 / 2.75 ) ) {
30160                    return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
30161                } else if ( k < ( 2.5 / 2.75 ) ) {
30162                    return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
30163                } else {
30164                    return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
30165                }
30166            }
30167        },
30168        elastic: {
30169            style: '',
30170            fn: function (k) {
30171                var f = 0.22,
30172                    e = 0.4;
30173
30174                if ( k === 0 ) { return 0; }
30175                if ( k == 1 ) { return 1; }
30176
30177                return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
30178            }
30179        }
30180    });
30181
30182    me.tap = function (e, eventName) {
30183        var ev = document.createEvent('Event');
30184        ev.initEvent(eventName, true, true);
30185        ev.pageX = e.pageX;
30186        ev.pageY = e.pageY;
30187        e.target.dispatchEvent(ev);
30188    };
30189
30190    me.click = function (e) {
30191        var target = e.target,
30192            ev;
30193
30194        if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
30195            // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
30196            // initMouseEvent is deprecated.
30197            ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event');
30198            ev.initEvent('click', true, true);
30199            ev.view = e.view || window;
30200            ev.detail = 1;
30201            ev.screenX = target.screenX || 0;
30202            ev.screenY = target.screenY || 0;
30203            ev.clientX = target.clientX || 0;
30204            ev.clientY = target.clientY || 0;
30205            ev.ctrlKey = !!e.ctrlKey;
30206            ev.altKey = !!e.altKey;
30207            ev.shiftKey = !!e.shiftKey;
30208            ev.metaKey = !!e.metaKey;
30209            ev.button = 0;
30210            ev.relatedTarget = null;
30211            ev._constructed = true;
30212            target.dispatchEvent(ev);
30213        }
30214    };
30215
30216    return me;
30217})();
30218function IScroll (el, options) {
30219    this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
30220    this.scroller = this.wrapper.children[0];
30221    this.scrollerStyle = this.scroller.style;       // cache style for better performance
30222
30223    this.options = {
30224
30225        resizeScrollbars: true,
30226
30227        mouseWheelSpeed: 20,
30228
30229        snapThreshold: 0.334,
30230
30231// INSERT POINT: OPTIONS
30232        disablePointer : !utils.hasPointer,
30233        disableTouch : utils.hasPointer || !utils.hasTouch,
30234        disableMouse : utils.hasPointer || utils.hasTouch,
30235        startX: 0,
30236        startY: 0,
30237        scrollY: true,
30238        directionLockThreshold: 5,
30239        momentum: true,
30240
30241        bounce: true,
30242        bounceTime: 600,
30243        bounceEasing: '',
30244
30245        preventDefault: true,
30246        preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ },
30247
30248        HWCompositing: true,
30249        useTransition: true,
30250        useTransform: true,
30251        bindToWrapper: typeof window.onmousedown === "undefined"
30252    };
30253
30254    for ( var i in options ) {
30255        this.options[i] = options[i];
30256    }
30257
30258    // Normalize options
30259    this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
30260
30261    this.options.useTransition = utils.hasTransition && this.options.useTransition;
30262    this.options.useTransform = utils.hasTransform && this.options.useTransform;
30263
30264    this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
30265    this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
30266
30267    // If you want eventPassthrough I have to lock one of the axes
30268    this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
30269    this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
30270
30271    // With eventPassthrough we also need lockDirection mechanism
30272    this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
30273    this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
30274
30275    this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing;
30276
30277    this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
30278
30279    if ( this.options.tap === true ) {
vendor: 4,893 bytes, lines 30280-30451
30280        this.options.tap = 'tap';
30281    }
30282
30283    // https://github.com/cubiq/iscroll/issues/1029
30284    if (!this.options.useTransition && !this.options.useTransform) {
30285        if(!(/relative|absolute/i).test(this.scrollerStyle.position)) {
30286            this.scrollerStyle.position = "relative";
30287        }
30288    }
30289
30290    if ( this.options.shrinkScrollbars == 'scale' ) {
30291        this.options.useTransition = false;
30292    }
30293
30294    this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;
30295
30296// INSERT POINT: NORMALIZATION
30297
30298    // Some defaults
30299    this.x = 0;
30300    this.y = 0;
30301    this.directionX = 0;
30302    this.directionY = 0;
30303    this._events = {};
30304
30305// INSERT POINT: DEFAULTS
30306
30307    this._init();
30308    this.refresh();
30309
30310    this.scrollTo(this.options.startX, this.options.startY);
30311    this.enable();
30312}
30313
30314IScroll.prototype = {
30315    version: '5.2.0',
30316
30317    _init: function () {
30318        this._initEvents();
30319
30320        if ( this.options.scrollbars || this.options.indicators ) {
30321            this._initIndicators();
30322        }
30323
30324        if ( this.options.mouseWheel ) {
30325            this._initWheel();
30326        }
30327
30328        if ( this.options.snap ) {
30329            this._initSnap();
30330        }
30331
30332        if ( this.options.keyBindings ) {
30333            this._initKeys();
30334        }
30335
30336// INSERT POINT: _init
30337
30338    },
30339
30340    destroy: function () {
30341        this._initEvents(true);
30342        clearTimeout(this.resizeTimeout);
30343        this.resizeTimeout = null;
30344        this._execEvent('destroy');
30345    },
30346
30347    _transitionEnd: function (e) {
30348        if ( e.target != this.scroller || !this.isInTransition ) {
30349            return;
30350        }
30351
30352        this._transitionTime();
30353        if ( !this.resetPosition(this.options.bounceTime) ) {
30354            this.isInTransition = false;
30355            this._execEvent('scrollEnd');
30356        }
30357    },
30358
30359    _start: function (e) {
30360        // React to left mouse button only
30361        if ( utils.eventType[e.type] != 1 ) {
30362          // for button property
30363          // http://unixpapa.com/js/mouse.html
30364          var button;
30365        if (!e.which) {
30366          /* IE case */
30367          button = (e.button < 2) ? 0 :
30368                   ((e.button == 4) ? 1 : 2);
30369        } else {
30370          /* All others */
30371          button = e.button;
30372        }
30373            if ( button !== 0 ) {
30374                return;
30375            }
30376        }
30377
30378        if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) {
30379            return;
30380        }
30381
30382        if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
30383            e.preventDefault();
30384        }
30385
30386        var point = e.touches ? e.touches[0] : e,
30387            pos;
30388
30389        this.initiated  = utils.eventType[e.type];
30390        this.moved      = false;
30391        this.distX      = 0;
30392        this.distY      = 0;
30393        this.directionX = 0;
30394        this.directionY = 0;
30395        this.directionLocked = 0;
30396
30397        this.startTime = utils.getTime();
30398
30399        if ( this.options.useTransition && this.isInTransition ) {
30400            this._transitionTime();
30401            this.isInTransition = false;
30402            pos = this.getComputedPosition();
30403            this._translate(Math.round(pos.x), Math.round(pos.y));
30404            this._execEvent('scrollEnd');
30405        } else if ( !this.options.useTransition && this.isAnimating ) {
30406            this.isAnimating = false;
30407            this._execEvent('scrollEnd');
30408        }
30409
30410        this.startX    = this.x;
30411        this.startY    = this.y;
30412        this.absStartX = this.x;
30413        this.absStartY = this.y;
30414        this.pointX    = point.pageX;
30415        this.pointY    = point.pageY;
30416
30417        this._execEvent('beforeScrollStart');
30418    },
30419
30420    _move: function (e) {
30421        if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
30422            return;
30423        }
30424
30425        if ( this.options.preventDefault ) {    // increases performance on Android? TODO: check!
30426            e.preventDefault();
30427        }
30428
30429        var point       = e.touches ? e.touches[0] : e,
30430            deltaX      = point.pageX - this.pointX,
30431            deltaY      = point.pageY - this.pointY,
30432            timestamp   = utils.getTime(),
30433            newX, newY,
30434            absDistX, absDistY;
30435
30436        this.pointX     = point.pageX;
30437        this.pointY     = point.pageY;
30438
30439        this.distX      += deltaX;
30440        this.distY      += deltaY;
30441        absDistX        = Math.abs(this.distX);
30442        absDistY        = Math.abs(this.distY);
30443
30444        // We need to move at least 10 pixels for the scrolling to initiate
30445        if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) {
30446            return;
30447        }
30448
30449        // If you are scrolling in one direction lock the other
30450        if ( !this.directionLocked && !this.options.freeScroll ) {
30451            if ( absDistX > absDistY + this.options.directionLockThreshold ) {
vendor: 6,057 bytes, lines 30452-30638
30452                this.directionLocked = 'h';     // lock horizontally
30453            } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) {
30454                this.directionLocked = 'v';     // lock vertically
30455            } else {
30456                this.directionLocked = 'n';     // no lock
30457            }
30458        }
30459
30460        if ( this.directionLocked == 'h' ) {
30461            if ( this.options.eventPassthrough == 'vertical' ) {
30462                e.preventDefault();
30463            } else if ( this.options.eventPassthrough == 'horizontal' ) {
30464                this.initiated = false;
30465                return;
30466            }
30467
30468            deltaY = 0;
30469        } else if ( this.directionLocked == 'v' ) {
30470            if ( this.options.eventPassthrough == 'horizontal' ) {
30471                e.preventDefault();
30472            } else if ( this.options.eventPassthrough == 'vertical' ) {
30473                this.initiated = false;
30474                return;
30475            }
30476
30477            deltaX = 0;
30478        }
30479
30480        deltaX = this.hasHorizontalScroll ? deltaX : 0;
30481        deltaY = this.hasVerticalScroll ? deltaY : 0;
30482
30483        newX = this.x + deltaX;
30484        newY = this.y + deltaY;
30485
30486        // Slow down if outside of the boundaries
30487        if ( newX > 0 || newX < this.maxScrollX ) {
30488            newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
30489        }
30490        if ( newY > 0 || newY < this.maxScrollY ) {
30491            newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
30492        }
30493
30494        this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
30495        this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
30496
30497        if ( !this.moved ) {
30498            this._execEvent('scrollStart');
30499        }
30500
30501        this.moved = true;
30502
30503        this._translate(newX, newY);
30504
30505/* REPLACE START: _move */
30506
30507        if ( timestamp - this.startTime > 300 ) {
30508            this.startTime = timestamp;
30509            this.startX = this.x;
30510            this.startY = this.y;
30511        }
30512
30513/* REPLACE END: _move */
30514
30515    },
30516
30517    _end: function (e) {
30518        if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
30519            return;
30520        }
30521
30522        if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
30523            e.preventDefault();
30524        }
30525
30526        var point = e.changedTouches ? e.changedTouches[0] : e,
30527            momentumX,
30528            momentumY,
30529            duration = utils.getTime() - this.startTime,
30530            newX = Math.round(this.x),
30531            newY = Math.round(this.y),
30532            distanceX = Math.abs(newX - this.startX),
30533            distanceY = Math.abs(newY - this.startY),
30534            time = 0,
30535            easing = '';
30536
30537        this.isInTransition = 0;
30538        this.initiated = 0;
30539        this.endTime = utils.getTime();
30540
30541        // reset if we are outside of the boundaries
30542        if ( this.resetPosition(this.options.bounceTime) ) {
30543            return;
30544        }
30545
30546        this.scrollTo(newX, newY);  // ensures that the last position is rounded
30547
30548        // we scrolled less than 10 pixels
30549        if ( !this.moved ) {
30550            if ( this.options.tap ) {
30551                utils.tap(e, this.options.tap);
30552            }
30553
30554            if ( this.options.click ) {
30555                utils.click(e);
30556            }
30557
30558            this._execEvent('scrollCancel');
30559            return;
30560        }
30561
30562        if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) {
30563            this._execEvent('flick');
30564            return;
30565        }
30566
30567        // start momentum animation if needed
30568        if ( this.options.momentum && duration < 300 ) {
30569            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 };
30570            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 };
30571            newX = momentumX.destination;
30572            newY = momentumY.destination;
30573            time = Math.max(momentumX.duration, momentumY.duration);
30574            this.isInTransition = 1;
30575        }
30576
30577
30578        if ( this.options.snap ) {
30579            var snap = this._nearestSnap(newX, newY);
30580            this.currentPage = snap;
30581            time = this.options.snapSpeed || Math.max(
30582                    Math.max(
30583                        Math.min(Math.abs(newX - snap.x), 1000),
30584                        Math.min(Math.abs(newY - snap.y), 1000)
30585                    ), 300);
30586            newX = snap.x;
30587            newY = snap.y;
30588
30589            this.directionX = 0;
30590            this.directionY = 0;
30591            easing = this.options.bounceEasing;
30592        }
30593
30594// INSERT POINT: _end
30595
30596        if ( newX != this.x || newY != this.y ) {
30597            // change easing function when scroller goes out of the boundaries
30598            if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
30599                easing = utils.ease.quadratic;
30600            }
30601
30602            this.scrollTo(newX, newY, time, easing);
30603            return;
30604        }
30605
30606        this._execEvent('scrollEnd');
30607    },
30608
30609    _resize: function () {
30610        var that = this;
30611
30612        clearTimeout(this.resizeTimeout);
30613
30614        this.resizeTimeout = setTimeout(function () {
30615            that.refresh();
30616        }, this.options.resizePolling);
30617    },
30618
30619    resetPosition: function (time) {
30620        var x = this.x,
30621            y = this.y;
30622
30623        time = time || 0;
30624
30625        if ( !this.hasHorizontalScroll || this.x > 0 ) {
30626            x = 0;
30627        } else if ( this.x < this.maxScrollX ) {
30628            x = this.maxScrollX;
30629        }
30630
30631        if ( !this.hasVerticalScroll || this.y > 0 ) {
30632            y = 0;
30633        } else if ( this.y < this.maxScrollY ) {
30634            y = this.maxScrollY;
30635        }
30636
30637        if ( x == this.x && y == this.y ) {
30638            return false;
vendor: 5,509 bytes, lines 30639-30843
30639        }
30640
30641        this.scrollTo(x, y, time, this.options.bounceEasing);
30642
30643        return true;
30644    },
30645
30646    disable: function () {
30647        this.enabled = false;
30648    },
30649
30650    enable: function () {
30651        this.enabled = true;
30652    },
30653
30654    refresh: function () {
30655        var rf = this.wrapper.offsetHeight;     // Force reflow
30656
30657        this.wrapperWidth   = this.wrapper.clientWidth;
30658        this.wrapperHeight  = this.wrapper.clientHeight;
30659
30660/* REPLACE START: refresh */
30661
30662        this.scrollerWidth  = this.scroller.offsetWidth;
30663        this.scrollerHeight = this.scroller.offsetHeight;
30664
30665        this.maxScrollX     = this.wrapperWidth - this.scrollerWidth;
30666        this.maxScrollY     = this.wrapperHeight - this.scrollerHeight;
30667
30668/* REPLACE END: refresh */
30669
30670        this.hasHorizontalScroll    = this.options.scrollX && this.maxScrollX < 0;
30671        this.hasVerticalScroll      = this.options.scrollY && this.maxScrollY < 0;
30672
30673        if ( !this.hasHorizontalScroll ) {
30674            this.maxScrollX = 0;
30675            this.scrollerWidth = this.wrapperWidth;
30676        }
30677
30678        if ( !this.hasVerticalScroll ) {
30679            this.maxScrollY = 0;
30680            this.scrollerHeight = this.wrapperHeight;
30681        }
30682
30683        this.endTime = 0;
30684        this.directionX = 0;
30685        this.directionY = 0;
30686
30687        this.wrapperOffset = utils.offset(this.wrapper);
30688
30689        this._execEvent('refresh');
30690
30691        this.resetPosition();
30692
30693// INSERT POINT: _refresh
30694
30695    },
30696
30697
30698    on: function (type, fn) {
30699        if ( !this._events[type] ) {
30700            this._events[type] = [];
30701        }
30702
30703        this._events[type].push(fn);
30704    },
30705
30706    off: function (type, fn) {
30707        if ( !this._events[type] ) {
30708            return;
30709        }
30710
30711        var index = this._events[type].indexOf(fn);
30712
30713        if ( index > -1 ) {
30714            this._events[type].splice(index, 1);
30715        }
30716    },
30717
30718    _execEvent: function (type) {
30719        if ( !this._events[type] ) {
30720            return;
30721        }
30722
30723        var i = 0,
30724            l = this._events[type].length;
30725
30726        if ( !l ) {
30727            return;
30728        }
30729
30730        for ( ; i < l; i++ ) {
30731            this._events[type][i].apply(this, [].slice.call(arguments, 1));
30732        }
30733    },
30734
30735    scrollBy: function (x, y, time, easing) {
30736        x = this.x + x;
30737        y = this.y + y;
30738        time = time || 0;
30739
30740        this.scrollTo(x, y, time, easing);
30741    },
30742
30743    scrollTo: function (x, y, time, easing) {
30744        easing = easing || utils.ease.circular;
30745
30746        this.isInTransition = this.options.useTransition && time > 0;
30747        var transitionType = this.options.useTransition && easing.style;
30748        if ( !time || transitionType ) {
30749                if(transitionType) {
30750                    this._transitionTimingFunction(easing.style);
30751                    this._transitionTime(time);
30752                }
30753            this._translate(x, y);
30754        } else {
30755            this._animate(x, y, time, easing.fn);
30756        }
30757    },
30758
30759    scrollToElement: function (el, time, offsetX, offsetY, easing) {
30760        el = el.nodeType ? el : this.scroller.querySelector(el);
30761
30762        if ( !el ) {
30763            return;
30764        }
30765
30766        var pos = utils.offset(el);
30767
30768        pos.left -= this.wrapperOffset.left;
30769        pos.top  -= this.wrapperOffset.top;
30770
30771        // if offsetX/Y are true we center the element to the screen
30772        if ( offsetX === true ) {
30773            offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2);
30774        }
30775        if ( offsetY === true ) {
30776            offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2);
30777        }
30778
30779        pos.left -= offsetX || 0;
30780        pos.top  -= offsetY || 0;
30781
30782        pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
30783        pos.top  = pos.top  > 0 ? 0 : pos.top  < this.maxScrollY ? this.maxScrollY : pos.top;
30784
30785        time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time;
30786
30787        this.scrollTo(pos.left, pos.top, time, easing);
30788    },
30789
30790    _transitionTime: function (time) {
30791        if (!this.options.useTransition) {
30792            return;
30793        }
30794        time = time || 0;
30795        var durationProp = utils.style.transitionDuration;
30796        if(!durationProp) {
30797            return;
30798        }
30799
30800        this.scrollerStyle[durationProp] = time + 'ms';
30801
30802        if ( !time && utils.isBadAndroid ) {
30803            this.scrollerStyle[durationProp] = '0.0001ms';
30804            // remove 0.0001ms
30805            var self = this;
30806            rAF(function() {
30807                if(self.scrollerStyle[durationProp] === '0.0001ms') {
30808                    self.scrollerStyle[durationProp] = '0s';
30809                }
30810            });
30811        }
30812
30813
30814        if ( this.indicators ) {
30815            for ( var i = this.indicators.length; i--; ) {
30816                this.indicators[i].transitionTime(time);
30817            }
30818        }
30819
30820
30821// INSERT POINT: _transitionTime
30822
30823    },
30824
30825    _transitionTimingFunction: function (easing) {
30826        this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
30827
30828
30829        if ( this.indicators ) {
30830            for ( var i = this.indicators.length; i--; ) {
30831                this.indicators[i].transitionTimingFunction(easing);
30832            }
30833        }
30834
30835
30836// INSERT POINT: _transitionTimingFunction
30837
30838    },
30839
30840    _translate: function (x, y) {
30841        //Uncode addition
30842        if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 )
30843            return false;
vendor: 9,939 bytes, lines 30844-31155
30844
30845        if ( this.options.useTransform ) {
30846
30847/* REPLACE START: _translate */
30848
30849            this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ;
30850
30851/* REPLACE END: _translate */
30852
30853        } else {
30854            x = Math.round(x);
30855            y = Math.round(y);
30856            this.scrollerStyle.left = x + 'px';
30857            this.scrollerStyle.top = y + 'px';
30858        }
30859
30860        this.x = x;
30861        this.y = y;
30862
30863
30864        if ( this.indicators ) {
30865            for ( var i = this.indicators.length; i--; ) {
30866                this.indicators[i].updatePosition();
30867            }
30868        }
30869
30870        //Uncode addition
30871        var uncodevent = new CustomEvent('fp-slide-scroll');
30872        window.dispatchEvent(uncodevent);
30873
30874// INSERT POINT: _translate
30875
30876    },
30877
30878    _initEvents: function (remove) {
30879        var eventType = remove ? utils.removeEvent : utils.addEvent,
30880            target = this.options.bindToWrapper ? this.wrapper : window;
30881
30882        eventType(window, 'orientationchange', this);
30883        eventType(window, 'resize', this);
30884
30885        if ( this.options.click ) {
30886            eventType(this.wrapper, 'click', this, true);
30887        }
30888
30889        if ( !this.options.disableMouse ) {
30890            eventType(this.wrapper, 'mousedown', this);
30891            eventType(target, 'mousemove', this);
30892            eventType(target, 'mousecancel', this);
30893            eventType(target, 'mouseup', this);
30894        }
30895
30896        if ( utils.hasPointer && !this.options.disablePointer ) {
30897            eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
30898            eventType(target, utils.prefixPointerEvent('pointermove'), this);
30899            eventType(target, utils.prefixPointerEvent('pointercancel'), this);
30900            eventType(target, utils.prefixPointerEvent('pointerup'), this);
30901        }
30902
30903        if ( utils.hasTouch && !this.options.disableTouch ) {
30904            eventType(this.wrapper, 'touchstart', this);
30905            eventType(target, 'touchmove', this);
30906            eventType(target, 'touchcancel', this);
30907            eventType(target, 'touchend', this);
30908        }
30909
30910        eventType(this.scroller, 'transitionend', this);
30911        eventType(this.scroller, 'webkitTransitionEnd', this);
30912        eventType(this.scroller, 'oTransitionEnd', this);
30913        eventType(this.scroller, 'MSTransitionEnd', this);
30914    },
30915
30916    getComputedPosition: function () {
30917        var matrix = window.getComputedStyle(this.scroller, null),
30918            x, y;
30919
30920        if ( this.options.useTransform ) {
30921            matrix = matrix[utils.style.transform].split(')')[0].split(', ');
30922            x = +(matrix[12] || matrix[4]);
30923            y = +(matrix[13] || matrix[5]);
30924        } else {
30925            x = +matrix.left.replace(/[^-\d.]/g, '');
30926            y = +matrix.top.replace(/[^-\d.]/g, '');
30927        }
30928
30929        return { x: x, y: y };
30930    },
30931    _initIndicators: function () {
30932        var interactive = this.options.interactiveScrollbars,
30933            customStyle = typeof this.options.scrollbars != 'string',
30934            indicators = [],
30935            indicator;
30936
30937        var that = this;
30938
30939        this.indicators = [];
30940
30941        if ( this.options.scrollbars ) {
30942            // Vertical scrollbar
30943            if ( this.options.scrollY ) {
30944                indicator = {
30945                    el: createDefaultScrollbar('v', interactive, this.options.scrollbars),
30946                    interactive: interactive,
30947                    defaultScrollbars: true,
30948                    customStyle: customStyle,
30949                    resize: this.options.resizeScrollbars,
30950                    shrink: this.options.shrinkScrollbars,
30951                    fade: this.options.fadeScrollbars,
30952                    listenX: false
30953                };
30954
30955                this.wrapper.appendChild(indicator.el);
30956                indicators.push(indicator);
30957            }
30958
30959            // Horizontal scrollbar
30960            if ( this.options.scrollX ) {
30961                indicator = {
30962                    el: createDefaultScrollbar('h', interactive, this.options.scrollbars),
30963                    interactive: interactive,
30964                    defaultScrollbars: true,
30965                    customStyle: customStyle,
30966                    resize: this.options.resizeScrollbars,
30967                    shrink: this.options.shrinkScrollbars,
30968                    fade: this.options.fadeScrollbars,
30969                    listenY: false
30970                };
30971
30972                this.wrapper.appendChild(indicator.el);
30973                indicators.push(indicator);
30974            }
30975        }
30976
30977        if ( this.options.indicators ) {
30978            // TODO: check concat compatibility
30979            indicators = indicators.concat(this.options.indicators);
30980        }
30981
30982        for ( var i = indicators.length; i--; ) {
30983            this.indicators.push( new Indicator(this, indicators[i]) );
30984        }
30985
30986        // TODO: check if we can use array.map (wide compatibility and performance issues)
30987        function _indicatorsMap (fn) {
30988            if (that.indicators) {
30989                for ( var i = that.indicators.length; i--; ) {
30990                    fn.call(that.indicators[i]);
30991                }
30992            }
30993        }
30994
30995        if ( this.options.fadeScrollbars ) {
30996            this.on('scrollEnd', function () {
30997                _indicatorsMap(function () {
30998                    this.fade();
30999                });
31000            });
31001
31002            this.on('scrollCancel', function () {
31003                _indicatorsMap(function () {
31004                    this.fade();
31005                });
31006            });
31007
31008            this.on('scrollStart', function () {
31009                _indicatorsMap(function () {
31010                    this.fade(1);
31011                });
31012            });
31013
31014            this.on('beforeScrollStart', function () {
31015                _indicatorsMap(function () {
31016                    this.fade(1, true);
31017                });
31018            });
31019        }
31020
31021
31022        this.on('refresh', function () {
31023            _indicatorsMap(function () {
31024                this.refresh();
31025            });
31026        });
31027
31028        this.on('destroy', function () {
31029            _indicatorsMap(function () {
31030                this.destroy();
31031            });
31032
31033            delete this.indicators;
31034        });
31035    },
31036
31037    _initWheel: function () {
31038        utils.addEvent(this.wrapper, 'wheel', this);
31039        utils.addEvent(this.wrapper, 'mousewheel', this);
31040        utils.addEvent(this.wrapper, 'DOMMouseScroll', this);
31041
31042        this.on('destroy', function () {
31043            clearTimeout(this.wheelTimeout);
31044            this.wheelTimeout = null;
31045            utils.removeEvent(this.wrapper, 'wheel', this);
31046            utils.removeEvent(this.wrapper, 'mousewheel', this);
31047            utils.removeEvent(this.wrapper, 'DOMMouseScroll', this);
31048        });
31049    },
31050
31051    _wheel: function (e) {
31052        if ( !this.enabled ) {
31053            return;
31054        }
31055
31056        var wheelDeltaX, wheelDeltaY,
31057            newX, newY,
31058            that = this;
31059
31060        if ( this.wheelTimeout === undefined ) {
31061            that._execEvent('scrollStart');
31062        }
31063
31064        // Execute the scrollEnd event after 400ms the wheel stopped scrolling
31065        clearTimeout(this.wheelTimeout);
31066        this.wheelTimeout = setTimeout(function () {
31067            if(!that.options.snap) {
31068                that._execEvent('scrollEnd');
31069            }
31070            that.wheelTimeout = undefined;
31071        }, 400);
31072
31073        if ( 'deltaX' in e ) {
31074            if (e.deltaMode === 1) {
31075                wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed;
31076                wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed;
31077            } else {
31078                wheelDeltaX = -e.deltaX;
31079                wheelDeltaY = -e.deltaY;
31080            }
31081        } else if ( 'wheelDeltaX' in e ) {
31082            wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed;
31083            wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed;
31084        } else if ( 'wheelDelta' in e ) {
31085            wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed;
31086        } else if ( 'detail' in e ) {
31087            wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed;
31088        } else {
31089            return;
31090        }
31091
31092        wheelDeltaX *= this.options.invertWheelDirection;
31093        wheelDeltaY *= this.options.invertWheelDirection;
31094
31095        if ( !this.hasVerticalScroll ) {
31096            wheelDeltaX = wheelDeltaY;
31097            wheelDeltaY = 0;
31098        }
31099
31100        if ( this.options.snap ) {
31101            newX = this.currentPage.pageX;
31102            newY = this.currentPage.pageY;
31103
31104            if ( wheelDeltaX > 0 ) {
31105                newX--;
31106            } else if ( wheelDeltaX < 0 ) {
31107                newX++;
31108            }
31109
31110            if ( wheelDeltaY > 0 ) {
31111                newY--;
31112            } else if ( wheelDeltaY < 0 ) {
31113                newY++;
31114            }
31115
31116            this.goToPage(newX, newY);
31117
31118            return;
31119        }
31120
31121        newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0);
31122        newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0);
31123
31124        this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0;
31125        this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0;
31126
31127        if ( newX > 0 ) {
31128            newX = 0;
31129        } else if ( newX < this.maxScrollX ) {
31130            newX = this.maxScrollX;
31131        }
31132
31133        if ( newY > 0 ) {
31134            newY = 0;
31135        } else if ( newY < this.maxScrollY ) {
31136            newY = this.maxScrollY;
31137        }
31138
31139        this.scrollTo(newX, newY, 0);
31140
31141// INSERT POINT: _wheel
31142    },
31143
31144    _initSnap: function () {
31145        this.currentPage = {};
31146
31147        if ( typeof this.options.snap == 'string' ) {
31148            this.options.snap = this.scroller.querySelectorAll(this.options.snap);
31149        }
31150
31151        this.on('refresh', function () {
31152            var i = 0, l,
31153                m = 0, n,
31154                cx, cy,
31155                x = 0, y,
vendor: 7,339 bytes, lines 31156-31409
31156                stepX = this.options.snapStepX || this.wrapperWidth,
31157                stepY = this.options.snapStepY || this.wrapperHeight,
31158                el;
31159
31160            this.pages = [];
31161
31162            if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) {
31163                return;
31164            }
31165
31166            if ( this.options.snap === true ) {
31167                cx = Math.round( stepX / 2 );
31168                cy = Math.round( stepY / 2 );
31169
31170                while ( x > -this.scrollerWidth ) {
31171                    this.pages[i] = [];
31172                    l = 0;
31173                    y = 0;
31174
31175                    while ( y > -this.scrollerHeight ) {
31176                        this.pages[i][l] = {
31177                            x: Math.max(x, this.maxScrollX),
31178                            y: Math.max(y, this.maxScrollY),
31179                            width: stepX,
31180                            height: stepY,
31181                            cx: x - cx,
31182                            cy: y - cy
31183                        };
31184
31185                        y -= stepY;
31186                        l++;
31187                    }
31188
31189                    x -= stepX;
31190                    i++;
31191                }
31192            } else {
31193                el = this.options.snap;
31194                l = el.length;
31195                n = -1;
31196
31197                for ( ; i < l; i++ ) {
31198                    if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) {
31199                        m = 0;
31200                        n++;
31201                    }
31202
31203                    if ( !this.pages[m] ) {
31204                        this.pages[m] = [];
31205                    }
31206
31207                    x = Math.max(-el[i].offsetLeft, this.maxScrollX);
31208                    y = Math.max(-el[i].offsetTop, this.maxScrollY);
31209                    cx = x - Math.round(el[i].offsetWidth / 2);
31210                    cy = y - Math.round(el[i].offsetHeight / 2);
31211
31212                    this.pages[m][n] = {
31213                        x: x,
31214                        y: y,
31215                        width: el[i].offsetWidth,
31216                        height: el[i].offsetHeight,
31217                        cx: cx,
31218                        cy: cy
31219                    };
31220
31221                    if ( x > this.maxScrollX ) {
31222                        m++;
31223                    }
31224                }
31225            }
31226
31227            this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0);
31228
31229            // Update snap threshold if needed
31230            if ( this.options.snapThreshold % 1 === 0 ) {
31231                this.snapThresholdX = this.options.snapThreshold;
31232                this.snapThresholdY = this.options.snapThreshold;
31233            } else {
31234                this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold);
31235                this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold);
31236            }
31237        });
31238
31239        this.on('flick', function () {
31240            var time = this.options.snapSpeed || Math.max(
31241                    Math.max(
31242                        Math.min(Math.abs(this.x - this.startX), 1000),
31243                        Math.min(Math.abs(this.y - this.startY), 1000)
31244                    ), 300);
31245
31246            this.goToPage(
31247                this.currentPage.pageX + this.directionX,
31248                this.currentPage.pageY + this.directionY,
31249                time
31250            );
31251        });
31252    },
31253
31254    _nearestSnap: function (x, y) {
31255        if ( !this.pages.length ) {
31256            return { x: 0, y: 0, pageX: 0, pageY: 0 };
31257        }
31258
31259        var i = 0,
31260            l = this.pages.length,
31261            m = 0;
31262
31263        // Check if we exceeded the snap threshold
31264        if ( Math.abs(x - this.absStartX) < this.snapThresholdX &&
31265            Math.abs(y - this.absStartY) < this.snapThresholdY ) {
31266            return this.currentPage;
31267        }
31268
31269        if ( x > 0 ) {
31270            x = 0;
31271        } else if ( x < this.maxScrollX ) {
31272            x = this.maxScrollX;
31273        }
31274
31275        if ( y > 0 ) {
31276            y = 0;
31277        } else if ( y < this.maxScrollY ) {
31278            y = this.maxScrollY;
31279        }
31280
31281        for ( ; i < l; i++ ) {
31282            if ( x >= this.pages[i][0].cx ) {
31283                x = this.pages[i][0].x;
31284                break;
31285            }
31286        }
31287
31288        l = this.pages[i].length;
31289
31290        for ( ; m < l; m++ ) {
31291            if ( y >= this.pages[0][m].cy ) {
31292                y = this.pages[0][m].y;
31293                break;
31294            }
31295        }
31296
31297        if ( i == this.currentPage.pageX ) {
31298            i += this.directionX;
31299
31300            if ( i < 0 ) {
31301                i = 0;
31302            } else if ( i >= this.pages.length ) {
31303                i = this.pages.length - 1;
31304            }
31305
31306            x = this.pages[i][0].x;
31307        }
31308
31309        if ( m == this.currentPage.pageY ) {
31310            m += this.directionY;
31311
31312            if ( m < 0 ) {
31313                m = 0;
31314            } else if ( m >= this.pages[0].length ) {
31315                m = this.pages[0].length - 1;
31316            }
31317
31318            y = this.pages[0][m].y;
31319        }
31320
31321        return {
31322            x: x,
31323            y: y,
31324            pageX: i,
31325            pageY: m
31326        };
31327    },
31328
31329    goToPage: function (x, y, time, easing) {
31330        easing = easing || this.options.bounceEasing;
31331
31332        if ( x >= this.pages.length ) {
31333            x = this.pages.length - 1;
31334        } else if ( x < 0 ) {
31335            x = 0;
31336        }
31337
31338        if ( y >= this.pages[x].length ) {
31339            y = this.pages[x].length - 1;
31340        } else if ( y < 0 ) {
31341            y = 0;
31342        }
31343
31344        var posX = this.pages[x][y].x,
31345            posY = this.pages[x][y].y;
31346
31347        time = time === undefined ? this.options.snapSpeed || Math.max(
31348            Math.max(
31349                Math.min(Math.abs(posX - this.x), 1000),
31350                Math.min(Math.abs(posY - this.y), 1000)
31351            ), 300) : time;
31352
31353        this.currentPage = {
31354            x: posX,
31355            y: posY,
31356            pageX: x,
31357            pageY: y
31358        };
31359
31360        this.scrollTo(posX, posY, time, easing);
31361    },
31362
31363    next: function (time, easing) {
31364        var x = this.currentPage.pageX,
31365            y = this.currentPage.pageY;
31366
31367        x++;
31368
31369        if ( x >= this.pages.length && this.hasVerticalScroll ) {
31370            x = 0;
31371            y++;
31372        }
31373
31374        this.goToPage(x, y, time, easing);
31375    },
31376
31377    prev: function (time, easing) {
31378        var x = this.currentPage.pageX,
31379            y = this.currentPage.pageY;
31380
31381        x--;
31382
31383        if ( x < 0 && this.hasVerticalScroll ) {
31384            x = 0;
31385            y--;
31386        }
31387
31388        this.goToPage(x, y, time, easing);
31389    },
31390
31391    _initKeys: function (e) {
31392        // default key bindings
31393        var keys = {
31394            pageUp: 33,
31395            pageDown: 34,
31396            end: 35,
31397            home: 36,
31398            left: 37,
31399            up: 38,
31400            right: 39,
31401            down: 40
31402        };
31403        var i;
31404
31405        // if you give me characters I give you keycode
31406        if ( typeof this.options.keyBindings == 'object' ) {
31407            for ( i in this.options.keyBindings ) {
31408                if ( typeof this.options.keyBindings[i] == 'string' ) {
31409                    this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
vendor: 11,097 bytes, lines 31409-31762
31409deAt(0);
31410                }
31411            }
31412        } else {
31413            this.options.keyBindings = {};
31414        }
31415
31416        for ( i in keys ) {
31417            this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
31418        }
31419
31420        utils.addEvent(window, 'keydown', this);
31421
31422        this.on('destroy', function () {
31423            utils.removeEvent(window, 'keydown', this);
31424        });
31425    },
31426
31427    _key: function (e) {
31428        if ( !this.enabled ) {
31429            return;
31430        }
31431
31432        var snap = this.options.snap,   // we are using this alot, better to cache it
31433            newX = snap ? this.currentPage.pageX : this.x,
31434            newY = snap ? this.currentPage.pageY : this.y,
31435            now = utils.getTime(),
31436            prevTime = this.keyTime || 0,
31437            acceleration = 0.250,
31438            pos;
31439
31440        if ( this.options.useTransition && this.isInTransition ) {
31441            pos = this.getComputedPosition();
31442
31443            this._translate(Math.round(pos.x), Math.round(pos.y));
31444            this.isInTransition = false;
31445        }
31446
31447        this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0;
31448
31449        switch ( e.keyCode ) {
31450            case this.options.keyBindings.pageUp:
31451                if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
31452                    newX += snap ? 1 : this.wrapperWidth;
31453                } else {
31454                    newY += snap ? 1 : this.wrapperHeight;
31455                }
31456                break;
31457            case this.options.keyBindings.pageDown:
31458                if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
31459                    newX -= snap ? 1 : this.wrapperWidth;
31460                } else {
31461                    newY -= snap ? 1 : this.wrapperHeight;
31462                }
31463                break;
31464            case this.options.keyBindings.end:
31465                newX = snap ? this.pages.length-1 : this.maxScrollX;
31466                newY = snap ? this.pages[0].length-1 : this.maxScrollY;
31467                break;
31468            case this.options.keyBindings.home:
31469                newX = 0;
31470                newY = 0;
31471                break;
31472            case this.options.keyBindings.left:
31473                newX += snap ? -1 : 5 + this.keyAcceleration>>0;
31474                break;
31475            case this.options.keyBindings.up:
31476                newY += snap ? 1 : 5 + this.keyAcceleration>>0;
31477                break;
31478            case this.options.keyBindings.right:
31479                newX -= snap ? -1 : 5 + this.keyAcceleration>>0;
31480                break;
31481            case this.options.keyBindings.down:
31482                newY -= snap ? 1 : 5 + this.keyAcceleration>>0;
31483                break;
31484            default:
31485                return;
31486        }
31487
31488        if ( snap ) {
31489            this.goToPage(newX, newY);
31490            return;
31491        }
31492
31493        if ( newX > 0 ) {
31494            newX = 0;
31495            this.keyAcceleration = 0;
31496        } else if ( newX < this.maxScrollX ) {
31497            newX = this.maxScrollX;
31498            this.keyAcceleration = 0;
31499        }
31500
31501        if ( newY > 0 ) {
31502            newY = 0;
31503            this.keyAcceleration = 0;
31504        } else if ( newY < this.maxScrollY ) {
31505            newY = this.maxScrollY;
31506            this.keyAcceleration = 0;
31507        }
31508
31509        this.scrollTo(newX, newY, 0);
31510
31511        this.keyTime = now;
31512    },
31513
31514    _animate: function (destX, destY, duration, easingFn) {
31515        var that = this,
31516            startX = this.x,
31517            startY = this.y,
31518            startTime = utils.getTime(),
31519            destTime = startTime + duration;
31520
31521        function step () {
31522            var now = utils.getTime(),
31523                newX, newY,
31524                easing;
31525
31526            if ( now >= destTime ) {
31527                that.isAnimating = false;
31528                that._translate(destX, destY);
31529
31530                if ( !that.resetPosition(that.options.bounceTime) ) {
31531                    that._execEvent('scrollEnd');
31532                }
31533
31534                return;
31535            }
31536
31537            now = ( now - startTime ) / duration;
31538            easing = easingFn(now);
31539            newX = ( destX - startX ) * easing + startX;
31540            newY = ( destY - startY ) * easing + startY;
31541            that._translate(newX, newY);
31542
31543            if ( that.isAnimating ) {
31544                rAF(step);
31545            }
31546        }
31547
31548        this.isAnimating = true;
31549        step();
31550    },
31551    handleEvent: function (e) {
31552        switch ( e.type ) {
31553            case 'touchstart':
31554            case 'pointerdown':
31555            case 'MSPointerDown':
31556            case 'mousedown':
31557                this._start(e);
31558                break;
31559            case 'touchmove':
31560            case 'pointermove':
31561            case 'MSPointerMove':
31562            case 'mousemove':
31563                this._move(e);
31564                break;
31565            case 'touchend':
31566            case 'pointerup':
31567            case 'MSPointerUp':
31568            case 'mouseup':
31569            case 'touchcancel':
31570            case 'pointercancel':
31571            case 'MSPointerCancel':
31572            case 'mousecancel':
31573                this._end(e);
31574                break;
31575            case 'orientationchange':
31576            case 'resize':
31577                this._resize();
31578                break;
31579            case 'transitionend':
31580            case 'webkitTransitionEnd':
31581            case 'oTransitionEnd':
31582            case 'MSTransitionEnd':
31583                this._transitionEnd(e);
31584                break;
31585            case 'wheel':
31586            case 'DOMMouseScroll':
31587            case 'mousewheel':
31588                this._wheel(e);
31589                break;
31590            case 'keydown':
31591                this._key(e);
31592                break;
31593            case 'click':
31594                if ( this.enabled && !e._constructed ) {
31595                    e.preventDefault();
31596                    e.stopPropagation();
31597                }
31598                break;
31599        }
31600    }
31601};
31602function createDefaultScrollbar (direction, interactive, type) {
31603    var scrollbar = document.createElement('div'),
31604        indicator = document.createElement('div');
31605
31606    if ( type === true ) {
31607        scrollbar.style.cssText = 'position:absolute;z-index:9999';
31608        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';
31609    }
31610
31611    indicator.className = 'iScrollIndicator';
31612
31613    if ( direction == 'h' ) {
31614        if ( type === true ) {
31615            scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0';
31616            indicator.style.height = '100%';
31617        }
31618        scrollbar.className = 'iScrollHorizontalScrollbar';
31619    } else {
31620        if ( type === true ) {
31621            scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px';
31622            indicator.style.width = '100%';
31623        }
31624        scrollbar.className = 'iScrollVerticalScrollbar';
31625    }
31626
31627    scrollbar.style.cssText += ';overflow:hidden';
31628
31629    if ( !interactive ) {
31630        scrollbar.style.pointerEvents = 'none';
31631    }
31632
31633    scrollbar.appendChild(indicator);
31634
31635    return scrollbar;
31636}
31637
31638function Indicator (scroller, options) {
31639    this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
31640    this.wrapperStyle = this.wrapper.style;
31641    this.indicator = this.wrapper.children[0];
31642    this.indicatorStyle = this.indicator.style;
31643    this.scroller = scroller;
31644
31645    this.options = {
31646        listenX: true,
31647        listenY: true,
31648        interactive: false,
31649        resize: true,
31650        defaultScrollbars: false,
31651        shrink: false,
31652        fade: false,
31653        speedRatioX: 0,
31654        speedRatioY: 0
31655    };
31656
31657    for ( var i in options ) {
31658        this.options[i] = options[i];
31659    }
31660
31661    this.sizeRatioX = 1;
31662    this.sizeRatioY = 1;
31663    this.maxPosX = 0;
31664    this.maxPosY = 0;
31665
31666    if ( this.options.interactive ) {
31667        if ( !this.options.disableTouch ) {
31668            utils.addEvent(this.indicator, 'touchstart', this);
31669            utils.addEvent(window, 'touchend', this);
31670        }
31671        if ( !this.options.disablePointer ) {
31672            utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
31673            utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this);
31674        }
31675        if ( !this.options.disableMouse ) {
31676            utils.addEvent(this.indicator, 'mousedown', this);
31677            utils.addEvent(window, 'mouseup', this);
31678        }
31679    }
31680
31681    if ( this.options.fade ) {
31682        this.wrapperStyle[utils.style.transform] = this.scroller.translateZ;
31683        var durationProp = utils.style.transitionDuration;
31684        if(!durationProp) {
31685            return;
31686        }
31687        this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms';
31688        // remove 0.0001ms
31689        var self = this;
31690        if(utils.isBadAndroid) {
31691            rAF(function() {
31692                if(self.wrapperStyle[durationProp] === '0.0001ms') {
31693                    self.wrapperStyle[durationProp] = '0s';
31694                }
31695            });
31696        }
31697        this.wrapperStyle.opacity = '0';
31698    }
31699}
31700
31701Indicator.prototype = {
31702    handleEvent: function (e) {
31703        switch ( e.type ) {
31704            case 'touchstart':
31705            case 'pointerdown':
31706            case 'MSPointerDown':
31707            case 'mousedown':
31708                this._start(e);
31709                break;
31710            case 'touchmove':
31711            case 'pointermove':
31712            case 'MSPointerMove':
31713            case 'mousemove':
31714                this._move(e);
31715                break;
31716            case 'touchend':
31717            case 'pointerup':
31718            case 'MSPointerUp':
31719            case 'mouseup':
31720            case 'touchcancel':
31721            case 'pointercancel':
31722            case 'MSPointerCancel':
31723            case 'mousecancel':
31724                this._end(e);
31725                break;
31726        }
31727    },
31728
31729    destroy: function () {
31730        if ( this.options.fadeScrollbars ) {
31731            clearTimeout(this.fadeTimeout);
31732            this.fadeTimeout = null;
31733        }
31734        if ( this.options.interactive ) {
31735            utils.removeEvent(this.indicator, 'touchstart', this);
31736            utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
31737            utils.removeEvent(this.indicator, 'mousedown', this);
31738
31739            utils.removeEvent(window, 'touchmove', this);
31740            utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
31741            utils.removeEvent(window, 'mousemove', this);
31742
31743            utils.removeEvent(window, 'touchend', this);
31744            utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this);
31745            utils.removeEvent(window, 'mouseup', this);
31746        }
31747
31748        if ( this.options.defaultScrollbars ) {
31749            this.wrapper.parentNode.removeChild(this.wrapper);
31750        }
31751    },
31752
31753    _start: function (e) {
31754        var point = e.touches ? e.touches[0] : e;
31755
31756        e.preventDefault();
31757        e.stopPropagation();
31758
31759        this.transitionTime();
31760
31761        this.initiated = true;
31762        this.moved = false;
vendor: 9,615 bytes, lines 31763-32021
31763        this.lastPointX = point.pageX;
31764        this.lastPointY = point.pageY;
31765
31766        this.startTime  = utils.getTime();
31767
31768        if ( !this.options.disableTouch ) {
31769            utils.addEvent(window, 'touchmove', this);
31770        }
31771        if ( !this.options.disablePointer ) {
31772            utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this);
31773        }
31774        if ( !this.options.disableMouse ) {
31775            utils.addEvent(window, 'mousemove', this);
31776        }
31777
31778        this.scroller._execEvent('beforeScrollStart');
31779    },
31780
31781    _move: function (e) {
31782        var point = e.touches ? e.touches[0] : e,
31783            deltaX, deltaY,
31784            newX, newY,
31785            timestamp = utils.getTime();
31786
31787        if ( !this.moved ) {
31788            this.scroller._execEvent('scrollStart');
31789        }
31790
31791        this.moved = true;
31792
31793        deltaX = point.pageX - this.lastPointX;
31794        this.lastPointX = point.pageX;
31795
31796        deltaY = point.pageY - this.lastPointY;
31797        this.lastPointY = point.pageY;
31798
31799        newX = this.x + deltaX;
31800        newY = this.y + deltaY;
31801
31802        this._pos(newX, newY);
31803
31804// INSERT POINT: indicator._move
31805
31806        e.preventDefault();
31807        e.stopPropagation();
31808    },
31809
31810    _end: function (e) {
31811        if ( !this.initiated ) {
31812            return;
31813        }
31814
31815        this.initiated = false;
31816
31817        e.preventDefault();
31818        e.stopPropagation();
31819
31820        utils.removeEvent(window, 'touchmove', this);
31821        utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
31822        utils.removeEvent(window, 'mousemove', this);
31823
31824        if ( this.scroller.options.snap ) {
31825            var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y);
31826
31827            var time = this.options.snapSpeed || Math.max(
31828                    Math.max(
31829                        Math.min(Math.abs(this.scroller.x - snap.x), 1000),
31830                        Math.min(Math.abs(this.scroller.y - snap.y), 1000)
31831                    ), 300);
31832
31833            if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) {
31834                this.scroller.directionX = 0;
31835                this.scroller.directionY = 0;
31836                this.scroller.currentPage = snap;
31837                this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing);
31838            }
31839        }
31840
31841        if ( this.moved ) {
31842            this.scroller._execEvent('scrollEnd');
31843        }
31844    },
31845
31846    transitionTime: function (time) {
31847        time = time || 0;
31848        var durationProp = utils.style.transitionDuration;
31849        if(!durationProp) {
31850            return;
31851        }
31852
31853        this.indicatorStyle[durationProp] = time + 'ms';
31854
31855        if ( !time && utils.isBadAndroid ) {
31856            this.indicatorStyle[durationProp] = '0.0001ms';
31857            // remove 0.0001ms
31858            var self = this;
31859            rAF(function() {
31860                if(self.indicatorStyle[durationProp] === '0.0001ms') {
31861                    self.indicatorStyle[durationProp] = '0s';
31862                }
31863            });
31864        }
31865    },
31866
31867    transitionTimingFunction: function (easing) {
31868        this.indicatorStyle[utils.style.transitionTimingFunction] = easing;
31869    },
31870
31871    refresh: function () {
31872        this.transitionTime();
31873
31874        if ( this.options.listenX && !this.options.listenY ) {
31875            this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
31876        } else if ( this.options.listenY && !this.options.listenX ) {
31877            this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
31878        } else {
31879            this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
31880        }
31881
31882        if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) {
31883            utils.addClass(this.wrapper, 'iScrollBothScrollbars');
31884            utils.removeClass(this.wrapper, 'iScrollLoneScrollbar');
31885
31886            if ( this.options.defaultScrollbars && this.options.customStyle ) {
31887                if ( this.options.listenX ) {
31888                    this.wrapper.style.right = '8px';
31889                } else {
31890                    this.wrapper.style.bottom = '8px';
31891                }
31892            }
31893        } else {
31894            utils.removeClass(this.wrapper, 'iScrollBothScrollbars');
31895            utils.addClass(this.wrapper, 'iScrollLoneScrollbar');
31896
31897            if ( this.options.defaultScrollbars && this.options.customStyle ) {
31898                if ( this.options.listenX ) {
31899                    this.wrapper.style.right = '2px';
31900                } else {
31901                    this.wrapper.style.bottom = '2px';
31902                }
31903            }
31904        }
31905
31906        var r = this.wrapper.offsetHeight;  // force refresh
31907
31908        if ( this.options.listenX ) {
31909            this.wrapperWidth = this.wrapper.clientWidth;
31910            if ( this.options.resize ) {
31911                this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
31912                this.indicatorStyle.width = this.indicatorWidth + 'px';
31913            } else {
31914                this.indicatorWidth = this.indicator.clientWidth;
31915            }
31916
31917            this.maxPosX = this.wrapperWidth - this.indicatorWidth;
31918
31919            if ( this.options.shrink == 'clip' ) {
31920                this.minBoundaryX = -this.indicatorWidth + 8;
31921                this.maxBoundaryX = this.wrapperWidth - 8;
31922            } else {
31923                this.minBoundaryX = 0;
31924                this.maxBoundaryX = this.maxPosX;
31925            }
31926
31927            this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
31928        }
31929
31930        if ( this.options.listenY ) {
31931            this.wrapperHeight = this.wrapper.clientHeight;
31932            if ( this.options.resize ) {
31933                this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
31934                this.indicatorStyle.height = this.indicatorHeight + 'px';
31935            } else {
31936                this.indicatorHeight = this.indicator.clientHeight;
31937            }
31938
31939            this.maxPosY = this.wrapperHeight - this.indicatorHeight;
31940
31941            if ( this.options.shrink == 'clip' ) {
31942                this.minBoundaryY = -this.indicatorHeight + 8;
31943                this.maxBoundaryY = this.wrapperHeight - 8;
31944            } else {
31945                this.minBoundaryY = 0;
31946                this.maxBoundaryY = this.maxPosY;
31947            }
31948
31949            this.maxPosY = this.wrapperHeight - this.indicatorHeight;
31950            this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
31951        }
31952
31953        this.updatePosition();
31954    },
31955
31956    updatePosition: function () {
31957        var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
31958            y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
31959
31960        if ( !this.options.ignoreBoundaries ) {
31961            if ( x < this.minBoundaryX ) {
31962                if ( this.options.shrink == 'scale' ) {
31963                    this.width = Math.max(this.indicatorWidth + x, 8);
31964                    this.indicatorStyle.width = this.width + 'px';
31965                }
31966                x = this.minBoundaryX;
31967            } else if ( x > this.maxBoundaryX ) {
31968                if ( this.options.shrink == 'scale' ) {
31969                    this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
31970                    this.indicatorStyle.width = this.width + 'px';
31971                    x = this.maxPosX + this.indicatorWidth - this.width;
31972                } else {
31973                    x = this.maxBoundaryX;
31974                }
31975            } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) {
31976                this.width = this.indicatorWidth;
31977                this.indicatorStyle.width = this.width + 'px';
31978            }
31979
31980            if ( y < this.minBoundaryY ) {
31981                if ( this.options.shrink == 'scale' ) {
31982                    this.height = Math.max(this.indicatorHeight + y * 3, 8);
31983                    this.indicatorStyle.height = this.height + 'px';
31984                }
31985                y = this.minBoundaryY;
31986            } else if ( y > this.maxBoundaryY ) {
31987                if ( this.options.shrink == 'scale' ) {
31988                    this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
31989                    this.indicatorStyle.height = this.height + 'px';
31990                    y = this.maxPosY + this.indicatorHeight - this.height;
31991                } else {
31992                    y = this.maxBoundaryY;
31993                }
31994            } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) {
31995                this.height = this.indicatorHeight;
31996                this.indicatorStyle.height = this.height + 'px';
31997            }
31998        }
31999
32000        this.x = x;
32001        this.y = y;
32002
32003        if ( this.scroller.options.useTransform ) {
32004            this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ;
32005        } else {
32006            this.indicatorStyle.left = x + 'px';
32007            this.indicatorStyle.top = y + 'px';
32008        }
32009    },
32010
32011    _pos: function (x, y) {
32012        if ( x < 0 ) {
32013            x = 0;
32014        } else if ( x > this.maxPosX ) {
32015            x = this.maxPosX;
32016        }
32017
32018        if ( y < 0 ) {
32019            y = 0;
32020        } else if ( y > this.maxPosY ) {
32021            y = this.maxPosY;
32022        }
32023
32024        x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x;
32025        y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y;
32026
32027        this.scroller.scrollTo(x, y);
32028    },
32029
32030    fade: function (val, hold) {
32031        if ( hold && !this.visible ) {
32032            return;
32033        }
32034
32035        clearTimeout(this.fadeTimeout);
32036        this.fadeTimeout = null;
32037
32038        var time = val ? 250 : 500,
32039            delay = val ? 0 : 300;
32040
32041        val = val ? '1' : '0';
32042
32043        this.wrapperStyle[utils.style.transitionDuration] = time + 'ms';
32044
32045        this.fadeTimeout = setTimeout((function (val) {
32046            this.wrapperStyle.opacity = val;
32047            this.visible = +val;
32048        }).bind(this, val), delay);
32049    }
32050};
32051
32052IScroll.utils = utils;
32053
32054if ( typeof module != 'undefined' && module.exports ) {
32055    module.exports = IScroll;
32056} else if ( typeof define == 'function' && define.amd ) {
32057        define( function () { return IScroll; } );
32058} else {
32059    window.IScroll = IScroll;
32060}
32061
32062})(window, document, Math);
32063/*!
32064 * fullPage 2.9.4
32065 * https://github.com/alvarotrigo/fullPage.js
32066 * @license MIT licensed
32067 *
32068 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo
32069 */
32070(function(global, factory) {
32071    'use strict';
32072    if (typeof define === 'function' && define.amd) {
32073        define(['jquery'], function($) {
32074          return factory($, global, global.document, global.Math);
32075        });
32076    } else if (typeof exports === "object" && exports) {
32077        module.exports = factory(require('jquery'), global, global.document, global.Math);
32078    } else {
32079        factory(jQuery, global, global.document, global.Math);
32080    }
32081})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) {
32082    'use strict';
32083
32084    // keeping central set of classnames and selectors
32085    var WRAPPER =               'fullpage-wrapper';
32086    var WRAPPER_SEL =           '.' + WRAPPER;
32087
32088    // slimscroll
32089    var SCROLLABLE =            'fp-scrollable';
32090    var SCROLLABLE_SEL =        '.' + SCROLLABLE;
32091
32092    // util
32093    var RESPONSIVE =            'fp-responsive';
32094    var NO_TRANSITION =         'fp-notransition';
32095    var DESTROYED =             'fp-destroyed';
32096    var ENABLED =               'fp-enabled';
32097    var VIEWING_PREFIX =        'fp-viewing';
32098    var ACTIVE =                'active';
32099    var ACTIVE_SEL =            '.' + ACTIVE;
32100    var COMPLETELY =            'fp-completely';
32101    var COMPLETELY_SEL =        '.' + COMPLETELY;
32102
32103    // section
32104    var SECTION_DEFAULT_SEL =   '.section';
32105    var SECTION =               'fp-section';
32106    var SECTION_SEL =           '.' + SECTION;
32107    var SECTION_ACTIVE_SEL =    SECTION_SEL + ACTIVE_SEL;
32108    var SECTION_FIRST_SEL =     SECTION_SEL + ':first';
32109    var SECTION_LAST_SEL =      SECTION_SEL + ':last';
32110    var TABLE_CELL =            'fp-tableCell';
32111    var TABLE_CELL_SEL =        '.' + TABLE_CELL;
32112    var AUTO_HEIGHT =           'fp-auto-height';
32113    var AUTO_HEIGHT_SEL =       '.fp-auto-height';
32114    var NORMAL_SCROLL =         'fp-normal-scroll';
32115    var NORMAL_SCROLL_SEL =     '.fp-normal-scroll';
32116
32117    // section nav
32118    var SECTION_NAV =           'fp-nav';
32119    var SECTION_NAV_SEL =       '#' + SECTION_NAV;
32120    var SECTION_NAV_TOOLTIP =   'fp-tooltip';
32121    var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP;
32122    var SHOW_ACTIVE_TOOLTIP =   'fp-show-active';
32123
32124    // slide
32125    var SLIDE_DEFAULT_SEL =     '.slide';
32126    var SLIDE =                 'fp-slide';
32127    var SLIDE_SEL =             '.' + SLIDE;
32128    var SLIDE_ACTIVE_SEL =      SLIDE_SEL + ACTIVE_SEL;
32129    var SLIDES_WRAPPER =        'fp-slides';
32130    var SLIDES_WRAPPER_SEL =    '.' + SLIDES_WRAPPER;
32131    var SLIDES_CONTAINER =      'fp-slidesContainer';
32132    var SLIDES_CONTAINER_SEL =  '.' + SLIDES_CONTAINER;
32133    var TABLE =                 'fp-table';
32134
32135    // slide nav
32136    var SLIDES_NAV =            'fp-slidesNav';
32137    var SLIDES_NAV_SEL =        '.' + SLIDES_NAV;
32138    var SLIDES_NAV_LINK_SEL =   SLIDES_NAV_SEL + ' a';
32139    var SLIDES_ARROW =          'fp-controlArrow';
32140    var SLIDES_ARROW_SEL =      '.' + SLIDES_ARROW;
32141    var SLIDES_PREV =           'fp-prev';
32142    var SLIDES_PREV_SEL =       '.' + SLIDES_PREV;
32143    var SLIDES_ARROW_PREV =     SLIDES_ARROW + ' ' + SLIDES_PREV;
32144    var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL;
32145    var SLIDES_NEXT =           'fp-next';
32146    var SLIDES_NEXT_SEL =       '.' + SLIDES_NEXT;
32147    var SLIDES_ARROW_NEXT =     SLIDES_ARROW + ' ' + SLIDES_NEXT;
32148    var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL;
32149
32150    var $window = $(window);
32151    var $document = $(document);
32152
32153    // Default options for iScroll.js used when using scrollOverflow
32154    var iscrollOptions = {
32155        scrollbars: true,
32156        mouseWheel: true,
32157        hideScrollbars: false,
32158        fadeScrollbars: false,
32159        disableMouse: true,
32160        interactiveScrollbars: true,
32161        bounce: false,
32162    };
32163
32164    $.fn.fullpage = function(options) {
32165        //only once my friend!
32166        if($('html').hasClass(ENABLED)){ displayWarnings(); return; }
32167
32168        // common jQuery objects
32169        var $htmlBody = $('html, body');
32170        var $body = $('body');
32171
32172        var FP = $.fn.fullpage;
32173
32174        // Creating some defaults, extending them with any options that were provided
32175        options = $.extend({
32176            //navigation
32177            menu: false,
32178            anchors:[],
32179            lockAnchors: false,
32180            navigation: false,
32181            navigationPosition: 'right',
32182            navigationTooltips: [],
32183            showActiveTooltip: false,
32184            slidesNavigation: false,
32185            slidesNavPosition: 'bottom',
32186            scrollBar: false,
32187            hybrid: false,
32188
32189            //scrolling
32190            css3: true,
32191            scrollingSpeed: 700,
32192            autoScrolling: true,
32193            fitToSection: true,
32194            fitToSectionDelay: 1000,
32195            easing: 'easeInOutCubic',
32196            easingcss3: 'ease',
32197            loopBottom: false,
32198            loopTop: false,
32199            loopHorizontal: true,
32200            continuousVertical: false,
32201            continuousHorizontal: false,
32202            scrollHorizontally: false,
32203            interlockedSlides: false,
32204            dragAndMove: false,
32205            offsetSections: false,
32206            resetSliders: false,
32207            fadingEffect: false,
32208            normalScrollElements: null,
32209            scrollOverflow: false,
32210            scrollOverflowReset: false,
32211            scrollOverflowHandler: iscrollHandler,
32212            scrollOverflowOptions: null,
32213            touchSensitivity: 5,
32214            normalScrollElementTouchThreshold: 5,
32215            bigSectionsDestination: null,
32216
32217            //Accessibility
32218            keyboardScrolling: true,
32219            animateAnchor: true,
32220            recordHistory: true,
32221
32222            //design
32223            controlArrows: true,
32224            controlArrowColor: '#fff',
32225            verticalCentered: true,
32226            sectionsColor : [],
32227            paddingTop: 0,
32228            paddingBottom: 0,
32229            fixedElements: null,
32230            responsive: 0, //backwards compabitility with responsiveWiddth
32231            responsiveWidth: 0,
32232            responsiveHeight: 0,
32233            responsiveSlides: false,
32234            parallax: false,
32235            parallaxOptions: {
32236                type: 'reveal',
32237                percentage: 62,
32238                property: 'translate'
32239            },
32240
32241            //Custom selectors
32242            sectionSelector: SECTION_DEFAULT_SEL,
32243            slideSelector: SLIDE_DEFAULT_SEL,
32244
32245            //events
32246            afterLoad: null,
32247            onLeave: null,
32248            afterRender: null,
32249            afterResize: null,
32250            afterReBuild: null,
32251            afterSlideLoad: null,
32252            onSlideLeave: null,
32253            afterResponsive: null,
32254
32255            lazyLoading: true
32256        }, options);
32257
32258        //flag to avoid very fast sliding for landscape sliders
32259        var slideMoving = false;
32260
32261        var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/);
32262        var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints));
32263        var container = $(this);
32264        var windowsHeight = $window.height();
32265        var isResizing = false;
32266        var isWindowFocused = true;
32267        var lastScrolledDestiny;
32268        var lastScrolledSlide;
32269        var canScroll = true;
32270        var scrollings = [];
32271        var controlPressed;
32272        var startingSection;
32273        var isScrollAllowed = {};
32274        isScrollAllowed.m = {  'up':true, 'down':true, 'left':true, 'right':true };
32275        isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m);
32276        var MSPointer = getMSPointer();
32277        var events = {
32278            touchmove: 'ontouchmove' in window ? 'touchmove' :  MSPointer.move,
32279            touchstart: 'ontouchstart' in window ? 'touchstart' :  MSPointer.down
32280        };
32281
32282        //cheks for passive event support
32283        //added by Uncode from new fullPage updates
32284        var g_supportsPassive = false;
32285        try {
32286          var opts = Object.defineProperty({}, 'passive', {
32287            get: function() {
32288              g_supportsPassive = true;
32289            }
32290          });
32291          window.addEventListener("testPassive", null, opts);
32292          window.removeEventListener("testPassive", null, opts);
32293        } catch (e) {}
32294
32295        //timeouts
32296        var resizeId;
32297        var afterSectionLoadsId;
32298        var afterSlideLoadsId;
32299        var scrollId;
32300        var scrollId2;
32301        var keydownId;
32302        var originals = $.extend(true, {}, options); //deep copy
32303
32304        //Uncode addition
32305        var $masthead = $('#masthead');
32306        var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false;
32307        var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight;
32308        var bodyBorder = UNCODE.bodyBorder;
32309        var adminBarHeight = UNCODE.adminBarHeight;
32310
32311        displayWarnings();
32312
32313        //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783
32314        iscrollOptions.click = isTouch; // see #2035
32315
32316        //extending iScroll options with the user custom ones
32317        iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions);
32318
32319        //easeInOutCubic animation included in the plugin
32320        $.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;}});
32321
32322        /**
32323        * Sets the autoScroll option.
32324        * It changes the scroll bar visibility and the history of the site as a result.
32325        */
32326        function setAutoScrolling(value, type){
32327            //removing the transformation
32328            if(!value){
32329                silentScroll(0);
32330            }
32331
32332            setVariableState('autoScrolling', value, type);
32333
32334            var element = $(SECTION_ACTIVE_SEL);
32335
32336            if(options.autoScrolling && !options.scrollBar){
32337                $htmlBody.css({
32338                    'overflow' : 'hidden !important',
32339                    'height' : '100%'
32340                });
32341
32342                //Uncode addition
32343                //setRecordHistory(originals.recordHistory, 'internal');
32344
32345                //for IE touch devices
32346                container.css({
32347                    '-ms-touch-action': 'none',
32348                    'touch-action': 'none'
32349                });
32350
32351                if(element.length){
32352                    //moving the container up
32353                    silentScroll(element.position().top);
32354                }
32355
32356            }else{
32357                $htmlBody.css({
32358                    'overflow' : 'visible !important',
32359                    'height' : 'initial'
32360                });
32361
32362                //Uncode addition
32363                //setRecordHistory(false, 'internal');
32364
32365                //for IE touch devices
32366                container.css({
32367                    '-ms-touch-action': '',
32368                    'touch-action': ''
32369                });
32370
32371                //scrolling the page to the section with no animation
32372                if (element.length) {
32373                    $htmlBody.scrollTop(element.position().top);
32374                }
32375            }
32376        }
32377
32378        /**
32379        * Defines wheter to record the history for each hash change in the URL.
32380        */
32381        function setRecordHistory(value, type){
32382            setVariableState('recordHistory', value, type);
32383        }
32384
32385        /**
32386        * Defines the scrolling speed
32387        */
32388        function setScrollingSpeed(value, type){
32389            setVariableState('scrollingSpeed', value, type);
32390        }
32391
32392        /**
32393        * Sets fitToSection
32394        */
32395        function setFitToSection(value, type){
32396            setVariableState('fitToSection', value, type);
32397        }
32398
32399        /**
32400        * Sets lockAnchors
32401        */
32402        function setLockAnchors(value){
32403            options.lockAnchors = value;
32404        }
32405
32406        /**
32407        * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad.
32408        */
32409        function setMouseWheelScrolling(value){
32410            if(value){
32411                addMouseWheelHandler();
32412                addMiddleWheelHandler();
32413            }else{
32414                removeMouseWheelHandler();
32415                removeMiddleWheelHandler();
32416            }
32417        }
32418
32419        /**
32420        * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures.
32421        * Optionally a second parameter can be used to specify the direction for which the action will be applied.
32422        *
32423        * @param directions string containing the direction or directions separated by comma.
32424        */
32425        function setAllowScrolling(value, directions){
32426            if(typeof directions !== 'undefined'){
32427                directions = directions.replace(/ /g,'').split(',');
32428
32429                $.each(directions, function (index, direction){
32430                    setIsScrollAllowed(value, direction, 'm');
32431                });
32432            }
32433            else if(value){
32434                setMouseWheelScrolling(true);
32435                addTouchHandler();
32436            }else{
32437                setMouseWheelScrolling(false);
32438                removeTouchHandler();
32439            }
32440        }
32441
32442        /**
32443        * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys
32444        */
32445        function setKeyboardScrolling(value, directions){
32446            if(typeof directions !== 'undefined'){
32447                directions = directions.replace(/ /g,'').split(',');
32448
32449                $.each(directions, function (index, direction){
32450                    setIsScrollAllowed(value, direction, 'k');
32451                });
32452            }else{
32453                options.keyboardScrolling = value;
32454            }
32455        }
32456
32457        /**
32458        * Moves the page up one section.
32459        */
32460        function moveSectionUp(){
32461            var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL);
32462
32463            //looping to the bottom if there's no more sections above
32464            if (!prev.length && (options.loopTop || options.continuousVertical)) {
32465                prev = $(SECTION_SEL).last();
32466            }
32467
32468            if (prev.length) {
32469                scrollPage(prev, null, true);
32470            }
32471        }
32472
32473        /**
32474        * Moves the page down one section.
32475        */
32476        function moveSectionDown(){
32477            var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL);
32478
32479            //looping to the top if there's no more sections below
32480            if(!next.length &&
32481                (options.loopBottom || options.continuousVertical)){
32482                next = $(SECTION_SEL).first();
32483            }
32484
32485            if(next.length){
32486                scrollPage(next, null, false);
32487            }
32488        }
32489
32490        /**
32491        * Moves the page to the given section and slide with no animation.
32492        * Anchors or index positions can be used as params.
32493        */
32494        function silentMoveTo(sectionAnchor, slideAnchor){
32495            setScrollingSpeed (0, 'internal');
32496            moveTo(sectionAnchor, slideAnchor);
32497            setScrollingSpeed (originals.scrollingSpeed, 'internal');
32498        }
32499
32500        /**
32501        * Moves the page to the given section and slide.
32502        * Anchors or index positions can be used as params.
32503        */
32504        function moveTo(sectionAnchor, slideAnchor){
32505            var destiny = getSectionByAnchor(sectionAnchor);
32506
32507            if (typeof slideAnchor !== 'undefined'){
32508                scrollPageAndSlide(sectionAnchor, slideAnchor);
32509            }else if(destiny.length > 0){
32510                scrollPage(destiny);
32511            }
32512        }
32513
32514        /**
32515        * Slides right the slider of the active section.
32516        * Optional `section` param.
32517        */
32518        function moveSlideRight(section){
32519            moveSlide('right', section);
32520        }
32521
32522        /**
32523        * Slides left the slider of the active section.
32524        * Optional `section` param.
32525        */
32526        function moveSlideLeft(section){
32527            moveSlide('left', section);
32528        }
32529
32530        /**
32531         * When resizing is finished, we adjust the slides sizes and positions
32532         */
32533        function reBuild(resizing){
32534            if(container.hasClass(DESTROYED)){ return; }  //nothing to do if the plugin was destroyed
32535
32536            isResizing = true;
32537
32538            windowsHeight = $window.height();  //updating global var
32539
32540            $(SECTION_SEL).each(function(){
32541                var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL);
32542                var slides = $(this).find(SLIDE_SEL);
32543
32544                //adjusting the height of the table-cell for IE and Firefox
32545                if(options.verticalCentered){
32546                    $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px');
32547                }
32548
32549                $(this).css('height', windowsHeight + 'px');
32550
32551                //resizing the scrolling divs
32552                if(options.scrollOverflow){
32553                    if(slides.length){
32554                        slides.each(function(){
32555                            createScrollBar($(this));
32556                        });
32557                    }else{
32558                        createScrollBar($(this));
32559                    }
32560                }
32561
32562                //adjusting the position fo the FULL WIDTH slides...
32563                if (slides.length > 1) {
32564                    landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL));
32565                }
32566            });
32567
32568            var activeSection = $(SECTION_ACTIVE_SEL);
32569            var sectionIndex = activeSection.index(SECTION_SEL);
32570
32571            //isn't it the first section?
32572            if(sectionIndex){
32573                //adjusting the position for the current section
32574                silentMoveTo(sectionIndex + 1);
32575            }
32576
32577            isResizing = false;
32578            // Uncode change
32579            // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container);
32580            $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight());
32581            $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container);
32582        }
32583
32584        /**
32585        * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height`
32586        * are smaller than the set limit values.
32587        */
32588        function setResponsive(active){
32589            var isResponsive = $body.hasClass(RESPONSIVE);
32590
32591            if(active){
32592                if(!isResponsive){
32593                    setAutoScrolling(false, 'internal');
32594                    setFitToSection(false, 'internal');
32595                    $(SECTION_NAV_SEL).hide();
32596                    $body.addClass(RESPONSIVE);
32597                    $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active);
32598                }
32599            }
32600            else if(isResponsive){
32601                setAutoScrolling(originals.autoScrolling, 'internal');
32602                setFitToSection(originals.autoScrolling, 'internal');
32603                $(SECTION_NAV_SEL).show();
32604                $body.removeClass(RESPONSIVE);
32605                $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active);
32606            }
32607        }
32608
32609        if($(this).length){
32610            //public functions
32611            FP.setAutoScrolling = setAutoScrolling;
32612            FP.setRecordHistory = setRecordHistory;
32613            FP.setScrollingSpeed = setScrollingSpeed;
32614            FP.setFitToSection = setFitToSection;
32615            FP.setLockAnchors = setLockAnchors;
32616            FP.setMouseWheelScrolling = setMouseWheelScrolling;
32617            FP.setAllowScrolling = setAllowScrolling;
32618            FP.setKeyboardScrolling = setKeyboardScrolling;
32619            FP.moveSectionUp = moveSectionUp;
32620            FP.moveSectionDown = moveSectionDown;
32621            FP.silentMoveTo = silentMoveTo;
32622            FP.moveTo = moveTo;
32623            FP.moveSlideRight = moveSlideRight;
32624            FP.moveSlideLeft = moveSlideLeft;
32625            FP.fitToSection = fitToSection;
32626            FP.reBuild = reBuild;
32627            FP.setResponsive = setResponsive;
32628            FP.destroy = destroy;
32629
32630            init();
32631
32632            bindEvents();
32633        }
32634
32635        function init(){
32636            //if css3 is not supported, it will use jQuery animations
32637            if(options.css3){
32638                options.css3 = support3d();
32639            }
32640
32641            options.scrollBar = options.scrollBar || options.hybrid;
32642
32643            setOptionsFromDOM();
32644            prepareDom();
32645            setAllowScrolling(true);
32646            setAutoScrolling(options.autoScrolling, 'internal');
32647            responsive();
32648
32649            //setting the class for the body element
32650            setBodyClass();
32651
32652            //Uncode addition
32653            // if(document.readyState === 'complete'){
32654            //     scrollToAnchor();
32655            // }
32656            // $window.on('load', scrollToAnchor);
32657        }
32658
32659        function bindEvents(){
32660            $window
32661                //when scrolling...
32662                //.on('scroll', scrollHandler)
32663
32664                //detecting any change on the URL to scroll to the given anchor link
32665                //(a way to detect back history button as we play with the hashes on the URL)
32666                .on('hashchange', hashChangeHandler)
32667
32668                //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
32669                .blur(blurHandler)
32670
32671                //when resizing the site, we adjust the heights of the sections, slimScroll...
32672                .resize(resizeHandler);
32673
32674            $document
32675                //Sliding with arrow keys, both, vertical and horizontal
32676                .keydown(keydownHandler)
32677
32678                //to prevent scrolling while zooming
32679                .keyup(keyUpHandler)
32680
32681                //Scrolls to the section when clicking the navigation bullet
32682                .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler)
32683
32684                //Scrolls the slider to the given slide destination for the given section
32685                .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler)
32686
32687                .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler);
32688
32689            //Scrolling horizontally when clicking on the slider controls.
32690            $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler);
32691
32692            /**
32693            * Applying normalScroll elements.
32694            * Ignoring the scrolls over the specified selectors.
32695            */
32696            if(options.normalScrollElements){
32697                $document.on('mouseenter', options.normalScrollElements, function () {
32698                    setMouseWheelScrolling(false);
32699                });
32700
32701                $document.on('mouseleave', options.normalScrollElements, function(){
32702                    setMouseWheelScrolling(true);
32703                });
32704            }
32705        }
32706
32707        /**
32708        * Setting options from DOM elements if they are not provided.
32709        */
32710        function setOptionsFromDOM(){
32711            var sections = container.find(options.sectionSelector);
32712
32713            //no anchors option? Checking for them in the DOM attributes
32714            if(!options.anchors.length){
32715                options.anchors = sections.filter('[data-anchor]').map(function(){
32716                    return $(this).data('anchor').toString();
32717                }).get();
32718            }
32719
32720            //no tooltips option? Checking for them in the DOM attributes
32721            if(!options.navigationTooltips.length){
32722                options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){
32723                    return $(this).data('tooltip').toString();
32724                }).get();
32725            }
32726        }
32727
32728        /**
32729        * Works over the DOM structure to set it up for the current fullpage options.
32730        */
32731        function prepareDom(){
32732            container.css({
32733                'height': '100%',
32734                'position': 'relative'
32735            });
32736
32737            //adding a class to recognize the container internally in the code
32738            container.addClass(WRAPPER);
32739            $('html').addClass(ENABLED);
32740
32741            windowsHeight = $window.height();
32742
32743            container.removeClass(DESTROYED); //in case it was destroyed before initializing it again
32744
32745            addInternalSelectors();
32746
32747             //styling the sections / slides / menu
32748            $(SECTION_SEL).each(function(index){
32749                var section = $(this);
32750                var slides = section.find(SLIDE_SEL);
32751                var numSlides = slides.length;
32752
32753                styleSection(section, index);
32754                styleMenu(section, index);
32755
32756                // if there's any slide
32757                if (numSlides > 0) {
32758                    styleSlides(section, slides, numSlides);
32759                }else{
32760                    if(options.verticalCentered){
32761                        addTableClass(section);
32762                    }
32763                }
32764            });
32765
32766            //fixed elements need to be moved out of the plugin container due to problems with CSS3.
32767            if(options.fixedElements && options.css3){
32768                $(options.fixedElements).appendTo($body);
32769            }
32770
32771            //vertical centered of the navigation + active bullet
32772            if(options.navigation){
32773                addVerticalNavigation();
32774            }
32775
32776            enableYoutubeAPI();
32777
32778            if(options.scrollOverflow){
32779                if(document.readyState === 'complete'){
32780                    createScrollBarHandler();
32781                }
32782                //after DOM and images are loaded
32783                $window.on('load', createScrollBarHandler);
32784            }else{
32785                afterRenderActions();
32786            }
32787        }
32788
32789        /**
32790        * Styles the horizontal slides for a section.
32791        */
32792        function styleSlides(section, slides, numSlides){
32793            var sliderWidth = numSlides * 100;
32794            var slideWidth = 100 / numSlides;
32795
32796            slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />');
32797            slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />');
32798
32799            section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%');
32800
32801            if(numSlides > 1){
32802                if(options.controlArrows){
32803                    createSlideArrows(section);
32804                }
32805
32806                if(options.slidesNavigation){
32807                    addSlidesNavigation(section, numSlides);
32808                }
32809            }
32810
32811            slides.each(function(index) {
32812                $(this).css('width', slideWidth + '%');
32813
32814                if(options.verticalCentered){
32815                    addTableClass($(this));
32816                }
32817            });
32818
32819            var startingSlide = section.find(SLIDE_ACTIVE_SEL);
32820
32821            //if the slide won't be an starting point, the default will be the first one
32822            //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
32822ide by default.
32823            if( startingSlide.length &&  ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){
32824                silentLandscapeScroll(startingSlide, 'internal');
32825            }else{
32826                slides.eq(0).addClass(ACTIVE);
32827            }
32828        }
32829
32830        /**
32831        * Styling vertical sections
32832        */
32833        function styleSection(section, index){
32834            //if no active section is defined, the 1st one will be the default one
32835            if(!index && $(SECTION_ACTIVE_SEL).length === 0) {
32836                section.addClass(ACTIVE);
32837            }
32838            startingSection = $(SECTION_ACTIVE_SEL);
32839
32840            section.css('height', windowsHeight + 'px');
32841
32842            if(options.paddingTop){
32843                section.css('padding-top', options.paddingTop);
32844            }
32845
32846            if(options.paddingBottom){
32847                section.css('padding-bottom', options.paddingBottom);
32848            }
32849
32850            if (typeof options.sectionsColor[index] !==  'undefined') {
32851                section.css('background-color', options.sectionsColor[index]);
32852            }
32853
32854            if (typeof options.anchors[index] !== 'undefined') {
32855                section.attr('data-anchor', options.anchors[index]);
32856            }
32857        }
32858
32859        /**
32860        * Sets the data-anchor attributes to the menu elements and activates the current one.
32861        */
32862        function styleMenu(section, index){
32863            if (typeof options.anchors[index] !== 'undefined') {
32864                //activating the menu / nav element on load
32865                if(section.hasClass(ACTIVE)){
32866                    activateMenuAndNav(options.anchors[index], index);
32867                }
32868            }
32869
32870            //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms)
32871            if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){
32872                $(options.menu).appendTo($body);
32873            }
32874        }
32875
32876        /**
32877        * Adds internal classes to be able to provide customizable selectors
32878        * keeping the link with the style sheet.
32879        */
32880        function addInternalSelectors(){
32881            container.find(options.sectionSelector).addClass(SECTION);
32882            container.find(options.slideSelector).addClass(SLIDE);
32883        }
32884
32885        /**
32886        * Creates the control arrows for the given section
32887        */
32888        function createSlideArrows(section){
32889            section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>');
32890
32891            if(options.controlArrowColor!='#fff'){
32892                section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor);
32893                section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent');
32894            }
32895
32896            if(!options.loopHorizontal){
32897                section.find(SLIDES_ARROW_PREV_SEL).hide();
32898            }
32899        }
32900
32901        /**
32902        * Creates a vertical navigation bar.
32903        */
32904        function addVerticalNavigation(){
32905            $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>');
32906            var nav = $(SECTION_NAV_SEL);
32907
32908            nav.addClass(function() {
32909                return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition;
32910            });
32911
32912            for (var i = 0; i < $(SECTION_SEL).length; i++) {
32913                var link = '';
32914                if (options.anchors.length) {
32915                    link = options.anchors[i];
32916                }
32917
32918                var li = '<li><a href="#' + link + '"><span></span></a>';
32919
32920                // Only add tooltip if needed (defined by user)
32921                var tooltip = options.navigationTooltips[i];
32922
32923                if (typeof tooltip !== 'undefined' && tooltip !== '') {
32924                    li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>';
32925                }
32926
32927                li += '</li>';
32928
32929                nav.find('ul').append(li);
32930            }
32931
32932            //centering it vertically
32933            $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px');
32934
32935            //activating the current active section
32936            $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE);
32937        }
32938
32939        /**
32940        * Creates the slim scroll scrollbar for the sections and slides inside them.
32941        */
32942        function createScrollBarHandler(){
32943            $(SECTION_SEL).each(function(){
32944                var slides = $(this).find(SLIDE_SEL);
32945
32946                if(slides.length){
32947                    slides.each(function(){
32948                        createScrollBar($(this));
32949                    });
32950                }else{
32951                    createScrollBar($(this));
32952                }
32953
32954            });
32955            afterRenderActions();
32956        }
32957
32958        /*
32959        * Enables the Youtube videos API so we can control their flow if necessary.
32960        */
32961        function enableYoutubeAPI(){
32962            container.find('iframe[src*="youtube.com/embed/"]').each(function(){
32963                addURLParam($(this), 'enablejsapi=1');
32964            });
32965        }
32966
32967        /**
32968        * Adds a new parameter and its value to the `src` of a given element
32969        */
32970        function addURLParam(element, newParam){
32971            var originalSrc = element.attr('src');
32972            element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam);
32973        }
32974
32975        /*
32976        * Returns the prefix sign to use for a new parameter in an existen URL.
32977        *
32978        * @return {String}  ? | &
32979        */
32980        function getUrlParamSign(url){
32981            return ( !/\?/.test( url ) ) ? '?' : '&';
32982        }
32983
32984        /**
32985        * Actions and callbacks to fire afterRender
32986        */
32987        function afterRenderActions(){
32988            var section = $(SECTION_ACTIVE_SEL);
32989
32990            section.addClass(COMPLETELY);
32991
32992            if(options.scrollOverflowHandler.afterRender){
32993                options.scrollOverflowHandler.afterRender(section);
32994            }
32995            lazyLoad(section);
32996            playMedia(section);
32997            options.scrollOverflowHandler.afterLoad();
32998
32999            if(isDestinyTheStartingSection()){
33000                $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1));
33001            }
33002
33003            // Uncode change
33004            // $.isFunction( options.afterRender ) && options.afterRender.call(container);
33005            $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight());
33006        }
33007
33008        /**
33009        * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization)
33010        */
33011        function isDestinyTheStartingSection(){
33012            var anchors =  window.location.hash.replace('#', '').split('/');
33013            var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0]));
33014
33015            return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index();
33016        }
33017
33018
33019        var isScrolling = false;
33020        var lastScroll = 0;
33021
33022        //when scrolling...
33023        function scrollHandler(){
33024            var currentSection;
33025
33026            if(!options.autoScrolling || options.scrollBar){
33027                var currentScroll = $window.scrollTop();
33028                var scrollDirection = getScrollDirection(currentScroll);
33029                var visibleSectionIndex = 0;
33030                var screen_mid = currentScroll + ($window.height() / 2.0);
33031                var isAtBottom = $body.height() - $window.height() === currentScroll;
33032                var sections =  document.querySelectorAll(SECTION_SEL);
33033
33034                //when using `auto-height` for a small last section it won't be centered in the viewport
33035                if(isAtBottom){
33036                    visibleSectionIndex = sections.length - 1;
33037                }
33038                //is at top? when using `auto-height` for a small first section it won't be centered in the viewport
33039                else if(!currentScroll){
33040                    visibleSectionIndex = 0;
33041                }
33042
33043                //taking the section which is showing more content in the viewport
33044                else{
33045                    for (var i = 0; i < sections.length; ++i) {
33046                        var section = sections[i];
33047
33048                        // Pick the the last section which passes the middle line of the screen.
33049                        if (section.offsetTop <= screen_mid)
33050                        {
33051                            visibleSectionIndex = i;
33052                        }
33053                    }
33054                }
33055
33056                if(isCompletelyInViewPort(scrollDirection)){
33057                    if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){
33058                        $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY);
33059                    }
33060                }
33061
33062                //geting the last one, the current one on the screen
33063                currentSection = $(sections).eq(visibleSectionIndex);
33064
33065                //setting the visible section as active when manually scrolling
33066                //executing only once the first time we reach the section
33067                if(!currentSection.hasClass(ACTIVE)){
33068                    isScrolling = true;
33069                    var leavingSection = $(SECTION_ACTIVE_SEL);
33070                    var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1;
33071                    var yMovement = getYmovement(currentSection);
33072                    var anchorLink  = currentSection.data('anchor');
33073                    var sectionIndex = currentSection.index(SECTION_SEL) + 1;
33074                    var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL);
33075                    var slideIndex;
33076                    var slideAnchorLink;
33077
33078                    if(activeSlide.length){
33079                        slideAnchorLink = activeSlide.data('anchor');
33080                        slideIndex = activeSlide.index();
33081                    }
33082
33083                    if(canScroll){
33084                        currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE);
33085
33086                        $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement);
33087                        $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex);
33088
33089                        stopMedia(leavingSection);
33090                        lazyLoad(currentSection);
33091                        playMedia(currentSection);
33092
33093                        activateMenuAndNav(anchorLink, sectionIndex - 1);
33094
33095                        if(options.anchors.length){
33096                            //needed to enter in hashChange event when using the menu with anchor links
33097                            lastScrolledDestiny = anchorLink;
33098                        }
33099                        setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex);
33100                    }
33101
33102                    //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet
33103                    clearTimeout(scrollId);
33104                    scrollId = setTimeout(function(){
33105                        isScrolling = false;
33106                    }, 100);
33107                }
33108
33109                if(options.fitToSection){
33110                    //for the auto adjust of the viewport to fit a whole section
33111                    clearTimeout(scrollId2);
33112
33113                    scrollId2 = setTimeout(function(){
33114                        //checking it again in case it changed during the delay
33115                        if(options.fitToSection){
33116                            fitToSection();
33117                        }
33118                    }, options.fitToSectionDelay);
33119                }
33120            }
33121        }
33122
33123        /**
33124        * Fits the site to the nearest active section
33125        */
33126        function fitToSection(){
33127            //checking fitToSection again in case it was set to false before the timeout delay
33128            if(canScroll){
33129                //allows to scroll to an active section and
33130                //if the section is already active, we prevent firing callbacks
33131                isResizing = true;
33132
33133                scrollPage($(SECTION_ACTIVE_SEL));
33134                isResizing = false;
33135            }
33136        }
33137
33138        /**
33139        * Determines whether the active section has seen in its whole or not.
33140        */
33141        function isCompletelyInViewPort(movement){
33142            var top = $(SECTION_ACTIVE_SEL).position().top;
33143            var bottom = top + $window.height();
33144
33145            if(movement == 'up'){
33146                return bottom >= ($window.scrollTop() + $window.height());
33147            }
33148            return top <= $window.scrollTop();
33149        }
33150
33151        /**
33152        * Gets the directon of the the scrolling fired by the scroll event.
33153        */
33154        function getScrollDirection(currentScroll){
33155            var direction = currentScroll > lastScroll ? 'down' : 'up';
33156
33157            lastScroll = currentScroll;
33158
33159            //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination
33160            previousDestTop = currentScroll;
33161
33162            return direction;
33163        }
33164
33165        /**
33166        * Determines the way of scrolling up or down:
33167        * by 'automatically' scrolling a section or by using the default and normal scrolling.
33168        */
33169        function scrolling(type, scrollable){
33170            if (!isScrollAllowed.m[type]){
33171                return;
33172            }
33173            var check = (type === 'down') ? 'bottom' : 'top';
33174            var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp;
33175
33176            if(scrollable.length > 0 ){
33177                //is the scrollbar at the start/end of the scroll?
33178                if(options.scrollOverflowHandler.isScrolled(check, scrollable)){
33179                    scrollSection();
33180                }else{
33181                    return true;
33182                }
33183            }else{
33184                // moved up/down
33185                scrollSection();
33186            }
33187        }
33188
33189        /*
33190        * Preventing bouncing in iOS #2285
33191        */
33192        function preventBouncing(event){
33193            var e = event.originalEvent;
33194            if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){
33195                //preventing the easing on iOS devices
33196                event.preventDefault();
33197            }
33198        }
33199
33200        var touchStartY = 0;
33201        var touchStartX = 0;
33202        var touchEndY = 0;
33203        var touchEndX = 0;
33204
33205        /* Detecting touch events
33206
33207        * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it.
33208        * This way, the touchstart and the touch moves shows an small difference between them which is the
33209        * used one to determine the direction.
33210        */
33211        function touchMoveHandler(event){
33212            var e = event.originalEvent;
33213            var activeSection = $(e.target).closest(SECTION_SEL);
33214
33215            // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain
33216            if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) {
33217
33218                if(options.autoScrolling){
33219                    //preventing the easing on iOS devices
33220                    event.preventDefault();
33221                }
33222
33223                var scrollable = options.scrollOverflowHandler.scrollable(activeSection);
33224                var touchEvents = getEventsPage(e);
33225
33226                touchEndY = touchEvents.y;
33227                touchEndX = touchEvents.x;
33228
33229                //if movement in the X axys is greater than in the Y and the currect section has slides...
33230                if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) {
33231
33232                    //is the movement greater than the minimum resistance to scroll?
33233                    if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) {
33234                        if (touchStartX > touchEndX) {
33235                            if(isScrollAllowed.m.right){
33236                                moveSlideRight(activeSection); //next
33237                            }
33238                        } else {
33239                            if(isScrollAllowed.m.left){
33240                                moveSlideLeft(activeSection); //prev
33241                            }
33242                        }
33243                    }
33244                }
33245
33246                //vertical scrolling (only when autoScrolling is enabled)
33247                else if(options.autoScrolling && canScroll){
33248
33249                    //is the movement greater than the minimum resistance to scroll?
33250                    if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) {
33251                        if (touchStartY > touchEndY) {
33252                            scrolling('down', scrollable);
33253                        } else if (touchEndY > touchStartY) {
33254                            scrolling('up', scrollable);
33255                        }
33256                    }
33257                }
33258            }
33259        }
33260
33261        /**
33262         * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements
33263         * Currently works well for iOS - Android might need some testing
33264         * @param  {Element} el  target element / jquery selector (in subsequent nodes)
33265         * @param  {int}     hop current hop compared to options.normalScrollElementTouchThreshold
33266         * @return {boolean} true if there is a match to options.normalScrollElements
33267         */
33268        function checkParentForNormalScrollElement (el, hop) {
33269            hop = hop || 0;
33270            var parent = $(el).parent();
33271
33272            if (hop < options.normalScrollElementTouchThreshold &&
33273                parent.is(options.normalScrollElements) ) {
33274                return true;
33275            } else if (hop == options.normalScrollElementTouchThreshold) {
33276                return false;
33277            } else {
33278                return checkParentForNormalScrollElement(parent, ++hop);
33279            }
33280        }
33281
33282        /**
33283        * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen
33284        * this way we make sure that is really a touch event what IE is detecting.
33285        */
33286        function isReallyTouch(e){
33287            //if is not IE   ||  IE is detecting `touch` or `pen`
33288            return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse';
33289        }
33290
33291        /**
33292        * Handler for the touch start event.
33293        */
33294        function touchStartHandler(event){
33295            var e = event.originalEvent;
33296
33297            //stopping the auto scroll to adjust to a section
33298            if(options.fitToSection){
33299                $htmlBody.stop();
33300            }
33301
33302            if(isReallyTouch(e)){
33303                var touchEvents = getEventsPage(e);
33304                touchStartY = touchEvents.y;
33305                touchStartX = touchEvents.x;
33306            }
33307        }
33308
33309        /**
33310        * Gets the average of the last `number` elements of the given array.
33311        */
33312        function getAverage(elements, number){
33313            var sum = 0;
33314
33315            //taking `number` elements from the end to make the average, if there are not enought, 1
33316            var lastElements = elements.slice(Math.max(elements.length - number, 1));
33317
33318            for(var i = 0; i < lastElements.length; i++){
33319                sum = sum + lastElements[i];
33320            }
33321
33322            return Math.ceil(sum/number);
33323        }
33324
33325        /**
33326         * Detecting mousewheel scrolling
33327         *
33328         * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html
33329         * http://www.sitepoint.com/html5-javascript-mouse-wheel/
33330         */
33331        var prevTime = new Date().getTime();
33332
33333        function MouseWheelHandler(e) {
33334            var curTime = new Date().getTime();
33335            var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL);
33336
33337            //autoscrolling and not zooming?
33338            if(options.autoScrolling && !controlPressed && !isNormalScroll){
33339                // cross-browser wheel delta
33340                e = e || window.event;
33341                var value = e.wheelDelta || -e.deltaY || -e.detail;
33342                var delta = Math.max(-1, Math.min(1, value));
33343
33344                var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined';
33345                var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection);
33346
33347                //Limiting the array to 150 (lets not waste memory!)
33348                if(scrollings.length > 149){
33349                    scrollings.shift();
33350                }
33351
33352                //keeping record of the previous scrollings
33353                scrollings.push(Math.abs(value));
33354
33355                //preventing to scroll the site on mouse wheel when scrollbar is present
33356                if(options.scrollBar){
33357                    e.preventDefault ? e.preventDefault() : e.returnValue = false;
33358                }
33359
33360                var activeSection = $(SECTION_ACTIVE_SEL);
33361                var scrollable = options.scrollOverflowHandler.scrollable(activeSection);
33362
33363                //time difference between the last scroll and the current one
33364                var timeDiff = curTime-prevTime;
33365                prevTime = curTime;
33366
33367                //haven't they scrolled in a while?
33368                //(enough to be consider a different scrolling action to scroll another section)
33369                if(timeDiff > 200){
33370                    //emptying the array, we dont care about old scrollings for our averages
33371                    scrollings = [];
33372                }
33373
33374                if(canScroll){
33375                    var averageEnd = getAverage(scrollings, 10);
33376                    var averageMiddle = getAverage(scrollings, 70);
33377                    var isAccelerating = averageEnd >= averageMiddle;
33378
33379                    //to avoid double swipes...
33380                    if(isAccelerating && isScrollingVertically){
33381                        //scrolling down?
33382                        if (delta < 0) {
33383                            scrolling('down', scrollable);
33384
33385                        //scrolling up?
33386                        }else {
33387                            scrolling('up', scrollable);
33388                        }
33389                    }
33390                }
33391
33392                return false;
33393            }
33394
33395            if(options.fitToSection){
33396                //stopping the auto scroll to adjust to a section
33397                $htmlBody.stop();
33398            }
33399        }
33400
33401        /**
33402        * Slides a slider to the given direction.
33403        * Optional `section` param.
33404        */
33405        function moveSlide(direction, section){
33406            var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section;
33407            var slides = activeSection.find(SLIDES_WRAPPER_SEL);
33408            var numSlides = slides.find(SLIDE_SEL).length;
33409
33410            // more than one slide needed and nothing should be sliding
33411            if (!slides.length || slideMoving || numSlides < 2) {
33412                return;
33413            }
33414
33415            var currentSlide = slides.find(SLIDE_ACTIVE_SEL);
33416            var destiny = null;
33417
33418            if(direction === 'left'){
33419                destiny = currentSlide.prev(SLIDE_SEL);
33420            }else{
33421                destiny = currentSlide.next(SLIDE_SEL);
33422            }
33423
33424            //isn't there a next slide in the secuence?
33425            if(!destiny.length){
33426                //respect loopHorizontal settin
33427                if (!options.loopHorizontal) return;
33428
33429                if(direction === 'left'){
33430                    destiny = currentSlide.siblings(':last');
33431                }else{
33432                    destiny = currentSlide.siblings(':first');
33433                }
33434            }
33435
33436            slideMoving = true;
33437
33438            landscapeScroll(slides, destiny, direction);
33439        }
33440
33441        /**
33442        * Maintains the active slides in the viewport
33443        * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical)
33444        */
33445        function keepSlidesPosition(){
33446            $(SLIDE_ACTIVE_SEL).each(function(){
33447                silentLandscapeScroll($(this), 'internal');
33448            });
33449        }
33450
33451        var previousDestTop = 0;
33452        /**
33453        * Returns the destination Y position based on the scrolling direction and
33454        * the height of the section.
33455        */
33456        function getDestinationPosition(element){
33457            var elemPosition = element.position();
33458
33459            //top of the desination will be at the top of the viewport
33460            var position = elemPosition.top;
33461            var isScrollingDown =  elemPosition.top > previousDestTop;
33462            var sectionBottom = position - windowsHeight + element.outerHeight();
33463            var bigSectionsDestination = options.bigSectionsDestination;
33464
33465            //Uncode addition
33466            var containerH = container.outerHeight();
33467            var containerPosition = container.offset();
33468
33469            //########### Commented by Uncode - START ###########
33470            //is the destination element bigger than the viewport?
33471            // if(element.outerHeight() > windowsHeight){
33472            //     //scrolling up?
33473            //     if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){
33474            //         position = sectionBottom;
33475            //     }
33476            // }
33477
33478            // //sections equal or smaller than the viewport height && scrolling down? ||  is resizing and its in the last section
33479            // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){
33480            //     //The bottom of the destination will be at the bottom of the viewport
33481            //     position = sectionBottom;
33482            // }
33483            //########### Commented by Uncode - END ###########
33484
33485            //Uncode addition
33486            if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') )
33487                position += 18;
33488            if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) {
33489                position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight;
33490            }
33491
33492            /*
33493            Keeping record of the last scrolled position to determine the scrolling direction.
33494            No conventional methods can be used as the scroll bar might not be present
33495            AND the section might not be active if it is auto-height and didnt reach the middle
33496            of the viewport.
33497            */
33498            previousDestTop = position;
33499            return position;
33500        }
33501
33502        /**
33503        * Scrolls the site to the given element and scrolls to the slide if a callback is given.
33504        */
33505        function scrollPage(element, callback, isMovementUp){
33506            if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function
33507
33508            var dtop = getDestinationPosition(element);
33509            var slideAnchorLink;
33510            var slideIndex;
33511
33512            //local variables
33513            var v = {
33514                element: element,
33515                callback: callback,
33516                isMovementUp: isMovementUp,
33517                dtop: dtop,
33518                yMovement: getYmovement(element),
33519                anchorLink: element.data('anchor'),
33520                sectionIndex: element.index(SECTION_SEL),
33521                activeSlide: element.find(SLIDE_ACTIVE_SEL),
33522                activeSection: $(SECTION_ACTIVE_SEL),
33523                leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1,
33524
33525                //caching the value of isResizing at the momment the function is called
33526                //because it will be checked later inside a setTimeout and the value might change
33527                localIsResizing: isResizing
33528            };
33529
33530            //quiting when destination scroll is the same as the current one
33531            if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; }
33532
33533            if(v.activeSlide.length){
33534                slideAnchorLink = v.activeSlide.data('anchor');
33535                slideIndex = v.activeSlide.index();
33536            }
33537
33538            // If continuousVertical && we need to wrap around
33539            if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" &&
33540                ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or
33541                (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down
33542
33543                v = createInfiniteSections(v);
33544            }
33545
33546            //callback (onLeave) if the site is not just resizing and readjusting the slides
33547            if($.isFunction(options.onLeave) && !v.localIsResizing){
33548                if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){
33549                    return;
33550                }
33551            }
33552
33553            //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one)
33554            if(!v.localIsResizing){
33555                stopMedia(v.activeSection);
33556            }
33557
33558            options.scrollOverflowHandler.beforeLeave();
33559            element.addClass(ACTIVE).siblings().removeClass(ACTIVE);
33560            lazyLoad(element);
33561            options.scrollOverflowHandler.onLeave();
33562
33563
33564            //preventing from activating the MouseWheelHandler event
33565            //more than once if the page is scrolling
33566            canScroll = false;
33567
33568            setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex);
33569
33570            performMovement(v);
33571
33572            //flag to avoid callingn `scrollPage()` twice in case of using anchor links
33573            lastScrolledDestiny = v.anchorLink;
33574
33575            //avoid firing it twice (as it does also on scroll)
33576            activateMenuAndNav(v.anchorLink, v.sectionIndex);
33577        }
33578
33579        /**
33580        * Performs the vertical movement (by CSS3 or by jQuery)
33581        */
33582        function performMovement(v){
33583            // using CSS3 translate functionality
33584            if (options.css3 && options.autoScrolling && !options.scrollBar) {
33585
33586                // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
33587                // that's why we round it to 0.
33588                var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)';
33589                transformContainer(translate3d, true);
33590
33591                //even when the scrollingSpeed is 0 there's a little delay, which might cause the
33592                //scrollingSpeed to change in case of using silentMoveTo();
33593                if(options.scrollingSpeed){
33594                    clearTimeout(afterSectionLoadsId);
33595                    afterSectionLoadsId = setTimeout(function () {
33596                        afterSectionLoads(v);
33597                    }, options.scrollingSpeed);
33598                }else{
33599                    afterSectionLoads(v);
33600                }
33601            }
33602
33603            // using jQuery animate
33604            else{
33605                var scrollSettings = getScrollSettings(v);
33606
33607                $(scrollSettings.element).animate(
33608                    scrollSettings.options,
33609                options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating  `html, body`
33610                    if(options.scrollBar){
33611
33612                        /* Hack!
33613                        The timeout prevents setting the most dominant section in the viewport as "active" when the user
33614                        scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar.
33615
33616                        When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished.
33617                        */
33618                        setTimeout(function(){
33619                            afterSectionLoads(v);
33620                        },30);
33621                    }else{
33622                        afterSectionLoads(v);
33623                    }
33624                });
33625            }
33626        }
33627
33628        /**
33629        * Gets the scrolling settings depending on the plugin autoScrolling option
33630        */
33631        function getScrollSettings(v){
33632            var scroll = {};
33633
33634            if(options.autoScrolling && !options.scrollBar){
33635                scroll.options = { 'top': -v.dtop};
33636                scroll.element = WRAPPER_SEL;
33637            }else{
33638                scroll.options = { 'scrollTop': v.dtop};
33639                scroll.element = 'html, body';
33640            }
33641
33642            return scroll;
33643        }
33644
33645        /**
33646        * Adds sections before or after the current one to create the infinite effect.
33647        */
33648        function createInfiniteSections(v){
33649            // Scrolling down
33650            if (!v.isMovementUp) {
33651                // Move all previous sections to after the active section
33652                $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse());
33653            }
33654            else { // Scrolling up
33655                // Move all next sections to before the active section
33656                $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL));
33657            }
33658
33659            // Maintain the displayed position (now that we changed the element order)
33660            silentScroll($(SECTION_ACTIVE_SEL).position().top);
33661
33662            // Maintain the active slides visible in the viewport
33663            keepSlidesPosition();
33664
33665            // save for later the elements that still need to be reordered
33666            v.wrapAroundElements = v.activeSection;
33667
33668            // Recalculate animation variables
33669            v.dtop = v.element.position().top;
33670            v.yMovement = getYmovement(v.element);
33671
33672            return v;
33673        }
33674
33675        /**
33676        * Fix section order after continuousVertical changes have been animated
33677        */
33678        function continuousVerticalFixSectionOrder (v) {
33679            // If continuousVertical is in effect (and autoScrolling would also be in effect then),
33680            // finish moving the elements around so the direct navigation will function more simply
33681            if (!v.wrapAroundElements || !v.wrapAroundElements.length) {
33682                return;
33683            }
33684
33685            if (v.isMovementUp) {
33686                $(SECTION_FIRST_SEL).before(v.wrapAroundElements);
33687            }
33688            else {
33689                $(SECTION_LAST_SEL).after(v.wrapAroundElements);
33690            }
33691
33692            silentScroll($(SECTION_ACTIVE_SEL).position().top);
33693
33694            // Maintain the active slides visible in the viewport
33695            keepSlidesPosition();
33696        }
33697
33698
33699        /**
33700        * Actions to do once the section is loaded.
33701        */
33702        function afterSectionLoads (v){
33703            continuousVerticalFixSectionOrder(v);
33704
33705            //callback (afterLoad) if the site is not just resizing and readjusting the slides
33706            $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1));
33707            options.scrollOverflowHandler.afterLoad();
33708
33709            if(!v.localIsResizing){
33710                playMedia(v.element);
33711            }
33712
33713            v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY);
33714
33715            canScroll = true;
33716
33717            $.isFunction(v.callback) && v.callback.call(this);
33718        }
33719
33720        /**
33721        * Sets the value for the given attribute from the `data-` attribute with the same suffix
33722        * ie: data-srcset ==> srcset  |  data-src ==> src
33723        */
33724        function setSrc(element, attribute){
33725            element
33726                .attr(attribute, element.data(attribute))
33727                .removeAttr('data-' + attribute);
33728        }
33729
33730        /**
33731        * Lazy loads image, video and audio elements.
33732        */
33733        function lazyLoad(destiny){
33734            if (!options.lazyLoading){
33735                return;
33736            }
33737
33738            var panel = getSlideOrSection(destiny);
33739            var element;
33740
33741            panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){
33742                element = $(this);
33743
33744                $.each(['src', 'srcset'], function(index, type){
33745                    var attribute = element.attr('data-' + type);
33746                    if(typeof attribute !== 'undefined' && attribute){
33747                        setSrc(element, type);
33748                    }
33749                });
33750
33751                if(element.is('source')){
33752                    element.closest('video').get(0).load();
33753                }
33754            });
33755        }
33756
33757        /**
33758        * Plays video and audio elements.
33759        */
33760        function playMedia(destiny){
33761            var panel = getSlideOrSection(destiny);
33762
33763            //playing HTML5 media elements
33764            panel.find('video, audio').each(function(){
33765                var element = $(this).get(0);
33766
33767                if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) {
33768                    element.play();
33769                }
33770            });
33771
33772            //youtube videos
33773            panel.find('iframe[src*="youtube.com/embed/"]').each(function(){
33774                var element = $(this).get(0);
33775
33776                if ( element.hasAttribute('data-autoplay') ){
33777                    playYoutube(element);
33778                }
33779
33780                //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load.
33781                element.onload = function() {
33782                    if ( element.hasAttribute('data-autoplay') ){
33783                        playYoutube(element);
33784                    }
33785                };
33786            });
33787        }
33788
33789        /**
33790        * Plays a youtube video
33791        */
33792        function playYoutube(element){
33793            element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
33794        }
33795
33796        /**
33797        * Stops video and audio elements.
33798        */
33799        function stopMedia(destiny){
33800            var panel = getSlideOrSection(destiny);
33801
33802            //stopping HTML5 media elements
33803            panel.find('video, audio').each(function(){
33804                var element = $(this).get(0);
33805
33806                if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) {
33807                    element.pause();
33808                }
33809            });
33810
33811            //youtube videos
33812            panel.find('iframe[src*="youtube.com/embed/"]').each(function(){
33813                var element = $(this).get(0);
33814
33815                if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){
33816                    $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*');
33817                }
33818            });
33819        }
33820
33821        /**
33822        * Gets the active slide (or section) for the given section
33823        */
33824        function getSlideOrSection(destiny){
33825            var slide = destiny.find(SLIDE_ACTIVE_SEL);
33826            if( slide.length ) {
33827                destiny = $(slide);
33828            }
33829
33830            return destiny;
33831        }
33832
33833        /**
33834        * Scrolls to the anchor in the URL when loading the site
33835        */
33836        function scrollToAnchor(){
33837            //getting the anchor link in the URL and deleting the `#`
33838            var value =  window.location.hash.replace('#', '').split('/');
33839            var sectionAnchor = decodeURIComponent(value[0]);
33840            var slideAnchor = decodeURIComponent(value[1]);
33841
33842            if(sectionAnchor){  //if theres any #
33843                if(options.animateAnchor){
33844                    scrollPageAndSlide(sectionAnchor, slideAnchor);
33845                }else{
33846                    silentMoveTo(sectionAnchor, slideAnchor);
33847                }
33848            }
33849        }
33850
33851        /**
33852        * Detecting any change on the URL to scroll to the given anchor link
33853        * (a way to detect back history button as we play with the hashes on the URL)
33854        */
33855        function hashChangeHandler(){
33856            if(!isScrolling && !options.lockAnchors){
33857                var value =  window.location.hash.replace('#', '').split('/');
33858                var sectionAnchor = decodeURIComponent(value[0]);
33859                var slideAnchor = decodeURIComponent(value[1]);
33860
33861                    //when moving to a slide in the first section for the first time (first time to add an anchor to the URL)
33862                    var isFirstSlideMove =  (typeof lastScrolledDestiny === 'undefined');
33863                    var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving);
33864
33865
33866                if(sectionAnchor.length){
33867                    /*in order to call scrollpage() only once for each destination at a time
33868                    It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange`
33869                    event is fired on every scroll too.*/
33870                    if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor ))  {
33871                        scrollPageAndSlide(sectionAnchor, slideAnchor);
33872                    }
33873                }
33874            }
33875        }
33876
33877        //Sliding with arrow keys, both, vertical and horizontal
33878        function keydownHandler(e) {
33879
33880            clearTimeout(keydownId);
33881
33882            var activeElement = $(':focus');
33883
33884            if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') &&
33885                activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' &&
33886                options.keyboardScrolling && options.autoScrolling){
33887                var keyCode = e.which;
33888
33889                //preventing the scroll with arrow keys & spacebar & Page Up & Down keys
33890                var keyControls = [40, 38, 32, 33, 34];
33891                if($.inArray(keyCode, keyControls) > -1){
33892                    e.preventDefault();
33893                }
33894
33895                controlPressed = e.ctrlKey;
33896
33897                keydownId = setTimeout(function(){
33898                    onkeydown(e);
33899                },150);
33900            }
33901        }
33902
33903        function tooltipTextHandler(){
33904            $(this).prev().trigger('click');
33905        }
33906
33907        //to prevent scrolling while zooming
33908        function keyUpHandler(e){
33909            if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox
33910                controlPressed = e.ctrlKey;
33911            }
33912        }
33913
33914        //binding the mousemove when the mouse's middle button is released
33915        function mouseDownHandler(e){
33916            //middle button
33917            if (e.which == 2){
33918                oldPageY = e.pageY;
33919                container.on('mousemove', mouseMoveHandler);
33920            }
33921        }
33922
33923        //unbinding the mousemove when the mouse's middle button is released
33924        function mouseUpHandler(e){
33925            //middle button
33926            if (e.which == 2){
33927                container.off('mousemove');
33928            }
33929        }
33930
33931        //Scrolling horizontally when clicking on the slider controls.
33932        function slideArrowHandler(){
33933            var section = $(this).closest(SECTION_SEL);
33934
33935            if ($(this).hasClass(SLIDES_PREV)) {
33936                if(isScrollAllowed.m.left){
33937                    moveSlideLeft(section);
33938                }
33939            } else {
33940                if(isScrollAllowed.m.right){
33941                    moveSlideRight(section);
33942                }
33943            }
33944        }
33945
33946        //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
33947        function blurHandler(){
33948            isWindowFocused = false;
33949            controlPressed = false;
33950        }
33951
33952        //Scrolls to the section when clicking the navigation bullet
33953        function sectionBulletHandler(e){
33954            e.preventDefault();
33955            var index = $(this).parent().index();
33956            scrollPage($(SECTION_SEL).eq(index));
33957        }
33958
33959        //Scrolls the slider to the given slide destination for the given section
33960        function slideBulletHandler(e){
33961            e.preventDefault();
33962            var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL);
33963            var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index());
33964
33965            landscapeScroll(slides, destiny);
33966        }
33967
33968        /**
33969        * Keydown event
33970        */
33971        function onkeydown(e){
33972            var shiftPressed = e.shiftKey;
33973
33974            //do nothing if we can not scroll or we are not using horizotnal key arrows.
33975            if(!canScroll && [37,39].indexOf(e.which) < 0){
33976                return;
33977            }
33978
33979            switch (e.which) {
33980                //up
33981                case 38:
33982                case 33:
33983                    if(isScrollAllowed.k.up){
33984                        moveSectionUp();
33985                    }
33986                    break;
33987
33988                //down
33989                case 32: //spacebar
33990                    if(shiftPressed && isScrollAllowed.k.up){
33991                        moveSectionUp();
33992                        break;
33993                    }
33994                /* falls through */
33995                case 40:
33996                case 34:
33997                    if(isScrollAllowed.k.down){
33998                        moveSectionDown();
33999                    }
34000                    break;
34001
34002                //Home
34003                case 36:
34004                    if(isScrollAllowed.k.up){
34005                        moveTo(1);
34006                    }
34007                    break;
34008
34009                //End
34010                case 35:
34011                     if(isScrollAllowed.k.down){
34012                        moveTo( $(SECTION_SEL).length );
34013                    }
34014                    break;
34015
34016                //left
34017                case 37:
34018                    if(isScrollAllowed.k.left){
34019                        moveSlideLeft();
34020                    }
34021                    break;
34022
34023                //right
34024                case 39:
34025                    if(isScrollAllowed.k.right){
34026                        moveSlideRight();
34027                    }
34028                    break;
34029
34030                default:
34031                    return; // exit this handler for other keys
34032            }
34033        }
34034
34035        /**
34036        * Detecting the direction of the mouse movement.
34037        * Used only for the middle button of the mouse.
34038        */
34039        var oldPageY = 0;
34040        function mouseMoveHandler(e){
34041            if(canScroll){
34042                // moving up
34043                if (e.pageY < oldPageY && isScrollAllowed.m.up){
34044                    moveSectionUp();
34045                }
34046
34047                // moving down
34048                else if(e.pageY > oldPageY && isScrollAllowed.m.down){
34049                    moveSectionDown();
34050                }
34051            }
34052            oldPageY = e.pageY;
34053        }
34054
34055        /**
34056        * Scrolls horizontal sliders.
34057        */
34058        function landscapeScroll(slides, destiny, direction){
34059            var section = slides.closest(SECTION_SEL);
34060            var v = {
34061                slides: slides,
34062                destiny: destiny,
34063                direction: direction,
34064                destinyPos: destiny.position(),
34065                slideIndex: destiny.index(),
34066                section: section,
34067                sectionIndex: section.index(SECTION_SEL),
34068                anchorLink: section.data('anchor'),
34069                slidesNav: section.find(SLIDES_NAV_SEL),
34070                slideAnchor:  getAnchor(destiny),
34071                prevSlide: section.find(SLIDE_ACTIVE_SEL),
34072                prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(),
34073
34074                //caching the value of isResizing at the momment the function is called
34075                //because it will be checked later inside a setTimeout and the value might change
34076                localIsResizing: isResizing
34077            };
34078            v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex);
34079            v.direction = v.direction ? v.direction : v.xMovement;
34080
34081            //important!! Only do it when not resizing
34082            if(!v.localIsResizing){
34083                //preventing from scrolling to the next/prev section when using scrollHorizontally
34084                canScroll = false;
34085            }
34086
34087            if(options.onSlideLeave){
34088
34089                //if the site is not just resizing and readjusting the slides
34090                if(!v.localIsResizing && v.xMovement!=='none'){
34091                    if($.isFunction( options.onSlideLeave )){
34092                        if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){
34093                            slideMoving = false;
34094                            return;
34095                        }
34096                    }
34097                }
34098            }
34099
34100            destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE);
34101
34102            if(!v.localIsResizing){
34103                stopMedia(v.prevSlide);
34104                lazyLoad(destiny);
34105            }
34106
34107            if(!options.loopHorizontal && options.controlArrows){
34108                //hidding it for the fist slide, showing for the rest
34109                section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0);
34110
34111                //hidding it for the last slide, showing for the rest
34112                section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child'));
34113            }
34114
34115            //only changing the URL if the slides are in the current section (not for resize re-adjusting)
34116            if(section.hasClass(ACTIVE) && !v.localIsResizing){
34117                setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex);
34118            }
34119
34120            performHorizontalMove(slides, v, true);
34121        }
34122
34123
34124        function afterSlideLoads(v){
34125            activeSlidesNavigation(v.slidesNav, v.slideIndex);
34126
34127            //if the site is not just resizing and readjusting the slides
34128            if(!v.localIsResizing){
34129                $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex);
34130
34131                //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally
34132                //and to prevent double scroll right after a windows resize
34133                canScroll = true;
34134
34135                playMedia(v.destiny);
34136            }
34137
34138            //letting them slide again
34139            slideMoving = false;
34140        }
34141
34142        /**
34143        * Performs the horizontal movement. (CSS3 or jQuery)
34144        *
34145        * @param fireCallback {Bool} - determines whether or not to fire the callback
34146        */
34147        function performHorizontalMove(slides, v, fireCallback){
34148            var destinyPos = v.destinyPos;
34149
34150            if(options.css3){
34151                var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)';
34152
34153                addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v);
34154
34155                afterSlideLoadsId = setTimeout(function(){
34156                    fireCallback && afterSlideLoads(v);
34157                }, options.scrollingSpeed, options.easing);
34158            }else{
34159                slides.animate({
34160                    scrollLeft : Math.round(destinyPos.left)
34161                }, options.scrollingSpeed, options.easing, function() {
34162
34163                    fireCallback && afterSlideLoads(v);
34164                });
34165            }
34166        }
34167
34168        /**
34169        * Sets the state for the horizontal bullet navigations.
34170        */
34171        function activeSlidesNavigation(slidesNav, slideIndex){
34172            slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE);
34173            slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE);
34174        }
34175
34176        var previousHeight = windowsHeight;
34177
34178        //when resizing the site, we adjust the heights of the sections, slimScroll...
34179        function resizeHandler(){
34180            //checking if it needs to get responsive
34181            responsive();
34182
34183            // rebuild immediately on touch devices
34184            if (isTouchDevice) {
34185                var activeElement = $(document.activeElement);
34186
34187                //if the keyboard is NOT visible
34188                if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) {
34189                    var currentHeight = $window.height();
34190
34191                    //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)
34192                    if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){
34193                        reBuild(true);
34194                        previousHeight = currentHeight;
34195                    }
34196                }
34197            }else{
34198                //in order to call the functions only when the resize is finished
34199                //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing
34200                clearTimeout(resizeId);
34201
34202                resizeId = setTimeout(function(){
34203                    reBuild(true);
34204                }, 350);
34205            }
34206        }
34207
34208        /**
34209        * Checks if the site needs to get responsive and disables autoScrolling if so.
34210        * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS.
34211        */
34212        function responsive(){
34213            var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity
34214            var heightLimit = options.responsiveHeight;
34215
34216            //only calculating what we need. Remember its called on the resize event.
34217            var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit;
34218            var isBreakingPointHeight = heightLimit && $window.height() < heightLimit;
34219
34220            if(widthLimit && heightLimit){
34221                setResponsive(isBreakingPointWidth || isBreakingPointHeight);
34222            }
34223            else if(widthLimit){
34224                setResponsive(isBreakingPointWidth);
34225            }
34226            else if(heightLimit){
34227                setResponsive(isBreakingPointHeight);
34228            }
34229        }
34230
34231        /**
34232        * Adds transition animations for the given element
34233        */
34234        function addAnimation(container, element){
34235            var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3;
34236
34237            container.removeClass(NO_TRANSITION);
34238            return container.css({
34239                '-webkit-transition': transition,
34240                'transition': transition
34241            });
34242        }
34243
34244        /**
34245        * Remove transition animations for the given element
34246        */
34247        function removeAnimation(element){
34248            return element.addClass(NO_TRANSITION);
34249        }
34250
34251        /**
34252        * Activating the vertical navigation bullets according to the given slide name.
34253        */
34254        function activateNavDots(name, sectionIndex){
34255            if(options.navigation){
34256                $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE);
34257                if(name){
34258                    $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE);
34259                }else{
34260                    $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE);
34261                }
34262            }
34263        }
34264
34265        /**
34266        * Activating the website main menu elements according to the given slide name.
34267        */
34268        function activateMenuElement(name){
34269            if(options.menu){
34270                $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE);
34271                $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE);
34272            }
34273        }
34274
34275        /**
34276        * Sets to active the current menu and vertical nav items.
34277        */
34278        function activateMenuAndNav(anchor, index){
34279            activateMenuElement(anchor);
34280            activateNavDots(anchor, index);
34281        }
34282
34283        /**
34284        * Retuns `up` or `down` depending on the scrolling movement to reach its destination
34285        * from the current section.
34286        */
34287        function getYmovement(destiny){
34288            var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL);
34289            var toIndex = destiny.index(SECTION_SEL);
34290            if( fromIndex == toIndex){
34291                return 'none';
34292            }
34293            if(fromIndex > toIndex){
34294                return 'up';
34295            }
34296            return 'down';
34297        }
34298
34299        /**
34300        * Retuns `right` or `left` depending on the scrolling movement to reach its destination
34301        * from the current slide.
34302        */
34303        function getXmovement(fromIndex, toIndex){
34304            if( fromIndex == toIndex){
34305                return 'none';
34306            }
34307            if(fromIndex > toIndex){
34308                return 'left';
34309            }
34310            return 'right';
34311        }
34312
34313        /**
34314        * Checks if the element needs scrollbar and if the user wants to apply it.
34315        * If so it creates it.
34316        *
34317        * @param {Object} element   jQuery object of the section or slide
34318        */
34319        function createScrollBar(element){
34320            //User doesn't want scrollbar here? Sayonara baby!
34321            if(element.hasClass('fp-noscroll')) return;
34322
34323            //needed to make `scrollHeight` work under Opera 12
34324            element.css('overflow', 'hidden');
34325
34326            var scrollOverflowHandler = options.scrollOverflowHandler;
34327            var wrap = scrollOverflowHandler.wrapContent();
34328            //in case element is a slide
34329            var section = element.closest(SECTION_SEL);
34330            var scrollable = scrollOverflowHandler.scrollable(element);
34331            var contentHeight;
34332
34333            //if there was scroll, the contentHeight will be the one in the scrollable section
34334            if(scrollable.length){
34335                contentHeight = scrollOverflowHandler.scrollHeight(element);
34336            }else{
34337                contentHeight = element.get(0).scrollHeight;
34338                if(options.verticalCentered){
34339                    contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight;
34340                }
34341            }
34342
34343            var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top'));
34344
34345            //needs scroll?
34346            if ( contentHeight > scrollHeight) {
34347                //did we already have an scrollbar ? Updating it
34348                if(scrollable.length){
34349                    scrollOverflowHandler.update(element, scrollHeight);
34350                }
34351                //creating the scrolling
34352                else{
34353                    if(options.verticalCentered){
34354                        element.find(TABLE_CELL_SEL).wrapInner(wrap);
34355                    }else{
34356                        element.wrapInner(wrap);
34357                    }
34358                    scrollOverflowHandler.create(element, scrollHeight);
34359                }
34360            }
34361            //removing the scrolling when it is not necessary anymore
34362            else{
34363                scrollOverflowHandler.remove(element);
34364            }
34365
34366            //undo
34367            element.css('overflow', '');
34368        }
34369
34370        function addTableClass(element){
34371            //In case we are styling for the 2nd time as in with reponsiveSlides
34372            if(!element.hasClass(TABLE)){
34373                element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />');
34374            }
34375        }
34376
34377        function getTableHeight(element){
34378            var sectionHeight = windowsHeight;
34379
34380            if(options.paddingTop || options.paddingBottom){
34381                var section = element;
34382                if(!section.hasClass(SECTION)){
34383                    section = element.closest(SECTION_SEL);
34384                }
34385
34386                var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom'));
34387                sectionHeight = (windowsHeight - paddings);
34388            }
34389
34390            return sectionHeight;
34391        }
34392
34393        /**
34394        * Adds a css3 transform property to the container class with or without animation depending on the animated param.
34395        */
34396        function transformContainer(translate3d, animated){
34397            if(animated){
34398                addAnimation(container);
34399            }else{
34400                removeAnimation(container);
34401            }
34402
34403            container.css(getTransforms(translate3d));
34404
34405            //syncronously removing the class after the animation has been applied.
34406            setTimeout(function(){
34407                container.removeClass(NO_TRANSITION);
34408            },10);
34409        }
34410
34411        /**
34412        * Gets a section by its anchor / index
34413        */
34414        function getSectionByAnchor(sectionAnchor){
34415            if(!sectionAnchor) return [];
34416
34417            var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]');
34418            if(!section.length){
34419                section = $(SECTION_SEL).eq( sectionAnchor -1);
34420            }
34421
34422            return section;
34423        }
34424
34425        /**
34426        * Gets a slide inside a given section by its anchor / index
34427        */
34428        function getSlideByAnchor(slideAnchor, section){
34429            var slides = section.find(SLIDES_WRAPPER_SEL);
34430            var slide =  slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]');
34431
34432            if(!slide.length){
34433                slide = slides.find(SLIDE_SEL).eq(slideAnchor);
34434            }
34435
34436            return slide;
34437        }
34438
34439        /**
34440        * Scrolls to the given section and slide anchors
34441        */
34442        function scrollPageAndSlide(destiny, slide){
34443            var section = getSectionByAnchor(destiny);
34444
34445            //do nothing if there's no section with the given anchor name
34446            if(!section.length) return;
34447
34448            //default slide
34449            if (typeof slide === 'undefined') {
34450                slide = 0;
34451            }
34452
34453            //we need to scroll to the section and then to the slide
34454            if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){
34455                scrollPage(section, function(){
34456                    scrollSlider(section, slide);
34457                });
34458            }
34459            //if we were already in the section
34460            else{
34461                scrollSlider(section, slide);
34462            }
34463        }
34464
34465        /**
34466        * Scrolls the slider to the given slide destination for the given section
34467        */
34468        function scrollSlider(section, slideAnchor){
34469            if(typeof slideAnchor !== 'undefined'){
34470                var slides = section.find(SLIDES_WRAPPER_SEL);
34471                var destiny =  getSlideByAnchor(slideAnchor, section);
34472
34473                if(destiny.length){
34474                    landscapeScroll(slides, destiny);
34475                }
34476            }
34477        }
34478
34479        /**
34480        * Creates a landscape navigation bar with dots for horizontal sliders.
34481        */
34482        function addSlidesNavigation(section, numSlides){
34483            section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>');
34484            var nav = section.find(SLIDES_NAV_SEL);
34485
34486            //top or bottom
34487            nav.addClass(options.slidesNavPosition);
34488
34489            for(var i=0; i< numSlides; i++){
34490                nav.find('ul').append('<li><a href="#"><span></span></a></li>');
34491            }
34492
34493            //centering it
34494            nav.css('margin-left', '-' + (nav.width()/2) + 'px');
34495
34496            nav.find('li').first().find('a').addClass(ACTIVE);
34497        }
34498
34499
34500        /**
34501        * Sets the state of the website depending on the active section/slide.
34502        * It changes the URL hash when needed and updates the body class.
34503        */
34504        function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){
34505            var sectionHash = '';
34506
34507            if(options.anchors.length && !options.lockAnchors){
34508
34509                //isn't it the first slide?
34510                if(slideIndex){
34511                    if(typeof anchorLink !== 'undefined'){
34512                        sectionHash = anchorLink;
34513                    }
34514
34515                    //slide without anchor link? We take the index instead.
34516                    if(typeof slideAnchor === 'undefined'){
34517                        slideAnchor = slideIndex;
34518                    }
34519
34520                    lastScrolledSlide = slideAnchor;
34521                    setUrlHash(sectionHash + '/' + slideAnchor);
34522
34523                //first slide won't have slide anchor, just the section one
34524                }else if(typeof slideIndex !== 'undefined'){
34525                    lastScrolledSlide = slideAnchor;
34526                    setUrlHash(anchorLink);
34527                }
34528
34529                //section without slides
34530                else{
34531                    setUrlHash(anchorLink);
34532                }
34533            }
34534
34535            setBodyClass();
34536        }
34537
34538        /**
34539        * Sets the URL hash.
34540        */
34541        function setUrlHash(url){
34542            //Uncode addition
34543            if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer )
34544                return false;
34545
34546            if(options.recordHistory){
34547                location.hash = url;
34548            }else{
34549                //Uncode addition
34550                //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :)
34551                // if(isTouchDevice || isTouch){
34552                //     window.history.replaceState(undefined, undefined, '#' + url);
34553                // }else{
34554                //     var baseUrl = window.location.href.split('#')[0];
34555                //     window.location.replace( baseUrl + '#' + url );
34556                // }
34557                return false;
34558            }
34559        }
34560
34561        /**
34562        * Gets the anchor for the given slide / section. Its index will be used if there's none.
34563        */
34564        function getAnchor(element){
34565            var anchor = element.data('anchor');
34566            var index = element.index();
34567
34568            //Slide without anchor link? We take the index instead.
34569            if(typeof anchor === 'undefined'){
34570                anchor = index;
34571            }
34572
34573            return anchor;
34574        }
34575
34576        /**
34577        * Sets a class for the body of the page depending on the active section / slide
34578        */
34579        function setBodyClass(){
34580            var section = $(SECTION_ACTIVE_SEL);
34581            var slide = section.find(SLIDE_ACTIVE_SEL);
34582
34583            var sectionAnchor = getAnchor(section);
34584            var slideAnchor = getAnchor(slide);
34585
34586            var text = String(sectionAnchor);
34587
34588            if(slide.length){
34589                text = text + '-' + slideAnchor;
34590            }
34591
34592            //changing slash for dash to make it a valid CSS style
34593            text = text.replace('/', '-').replace('#','');
34594
34595            //removing previous anchor classes
34596            var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g");
34597            $body[0].className = $body[0].className.replace(classRe, '');
34598
34599            //adding the current anchor
34600            $body.addClass(VIEWING_PREFIX + '-' + text);
34601        }
34602
34603        /**
34604        * Checks for translate3d support
34605        * @return boolean
34606        * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support
34607        */
34608        function support3d() {
34609            var el = document.createElement('p'),
34610                has3d,
34611                transforms = {
34612                    'webkitTransform':'-webkit-transform',
34613                    'OTransform':'-o-transform',
34614                    'msTransform':'-ms-transform',
34615                    'MozTransform':'-moz-transform',
34616                    'transform':'transform'
34617                };
34618
34619            // Add it to the body to get the computed style.
34620            document.body.insertBefore(el, null);
34621
34622            for (var t in transforms) {
34623                if (el.style[t] !== undefined) {
34624                    el.style[t] = 'translate3d(1px,1px,1px)';
34625                    has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
34626                }
34627            }
34628
34629            document.body.removeChild(el);
34630
34631            return (has3d !== undefined && has3d.length > 0 && has3d !== 'none');
34632        }
34633
34634        /**
34635        * Removes the auto scrolling action fired by the mouse wheel and trackpad.
34636        * After this function is called, the mousewheel and trackpad movements won't scroll through sections.
34637        */
34638        function removeMouseWheelHandler(){
34639            if (document.addEventListener) {
34640                document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper
34641                document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox
34642                document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox
34643            } else {
34644                document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8
34645            }
34646        }
34647
34648        /**
34649        * Adds the auto scrolling action for the mouse wheel and trackpad.
34650        * After this function is called, the mousewheel and trackpad movements will scroll through sections
34651        * https://developer.mozilla.org/en-US/docs/Web/Events/wheel
34652        */
34653        function addMouseWheelHandler(){
34654            var prefix = '';
34655            var _addEventListener;
34656
34657            if (window.addEventListener){
34658                _addEventListener = "addEventListener";
34659            }else{
34660                _addEventListener = "attachEvent";
34661                prefix = 'on';
34662            }
34663
34664             // detect available wheel event
34665            var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel"
34666                      document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel"
34667                      'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox
34668            var passiveEvent = g_supportsPassive ? {passive: false }
34668: false;
34669
34670
34671            if(support == 'DOMMouseScroll'){
34672                document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent);
34673            }
34674
34675            //handle MozMousePixelScroll in older Firefox
34676            else{
34677                document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent);
34678            }
34679        }
34680
34681        /**
34682        * Binding the mousemove when the mouse's middle button is pressed
34683        */
34684        function addMiddleWheelHandler(){
34685            container
34686                .on('mousedown', mouseDownHandler)
34687                .on('mouseup', mouseUpHandler);
34688        }
34689
34690        /**
34691        * Unbinding the mousemove when the mouse's middle button is released
34692        */
34693        function removeMiddleWheelHandler(){
34694            container
34695                .off('mousedown', mouseDownHandler)
34696                .off('mouseup', mouseUpHandler);
34697        }
34698
34699        /**
34700        * Adds the possibility to auto scroll through sections on touch devices.
34701        */
34702        function addTouchHandler(){
34703            if(isTouchDevice || isTouch){
34704                if(options.autoScrolling){
34705                    $body.off(events.touchmove).on(events.touchmove, preventBouncing);
34706                }
34707
34708                $(WRAPPER_SEL)
34709                    .off(events.touchstart).on(events.touchstart, touchStartHandler)
34710                    .off(events.touchmove).on(events.touchmove, touchMoveHandler);
34711            }
34712        }
34713
34714        /**
34715        * Removes the auto scrolling for touch devices.
34716        */
34717        function removeTouchHandler(){
34718            if(isTouchDevice || isTouch){
34719                $(WRAPPER_SEL)
34720                    .off(events.touchstart)
34721                    .off(events.touchmove);
34722            }
34723        }
34724
34725        /*
34726        * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11)
34727        * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx
34728        */
34729        function getMSPointer(){
34730            var pointer;
34731
34732            //IE >= 11 & rest of browsers
34733            if(window.PointerEvent){
34734                pointer = { down: 'pointerdown', move: 'pointermove'};
34735            }
34736
34737            //IE < 11
34738            else{
34739                pointer = { down: 'MSPointerDown', move: 'MSPointerMove'};
34740            }
34741
34742            return pointer;
34743        }
34744
34745        /**
34746        * Gets the pageX and pageY properties depending on the browser.
34747        * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854
34748        */
34749        function getEventsPage(e){
34750            var events = [];
34751
34752            events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY);
34753            events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX);
34754
34755            //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008
34756            if(isTouch && isReallyTouch(e) && options.scrollBar){
34757                events.y = e.touches[0].pageY;
34758                events.x = e.touches[0].pageX;
34759            }
34760
34761            return events;
34762        }
34763
34764        /**
34765        * Slides silently (with no animation) the active slider to the given slide.
34766        * @param noCallback {bool} true or defined -> no callbacks
34767        */
34768        function silentLandscapeScroll(activeSlide, noCallbacks){
34769            setScrollingSpeed (0, 'internal');
34770
34771            if(typeof noCallbacks !== 'undefined'){
34772                //preventing firing callbacks afterSlideLoad etc.
34773                isResizing = true;
34774            }
34775
34776            landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide);
34777
34778            if(typeof noCallbacks !== 'undefined'){
34779                isResizing = false;
34780            }
34781
34782            setScrollingSpeed(originals.scrollingSpeed, 'internal');
34783        }
34784
34785        /**
34786        * Scrolls silently (with no animation) the page to the given Y position.
34787        */
34788        function silentScroll(top){
34789            // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
34790            // that's why we round it to 0.
34791            var roundedTop = Math.round(top);
34792
34793            if (options.css3 && options.autoScrolling && !options.scrollBar){
34794                var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)';
34795                transformContainer(translate3d, false);
34796            }
34797            else if(options.autoScrolling && !options.scrollBar){
34798                container.css('top', -roundedTop);
34799            }
34800            else{
34801                $htmlBody.scrollTop(roundedTop);
34802            }
34803        }
34804
34805        /**
34806        * Returns the cross-browser transform string.
34807        */
34808        function getTransforms(translate3d){
34809            return {
34810                '-webkit-transform': translate3d,
34811                '-moz-transform': translate3d,
34812                '-ms-transform':translate3d,
34813                'transform': translate3d
34814            };
34815        }
34816
34817        /**
34818        * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard)
34819        * @type  m (mouse) or k (keyboard)
34820        */
34821        function setIsScrollAllowed(value, direction, type){
34822            switch (direction){
34823                case 'up': isScrollAllowed[type].up = value; break;
34824                case 'down': isScrollAllowed[type].down = value; break;
34825                case 'left': isScrollAllowed[type].left = value; break;
34826                case 'right': isScrollAllowed[type].right = value; break;
34827                case 'all':
34828                    if(type == 'm'){
34829                        setAllowScrolling(value);
34830                    }else{
34831                        setKeyboardScrolling(value);
34832                    }
34833            }
34834        }
34835
34836        /*
34837        * Destroys fullpage.js plugin events and optinally its html markup and styles
34838        */
34839        function destroy(all){
34840            setAutoScrolling(false, 'internal');
34841            setAllowScrolling(false);
34842            setKeyboardScrolling(false);
34843            container.addClass(DESTROYED);
34844
34845            clearTimeout(afterSlideLoadsId);
34846            clearTimeout(afterSectionLoadsId);
34847            clearTimeout(resizeId);
34848            clearTimeout(scrollId);
34849            clearTimeout(scrollId2);
34850
34851            $window
34852                .off('scroll', scrollHandler)
34853                .off('hashchange', hashChangeHandler)
34854                .off('resize', resizeHandler);
34855
34856            $document
34857                .off('click touchstart', SECTION_NAV_SEL + ' a')
34858                .off('mouseenter', SECTION_NAV_SEL + ' li')
34859                .off('mouseleave', SECTION_NAV_SEL + ' li')
34860                .off('click touchstart', SLIDES_NAV_LINK_SEL)
34861                .off('mouseover', options.normalScrollElements)
34862                .off('mouseout', options.normalScrollElements);
34863
34864            $(SECTION_SEL)
34865                .off('click touchstart', SLIDES_ARROW_SEL);
34866
34867            clearTimeout(afterSlideLoadsId);
34868            clearTimeout(afterSectionLoadsId);
34869
34870            //lets make a mess!
34871            if(all){
34872                destroyStructure();
34873            }
34874        }
34875
34876        /*
34877        * Removes inline styles added by fullpage.js
34878        */
34879        function destroyStructure(){
34880            //reseting the `top` or `translate` properties to 0
34881            silentScroll(0);
34882
34883            //loading all the lazy load content
34884            container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){
34885                setSrc($(this), 'src');
34886            });
34887
34888            container.find('img[data-srcset]').each(function(){
34889                setSrc($(this), 'srcset');
34890            });
34891
34892            $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL +  ', ' + SLIDES_ARROW_SEL).remove();
34893
34894            //removing inline styles
34895            $(SECTION_SEL).css( {
34896                'height': '',
34897                'background-color' : '',
34898                'padding': ''
34899            });
34900
34901            $(SLIDE_SEL).css( {
34902                'width': ''
34903            });
34904
34905            container.css({
34906                'height': '',
34907                'position': '',
34908                '-ms-touch-action': '',
34909                'touch-action': ''
34910            });
34911
34912            $htmlBody.css({
34913                'overflow': '',
34914                'height': ''
34915            });
34916
34917            // remove .fp-enabled class
34918            $('html').removeClass(ENABLED);
34919
34920            // remove .fp-responsive class
34921            $body.removeClass(RESPONSIVE);
34922
34923            // remove all of the .fp-viewing- classes
34924            $.each($body.get(0).className.split(/\s+/), function (index, className) {
34925                if (className.indexOf(VIEWING_PREFIX) === 0) {
34926                    $body.removeClass(className);
34927                }
34928            });
34929
34930            //removing added classes
34931            $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){
34932                options.scrollOverflowHandler.remove($(this));
34933                $(this).removeClass(TABLE + ' ' + ACTIVE);
34934            });
34935
34936            removeAnimation(container);
34937
34938            //Unwrapping content
34939            container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){
34940                //unwrap not being use in case there's no child element inside and its just text
34941                $(this).replaceWith(this.childNodes);
34942            });
34943
34944            //removing the applied transition from the fullpage wrapper
34945            container.css({
34946                '-webkit-transition': 'none',
34947                'transition': 'none'
34948            });
34949
34950            //scrolling the page to the top with no animation
34951            $htmlBody.scrollTop(0);
34952
34953            //removing selectors
34954            var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER];
34955            $.each(usedSelectors, function(index, value){
34956                $('.' + value).removeClass(value);
34957            });
34958        }
34959
34960        /*
34961        * Sets the state for a variable with multiple states (original, and temporal)
34962        * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`.
34963        * This function is used to keep track of both states, the original and the temporal one.
34964        * If type is not 'internal', then we assume the user is globally changing the variable.
34965        */
34966        function setVariableState(variable, value, type){
34967            options[variable] = value;
34968            if(type !== 'internal'){
34969                originals[variable] = value;
34970            }
34971        }
34972
34973        /**
34974        * Displays warnings
34975        */
34976        function displayWarnings(){
34977            var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax'];
34978            //UNCODE.addition
34979            // if($('html').hasClass(ENABLED)){
34980            //     showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!');
34981            //     return;
34982            // }
34983
34984            // Disable mutually exclusive settings
34985            //UNCODE.addition
34986            // if (options.continuousVertical &&
34987            //     (options.loopTop || options.loopBottom)) {
34988            //     options.continuousVertical = false;
34989            //     showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
34990            // }
34991
34992            // if(options.scrollBar && options.scrollOverflow){
34993            //     showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox');
34994            // }
34995
34996            // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){
34997            //     options.continuousVertical = false;
34998            //     showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
34999            // }
35000
35001            //using extensions? Wrong file!
35002            $.each(extensions, function(index, extension){
35003                //is the option set to true?
35004                if(options[extension]){
35005                    showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension);
35006                }
35007            });
35008
35009            //anchors can not have the same value as any element ID or NAME
35010            $.each(options.anchors, function(index, name){
35011
35012                //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396)
35013                var nameAttr = $document.find('[name]').filter(function() {
35014                    return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase();
35015                });
35016
35017                var idAttr = $document.find('[id]').filter(function() {
35018                    return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase();
35019                });
35020
35021                if(idAttr.length || nameAttr.length ){
35022                    showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).');
35023                    idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property');
35024                    nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property');
35025                }
35026            });
35027        }
35028
35029        /**
35030        * Shows a message in the console of the given type.
35031        */
35032        function showError(type, text){
35033            console && console[type] && console[type]('fullPage: ' + text);
35034        }
35035
35036    }; //end of $.fn.fullpage
35037
35038    if(typeof IScroll !== 'undefined'){
35039        /*
35040        * Turns iScroll `mousewheel` option off dynamically
35041        * https://github.com/cubiq/iscroll/issues/1036
35042        */
35043        IScroll.prototype.wheelOn = function () {
35044            this.wrapper.addEventListener('wheel', this);
35045            this.wrapper.addEventListener('mousewheel', this);
35046            this.wrapper.addEventListener('DOMMouseScroll', this);
35047        };
35048
35049        /*
35050        * Turns iScroll `mousewheel` option on dynamically
35051        * https://github.com/cubiq/iscroll/issues/1036
35052        */
35053        IScroll.prototype.wheelOff = function () {
35054            this.wrapper.removeEventListener('wheel', this);
35055            this.wrapper.removeEventListener('mousewheel', this);
35056            this.wrapper.removeEventListener('DOMMouseScroll', this);
35057        };
35058    }
35059
35060    /**
35061     * An object to handle overflow scrolling.
35062     * This uses jquery.slimScroll to accomplish overflow scrolling.
35063     * It is possible to pass in an alternate scrollOverflowHandler
35064     * to the fullpage.js option that implements the same functions
35065     * as this handler.
35066     *
35067     * @type {Object}
35068     */
35069    var iscrollHandler = {
35070        refreshId: null,
35071        iScrollInstances: [],
35072
35073        // Enables or disables the mouse wheel for the active section or all slides in it
35074        toggleWheel: function(value){
35075            var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL);
35076            scrollable.each(function(){
35077                var iScrollInstance = $(this).data('iscrollInstance');
35078                if(typeof iScrollInstance !== 'undefined' && iScrollInstance){
35079                    if(value){
35080                        iScrollInstance.wheelOn();
35081                    }
35082                    else{
35083                        iScrollInstance.wheelOff();
35084                    }
35085                }
35086            });
35087        },
35088
35089        /**
35090        * Turns off iScroll for the destination section.
35091        * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
35092        * scroll the destination section/slide before the sections animations ends.
35093        */
35094        onLeave: function(){
35095            iscrollHandler.toggleWheel(false);
35096        },
35097
35098        // Turns off iScroll for the leaving section
35099        beforeLeave: function(){
35100            iscrollHandler.onLeave()
35101        },
35102
35103        // Turns on iScroll on section load
35104        afterLoad: function(){
35105            iscrollHandler.toggleWheel(true);
35106        },
35107
35108        /**
35109         * Called when overflow scrolling is needed for a section.
35110         *
35111         * @param  {Object} element      jQuery object containing current section
35112         * @param  {Number} scrollHeight Current window height in pixels
35113         */
35114        create: function(element, scrollHeight) {
35115            var scrollable = element.find(SCROLLABLE_SEL);
35116
35117            scrollable.height(scrollHeight);
35118            scrollable.each(function() {
35119                var $this = $(this);
35120                var iScrollInstance = $this.data('iscrollInstance');
35121                if (iScrollInstance) {
35122                    $.each(iscrollHandler.iScrollInstances, function(){
35123                        $(this).destroy();
35124                    });
35125                }
35126
35127                iScrollInstance = new IScroll($this.get(0), iscrollOptions);
35128                iscrollHandler.iScrollInstances.push(iScrollInstance);
35129
35130                //off by default until the section gets active
35131                iScrollInstance.wheelOff();
35132
35133                $this.data('iscrollInstance', iScrollInstance);
35134            });
35135        },
35136
35137        /**
35138         * Return a boolean depending on whether the scrollable element is a
35139         * the end or at the start of the scrolling depending on the given type.
35140         *
35141         * @param  {String}  type       Either 'top' or 'bottom'
35142         * @param  {Object}  scrollable jQuery object for the scrollable element
35143         * @return {Boolean}
35144         */
35145        isScrolled: function(type, scrollable) {
35146            var scroller = scrollable.data('iscrollInstance');
35147
35148            //no scroller?
35149            if (!scroller) {
35150                return true;
35151            }
35152
35153            //Uncode addition
35154            var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0;
35155            //End Uncode addition
35156
35157            if (type === 'top') {
35158                return scroller.y >= 0 && !scrollable.scrollTop();
35159            } else if (type === 'bottom') {
35160                //Uncode change
35161                // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight;
35162                return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight;
35163                //End Uncode change
35164            }
35165        },
35166
35167        /**
35168         * Returns the scrollable element for the given section.
35169         * If there are landscape slides, will only return a scrollable element
35170         * if it is in the active slide.
35171         *
35172         * @param  {Object}  activeSection jQuery object containing current section
35173         * @return {Boolean}
35174         */
35175        scrollable: function(activeSection){
35176            // if there are landscape slides, we check if the scrolling bar is in the current one or not
35177            if (activeSection.find(SLIDES_WRAPPER_SEL).length) {
35178                return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL);
35179            }
35180            return activeSection.find(SCROLLABLE_SEL);
35181        },
35182
35183        /**
35184         * Returns the scroll height of the wrapped content.
35185         * If this is larger than the window height minus section padding,
35186         * overflow scrolling is needed.
35187         *
35188         * @param  {Object} element jQuery object containing current section
35189         * @return {Number}
35190         */
35191        scrollHeight: function(element) {
35192            return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight;
35193        },
35194
35195        /**
35196         * Called when overflow scrolling is no longer needed for a section.
35197         *
35198         * @param  {Object}
vendor: 5,435 bytes, lines 35198-35349
35198 element      jQuery object containing current section
35199         */
35200        remove: function(element) {
35201            var scrollable = element.find(SCROLLABLE_SEL);
35202            if (scrollable.length) {
35203                var iScrollInstance = scrollable.data('iscrollInstance');
35204                iScrollInstance.destroy();
35205
35206                scrollable.data('iscrollInstance', null);
35207            }
35208            element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap();
35209        },
35210
35211        /**
35212         * Called when overflow scrolling has already been setup but the
35213         * window height has potentially changed.
35214         *
35215         * @param  {Object} element      jQuery object containing current section
35216         * @param  {Number} scrollHeight Current window height in pixels
35217         */
35218        update: function(element, scrollHeight) {
35219            //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a
35220            //short period of time.
35221            //it also comes on handy because iScroll requires the use of timeout when using `refresh`.
35222            clearTimeout(iscrollHandler.refreshId);
35223            iscrollHandler.refreshId = setTimeout(function(){
35224                $.each(iscrollHandler.iScrollInstances, function(){
35225                    $(this).get(0).refresh();
35226                });
35227            }, 150);
35228
35229            //updating the wrappers height
35230            element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px');
35231        },
35232
35233        /**
35234         * Called to get any additional elements needed to wrap the section
35235         * content in order to facilitate overflow scrolling.
35236         *
35237         * @return {String|Object} Can be a string containing HTML,
35238         *                         a DOM element, or jQuery object.
35239         */
35240        wrapContent: function() {
35241            return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>';
35242        }
35243    };
35244});
35245
35246(function (global, factory) {
35247	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
35248	typeof define === 'function' && define.amd ? define(['exports'], factory) :
35249	(global = global || self, factory(global.window = global.window || {}));
35250  }(this, (function (exports) { 'use strict';
35251  
35252	function _defineProperties(target, props) {
35253	  for (var i = 0; i < props.length; i++) {
35254		var descriptor = props[i];
35255		descriptor.enumerable = descriptor.enumerable || false;
35256		descriptor.configurable = true;
35257		if ("value" in descriptor) descriptor.writable = true;
35258		Object.defineProperty(target, descriptor.key, descriptor);
35259	  }
35260	}
35261  
35262	function _createClass(Constructor, protoProps, staticProps) {
35263	  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
35264	  if (staticProps) _defineProperties(Constructor, staticProps);
35265	  return Constructor;
35266	}
35267  
35268	/*!
35269	 * Observer 3.12.5
35270	 * https://gsap.com
35271	 *
35272	 * @license Copyright 2008-2024, GreenSock. All rights reserved.
35273	 * Subject to the terms at https://gsap.com/standard-license or for
35274	 * Club GSAP members, the agreement issued with that membership.
35275	 * @author: Jack Doyle, [email protected]
35276	*/
35277	var gsap,
35278		_coreInitted,
35279		_clamp,
35280		_win,
35281		_doc,
35282		_docEl,
35283		_body,
35284		_isTouch,
35285		_pointerType,
35286		ScrollTrigger,
35287		_root,
35288		_normalizer,
35289		_eventTypes,
35290		_context,
35291		_getGSAP = function _getGSAP() {
35292	  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;
35293	},
35294		_startup = 1,
35295		_observers = [],
35296		_scrollers = [],
35297		_proxies = [],
35298		_getTime = Date.now,
35299		_bridge = function _bridge(name, value) {
35300	  return value;
35301	},
35302		_integrate = function _integrate() {
35303	  var core = ScrollTrigger.core,
35304		  data = core.bridge || {},
35305		  scrollers = core._scrollers,
35306		  proxies = core._proxies;
35307	  scrollers.push.apply(scrollers, _scrollers);
35308	  proxies.push.apply(proxies, _proxies);
35309	  _scrollers = scrollers;
35310	  _proxies = proxies;
35311  
35312	  _bridge = function _bridge(name, value) {
35313		return data[name](value);
35314	  };
35315	},
35316		_getProxyProp = function _getProxyProp(element, property) {
35317	  return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property];
35318	},
35319		_isViewport = function _isViewport(el) {
35320	  return !!~_root.indexOf(el);
35321	},
35322		_addListener = function _addListener(element, type, func, passive, capture) {
35323	  return element.addEventListener(type, func, {
35324		passive: passive !== false,
35325		capture: !!capture
35326	  });
35327	},
35328		_removeListener = function _removeListener(element, type, func, capture) {
35329	  return element.removeEventListener(type, func, !!capture);
35330	},
35331		_scrollLeft = "scrollLeft",
35332		_scrollTop = "scrollTop",
35333		_onScroll = function _onScroll() {
35334	  return _normalizer && _normalizer.isPressed || _scrollers.cache++;
35335	},
35336		_scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) {
35337	  var cachingFunc = function cachingFunc(value) {
35338		if (value || value === 0) {
35339		  _startup && (_win.history.scrollRestoration = "manual");
35340		  var isNormalizing = _normalizer && _normalizer.isPressed;
35341		  value = cachingFunc.v = Math.round(value) || (_normalizer && _normalizer.iOS ? 1 : 0);
35342		  f(value);
35343		  cachingFunc.cacheID = _scrollers.cache;
35344		  isNormalizing && _bridge("ss", value);
35345		} else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge("ref")) {
35346		  cachingFunc.cacheID = _scrollers.cache;
35347		  cachingFunc.v = f();
35348		}
35349  
vendor: 4,462 bytes, lines 35350-35486
35350		return cachingFunc.v + cachingFunc.offset;
35351	  };
35352  
35353	  cachingFunc.offset = 0;
35354	  return f && cachingFunc;
35355	},
35356		_horizontal = {
35357	  s: _scrollLeft,
35358	  p: "left",
35359	  p2: "Left",
35360	  os: "right",
35361	  os2: "Right",
35362	  d: "width",
35363	  d2: "Width",
35364	  a: "x",
35365	  sc: _scrollCacheFunc(function (value) {
35366		return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0;
35367	  })
35368	},
35369		_vertical = {
35370	  s: _scrollTop,
35371	  p: "top",
35372	  p2: "Top",
35373	  os: "bottom",
35374	  os2: "Bottom",
35375	  d: "height",
35376	  d2: "Height",
35377	  a: "y",
35378	  op: _horizontal,
35379	  sc: _scrollCacheFunc(function (value) {
35380		return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0;
35381	  })
35382	},
35383		_getTarget = function _getTarget(t, self) {
35384	  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);
35385	},
35386		_getScrollFunc = function _getScrollFunc(element, _ref) {
35387	  var s = _ref.s,
35388		  sc = _ref.sc;
35389	  _isViewport(element) && (element = _doc.scrollingElement || _docEl);
35390  
35391	  var i = _scrollers.indexOf(element),
35392		  offset = sc === _vertical.sc ? 1 : 2;
35393  
35394	  !~i && (i = _scrollers.push(element) - 1);
35395	  _scrollers[i + offset] || _addListener(element, "scroll", _onScroll);
35396	  var prev = _scrollers[i + offset],
35397		  func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) {
35398		return arguments.length ? element[s] = value : element[s];
35399	  })));
35400	  func.target = element;
35401	  prev || (func.smooth = gsap.getProperty(element, "scrollBehavior") === "smooth");
35402	  return func;
35403	},
35404		_getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) {
35405	  var v1 = value,
35406		  v2 = value,
35407		  t1 = _getTime(),
35408		  t2 = t1,
35409		  min = minTimeRefresh || 50,
35410		  dropToZeroTime = Math.max(500, min * 3),
35411		  update = function update(value, force) {
35412		var t = _getTime();
35413  
35414		if (force || t - t1 > min) {
35415		  v2 = v1;
35416		  v1 = value;
35417		  t2 = t1;
35418		  t1 = t;
35419		} else if (useDelta) {
35420		  v1 += value;
35421		} else {
35422		  v1 = v2 + (value - v2) / (t - t2) * (t1 - t2);
35423		}
35424	  },
35425		  reset = function reset() {
35426		v2 = v1 = useDelta ? 0 : v1;
35427		t2 = t1 = 0;
35428	  },
35429		  getVelocity = function getVelocity(latestValue) {
35430		var tOld = t2,
35431			vOld = v2,
35432			t = _getTime();
35433  
35434		(latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue);
35435		return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000;
35436	  };
35437  
35438	  return {
35439		update: update,
35440		reset: reset,
35441		getVelocity: getVelocity
35442	  };
35443	},
35444		_getEvent = function _getEvent(e, preventDefault) {
35445	  preventDefault && !e._gsapAllow && e.preventDefault();
35446	  return e.changedTouches ? e.changedTouches[0] : e;
35447	},
35448		_getAbsoluteMax = function _getAbsoluteMax(a) {
35449	  var max = Math.max.apply(Math, a),
35450		  min = Math.min.apply(Math, a);
35451	  return Math.abs(max) >= Math.abs(min) ? max : min;
35452	},
35453		_setScrollTrigger = function _setScrollTrigger() {
35454	  ScrollTrigger = gsap.core.globals().ScrollTrigger;
35455	  ScrollTrigger && ScrollTrigger.core && _integrate();
35456	},
35457		_initCore = function _initCore(core) {
35458	  gsap = core || _getGSAP();
35459  
35460	  if (!_coreInitted && gsap && typeof document !== "undefined" && document.body) {
35461		_win = window;
35462		_doc = document;
35463		_docEl = _doc.documentElement;
35464		_body = _doc.body;
35465		_root = [_win, _doc, _docEl, _body];
35466		_clamp = gsap.utils.clamp;
35467  
35468		_context = gsap.core.context || function () {};
35469  
35470		_pointerType = "onpointerenter" in _body ? "pointer" : "mouse";
35471		_isTouch = Observer.isTouch = _win.matchMedia && _win.matchMedia("(hover: none), (pointer: coarse)").matches ? 1 : "ontouchstart" in _win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0;
35472		_eventTypes = Observer.eventTypes = ("ontouchstart" in _docEl ? "touchstart,touchmove,touchcancel,touchend" : !("onpointerdown" in _docEl) ? "mousedown,mousemove,mouseup,mouseup" : "pointerdown,pointermove,pointercancel,pointerup").split(",");
35473		setTimeout(function () {
35474		  return _startup = 0;
35475		}, 500);
35476  
35477		_setScrollTrigger();
35478  
35479		_coreInitted = 1;
35480	  }
35481  
35482	  return _coreInitted;
35483	};
35484  
35485	_horizontal.op = _vertical;
35486	_scrollers.cache = 0;
vendor: 9,292 bytes, lines 35487-35803
35487	var Observer = function () {
35488	  function Observer(vars) {
35489		this.init(vars);
35490	  }
35491  
35492	  var _proto = Observer.prototype;
35493  
35494	  _proto.init = function init(vars) {
35495		_coreInitted || _initCore(gsap) || console.warn("Please gsap.registerPlugin(Observer)");
35496		ScrollTrigger || _setScrollTrigger();
35497		var tolerance = vars.tolerance,
35498			dragMinimum = vars.dragMinimum,
35499			type = vars.type,
35500			target = vars.target,
35501			lineHeight = vars.lineHeight,
35502			debounce = vars.debounce,
35503			preventDefault = vars.preventDefault,
35504			onStop = vars.onStop,
35505			onStopDelay = vars.onStopDelay,
35506			ignore = vars.ignore,
35507			wheelSpeed = vars.wheelSpeed,
35508			event = vars.event,
35509			onDragStart = vars.onDragStart,
35510			onDragEnd = vars.onDragEnd,
35511			onDrag = vars.onDrag,
35512			onPress = vars.onPress,
35513			onRelease = vars.onRelease,
35514			onRight = vars.onRight,
35515			onLeft = vars.onLeft,
35516			onUp = vars.onUp,
35517			onDown = vars.onDown,
35518			onChangeX = vars.onChangeX,
35519			onChangeY = vars.onChangeY,
35520			onChange = vars.onChange,
35521			onToggleX = vars.onToggleX,
35522			onToggleY = vars.onToggleY,
35523			onHover = vars.onHover,
35524			onHoverEnd = vars.onHoverEnd,
35525			onMove = vars.onMove,
35526			ignoreCheck = vars.ignoreCheck,
35527			isNormalizer = vars.isNormalizer,
35528			onGestureStart = vars.onGestureStart,
35529			onGestureEnd = vars.onGestureEnd,
35530			onWheel = vars.onWheel,
35531			onEnable = vars.onEnable,
35532			onDisable = vars.onDisable,
35533			onClick = vars.onClick,
35534			scrollSpeed = vars.scrollSpeed,
35535			capture = vars.capture,
35536			allowClicks = vars.allowClicks,
35537			lockAxis = vars.lockAxis,
35538			onLockAxis = vars.onLockAxis;
35539		this.target = target = _getTarget(target) || _docEl;
35540		this.vars = vars;
35541		ignore && (ignore = gsap.utils.toArray(ignore));
35542		tolerance = tolerance || 1e-9;
35543		dragMinimum = dragMinimum || 0;
35544		wheelSpeed = wheelSpeed || 1;
35545		scrollSpeed = scrollSpeed || 1;
35546		type = type || "wheel,touch,pointer";
35547		debounce = debounce !== false;
35548		lineHeight || (lineHeight = parseFloat(_win.getComputedStyle(_body).lineHeight) || 22);
35549  
35550		var id,
35551			onStopDelayedCall,
35552			dragged,
35553			moved,
35554			wheeled,
35555			locked,
35556			axis,
35557			self = this,
35558			prevDeltaX = 0,
35559			prevDeltaY = 0,
35560			passive = vars.passive || !preventDefault,
35561			scrollFuncX = _getScrollFunc(target, _horizontal),
35562			scrollFuncY = _getScrollFunc(target, _vertical),
35563			scrollX = scrollFuncX(),
35564			scrollY = scrollFuncY(),
35565			limitToTouch = ~type.indexOf("touch") && !~type.indexOf("pointer") && _eventTypes[0] === "pointerdown",
35566			isViewport = _isViewport(target),
35567			ownerDoc = target.ownerDocument || _doc,
35568			deltaX = [0, 0, 0],
35569			deltaY = [0, 0, 0],
35570			onClickTime = 0,
35571			clickCapture = function clickCapture() {
35572		  return onClickTime = _getTime();
35573		},
35574			_ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) {
35575		  return (self.event = e) && ignore && ~ignore.indexOf(e.target) || isPointerOrTouch && limitToTouch && e.pointerType !== "touch" || ignoreCheck && ignoreCheck(e, isPointerOrTouch);
35576		},
35577			onStopFunc = function onStopFunc() {
35578		  self._vx.reset();
35579  
35580		  self._vy.reset();
35581  
35582		  onStopDelayedCall.pause();
35583		  onStop && onStop(self);
35584		},
35585			update = function update() {
35586		  var dx = self.deltaX = _getAbsoluteMax(deltaX),
35587			  dy = self.deltaY = _getAbsoluteMax(deltaY),
35588			  changedX = Math.abs(dx) >= tolerance,
35589			  changedY = Math.abs(dy) >= tolerance;
35590  
35591		  onChange && (changedX || changedY) && onChange(self, dx, dy, deltaX, deltaY);
35592  
35593		  if (changedX) {
35594			onRight && self.deltaX > 0 && onRight(self);
35595			onLeft && self.deltaX < 0 && onLeft(self);
35596			onChangeX && onChangeX(self);
35597			onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self);
35598			prevDeltaX = self.deltaX;
35599			deltaX[0] = deltaX[1] = deltaX[2] = 0;
35600		  }
35601  
35602		  if (changedY) {
35603			onDown && self.deltaY > 0 && onDown(self);
35604			onUp && self.deltaY < 0 && onUp(self);
35605			onChangeY && onChangeY(self);
35606			onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self);
35607			prevDeltaY = self.deltaY;
35608			deltaY[0] = deltaY[1] = deltaY[2] = 0;
35609		  }
35610  
35611		  if (moved || dragged) {
35612			onMove && onMove(self);
35613  
35614			if (dragged) {
35615			  onDrag(self);
35616			  dragged = false;
35617			}
35618  
35619			moved = false;
35620		  }
35621  
35622		  locked && !(locked = false) && onLockAxis && onLockAxis(self);
35623  
35624		  if (wheeled) {
35625			onWheel(self);
35626			wheeled = false;
35627		  }
35628  
35629		  id = 0;
35630		},
35631			onDelta = function onDelta(x, y, index) {
35632		  deltaX[index] += x;
35633		  deltaY[index] += y;
35634  
35635		  self._vx.update(x);
35636  
35637		  self._vy.update(y);
35638  
35639		  debounce ? id || (id = requestAnimationFrame(update)) : update();
35640		},
35641			onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) {
35642		  if (lockAxis && !axis) {
35643			self.axis = axis = Math.abs(x) > Math.abs(y) ? "x" : "y";
35644			locked = true;
35645		  }
35646  
35647		  if (axis !== "y") {
35648			deltaX[2] += x;
35649  
35650			self._vx.update(x, true);
35651		  }
35652  
35653		  if (axis !== "x") {
35654			deltaY[2] += y;
35655  
35656			self._vy.update(y, true);
35657		  }
35658  
35659		  debounce ? id || (id = requestAnimationFrame(update)) : update();
35660		},
35661			_onDrag = function _onDrag(e) {
35662		  if (_ignoreCheck(e, 1)) {
35663			return;
35664		  }
35665  
35666		  e = _getEvent(e, preventDefault);
35667		  var x = e.clientX,
35668			  y = e.clientY,
35669			  dx = x - self.x,
35670			  dy = y - self.y,
35671			  isDragging = self.isDragging;
35672		  self.x = x;
35673		  self.y = y;
35674  
35675		  if (isDragging || Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum) {
35676			onDrag && (dragged = true);
35677			isDragging || (self.isDragging = true);
35678			onTouchOrPointerDelta(dx, dy);
35679			isDragging || onDragStart && onDragStart(self);
35680		  }
35681		},
35682			_onPress = self.onPress = function (e) {
35683		  if (_ignoreCheck(e, 1) || e && e.button) {
35684			return;
35685		  }
35686  
35687		  self.axis = axis = null;
35688		  onStopDelayedCall.pause();
35689		  self.isPressed = true;
35690		  e = _getEvent(e);
35691		  prevDeltaX = prevDeltaY = 0;
35692		  self.startX = self.x = e.clientX;
35693		  self.startY = self.y = e.clientY;
35694  
35695		  self._vx.reset();
35696  
35697		  self._vy.reset();
35698  
35699		  _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, passive, true);
35700  
35701		  self.deltaX = self.deltaY = 0;
35702		  onPress && onPress(self);
35703		},
35704			_onRelease = self.onRelease = function (e) {
35705		  if (_ignoreCheck(e, 1)) {
35706			return;
35707		  }
35708  
35709		  _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);
35710  
35711		  var isTrackingDrag = !isNaN(self.y - self.startY),
35712			  wasDragging = self.isDragging,
35713			  isDragNotClick = wasDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3),
35714			  eventData = _getEvent(e);
35715  
35716		  if (!isDragNotClick && isTrackingDrag) {
35717			self._vx.reset();
35718  
35719			self._vy.reset();
35720  
35721			if (preventDefault && allowClicks) {
35722			  gsap.delayedCall(0.08, function () {
35723				if (_getTime() - onClickTime > 300 && !e.defaultPrevented) {
35724				  if (e.target.click) {
35725					e.target.click();
35726				  } else if (ownerDoc.createEvent) {
35727					var syntheticEvent = ownerDoc.createEvent("MouseEvents");
35728					syntheticEvent.initMouseEvent("click", true, true, _win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null);
35729					e.target.dispatchEvent(syntheticEvent);
35730				  }
35731				}
35732			  });
35733			}
35734		  }
35735  
35736		  self.isDragging = self.isGesturing = self.isPressed = false;
35737		  onStop && wasDragging && !isNormalizer && onStopDelayedCall.restart(true);
35738		  onDragEnd && wasDragging && onDragEnd(self);
35739		  onRelease && onRelease(self, isDragNotClick);
35740		},
35741			_onGestureStart = function _onGestureStart(e) {
35742		  return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging);
35743		},
35744			_onGestureEnd = function _onGestureEnd() {
35745		  return (self.isGesturing = false) || onGestureEnd(self);
35746		},
35747			onScroll = function onScroll(e) {
35748		  if (_ignoreCheck(e)) {
35749			return;
35750		  }
35751  
35752		  var x = scrollFuncX(),
35753			  y = scrollFuncY();
35754		  onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1);
35755		  scrollX = x;
35756		  scrollY = y;
35757		  onStop && onStopDelayedCall.restart(true);
35758		},
35759			_onWheel = function _onWheel(e) {
35760		  if (_ignoreCheck(e)) {
35761			return;
35762		  }
35763  
35764		  e = _getEvent(e, preventDefault);
35765		  onWheel && (wheeled = true);
35766		  var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? _win.innerHeight : 1) * wheelSpeed;
35767		  onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0);
35768		  onStop && !isNormalizer && onStopDelayedCall.restart(true);
35769		},
35770			_onMove = function _onMove(e) {
35771		  if (_ignoreCheck(e)) {
35772			return;
35773		  }
35774  
35775		  var x = e.clientX,
35776			  y = e.clientY,
35777			  dx = x - self.x,
35778			  dy = y - self.y;
35779		  self.x = x;
35780		  self.y = y;
35781		  moved = true;
35782		  onStop && onStopDelayedCall.restart(true);
35783		  (dx || dy) && onTouchOrPointerDelta(dx, dy);
35784		},
35785			_onHover = function _onHover(e) {
35786		  self.event = e;
35787		  onHover(self);
35788		},
35789			_onHoverEnd = function _onHoverEnd(e) {
35790		  self.event = e;
35791		  onHoverEnd(self);
35792		},
35793			_onClick = function _onClick(e) {
35794		  return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self);
35795		};
35796  
35797		onStopDelayedCall = self._dc = gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause();
35798		self.deltaX = self.deltaY = 0;
35799		self._vx = _getVelocityProp(0, 50, true);
35800		self._vy = _getVelocityProp(0, 50, true);
35801		self.scrollX = scrollFuncX;
35802		self.scrollY = scrollFuncY;
35803		self.isDragging = self.isGesturing = self.isPressed = false;
vendor: 7,173 bytes, lines 35804-36046
35804  
35805		_context(this);
35806  
35807		self.enable = function (e) {
35808		  if (!self.isEnabled) {
35809			_addListener(isViewport ? ownerDoc : target, "scroll", _onScroll);
35810  
35811			type.indexOf("scroll") >= 0 && _addListener(isViewport ? ownerDoc : target, "scroll", onScroll, passive, capture);
35812			type.indexOf("wheel") >= 0 && _addListener(target, "wheel", _onWheel, passive, capture);
35813  
35814			if (type.indexOf("touch") >= 0 && _isTouch || type.indexOf("pointer") >= 0) {
35815			  _addListener(target, _eventTypes[0], _onPress, passive, capture);
35816  
35817			  _addListener(ownerDoc, _eventTypes[2], _onRelease);
35818  
35819			  _addListener(ownerDoc, _eventTypes[3], _onRelease);
35820  
35821			  allowClicks && _addListener(target, "click", clickCapture, true, true);
35822			  onClick && _addListener(target, "click", _onClick);
35823			  onGestureStart && _addListener(ownerDoc, "gesturestart", _onGestureStart);
35824			  onGestureEnd && _addListener(ownerDoc, "gestureend", _onGestureEnd);
35825			  onHover && _addListener(target, _pointerType + "enter", _onHover);
35826			  onHoverEnd && _addListener(target, _pointerType + "leave", _onHoverEnd);
35827			  onMove && _addListener(target, _pointerType + "move", _onMove);
35828			}
35829  
35830			self.isEnabled = true;
35831			e && e.type && _onPress(e);
35832			onEnable && onEnable(self);
35833		  }
35834  
35835		  return self;
35836		};
35837  
35838		self.disable = function () {
35839		  if (self.isEnabled) {
35840			_observers.filter(function (o) {
35841			  return o !== self && _isViewport(o.target);
35842			}).length || _removeListener(isViewport ? ownerDoc : target, "scroll", _onScroll);
35843  
35844			if (self.isPressed) {
35845			  self._vx.reset();
35846  
35847			  self._vy.reset();
35848  
35849			  _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);
35850			}
35851  
35852			_removeListener(isViewport ? ownerDoc : target, "scroll", onScroll, capture);
35853  
35854			_removeListener(target, "wheel", _onWheel, capture);
35855  
35856			_removeListener(target, _eventTypes[0], _onPress, capture);
35857  
35858			_removeListener(ownerDoc, _eventTypes[2], _onRelease);
35859  
35860			_removeListener(ownerDoc, _eventTypes[3], _onRelease);
35861  
35862			_removeListener(target, "click", clickCapture, true);
35863  
35864			_removeListener(target, "click", _onClick);
35865  
35866			_removeListener(ownerDoc, "gesturestart", _onGestureStart);
35867  
35868			_removeListener(ownerDoc, "gestureend", _onGestureEnd);
35869  
35870			_removeListener(target, _pointerType + "enter", _onHover);
35871  
35872			_removeListener(target, _pointerType + "leave", _onHoverEnd);
35873  
35874			_removeListener(target, _pointerType + "move", _onMove);
35875  
35876			self.isEnabled = self.isPressed = self.isDragging = false;
35877			onDisable && onDisable(self);
35878		  }
35879		};
35880  
35881		self.kill = self.revert = function () {
35882		  self.disable();
35883  
35884		  var i = _observers.indexOf(self);
35885  
35886		  i >= 0 && _observers.splice(i, 1);
35887		  _normalizer === self && (_normalizer = 0);
35888		};
35889  
35890		_observers.push(self);
35891  
35892		isNormalizer && _isViewport(target) && (_normalizer = self);
35893		self.enable(event);
35894	  };
35895  
35896	  _createClass(Observer, [{
35897		key: "velocityX",
35898		get: function get() {
35899		  return this._vx.getVelocity();
35900		}
35901	  }, {
35902		key: "velocityY",
35903		get: function get() {
35904		  return this._vy.getVelocity();
35905		}
35906	  }]);
35907  
35908	  return Observer;
35909	}();
35910	Observer.version = "3.12.5";
35911  
35912	Observer.create = function (vars) {
35913	  return new Observer(vars);
35914	};
35915  
35916	Observer.register = _initCore;
35917  
35918	Observer.getAll = function () {
35919	  return _observers.slice();
35920	};
35921  
35922	Observer.getById = function (id) {
35923	  return _observers.filter(function (o) {
35924		return o.vars.id === id;
35925	  })[0];
35926	};
35927  
35928	_getGSAP() && gsap.registerPlugin(Observer);
35929  
35930	/*!
35931	 * ScrollTrigger 3.12.5
35932	 * https://gsap.com
35933	 *
35934	 * @license Copyright 2008-2024, GreenSock. All rights reserved.
35935	 * Subject to the terms at https://gsap.com/standard-license or for
35936	 * Club GSAP members, the agreement issued with that membership.
35937	 * @author: Jack Doyle, [email protected]
35938	*/
35939  
35940	var gsap$1,
35941		_coreInitted$1,
35942		_win$1,
35943		_doc$1,
35944		_docEl$1,
35945		_body$1,
35946		_root$1,
35947		_resizeDelay,
35948		_toArray,
35949		_clamp$1,
35950		_time2,
35951		_syncInterval,
35952		_refreshing,
35953		_pointerIsDown,
35954		_transformProp,
35955		_i,
35956		_prevWidth,
35957		_prevHeight,
35958		_autoRefresh,
35959		_sort,
35960		_suppressOverwrites,
35961		_ignoreResize,
35962		_normalizer$1,
35963		_ignoreMobileResize,
35964		_baseScreenHeight,
35965		_baseScreenWidth,
35966		_fixIOSBug,
35967		_context$1,
35968		_scrollRestoration,
35969		_div100vh,
35970		_100vh,
35971		_isReverted,
35972		_clampingMax,
35973		_limitCallbacks,
35974		_startup$1 = 1,
35975		_getTime$1 = Date.now,
35976		_time1 = _getTime$1(),
35977		_lastScrollTime = 0,
35978		_enabled = 0,
35979		_parseClamp = function _parseClamp(value, type, self) {
35980	  var clamp = _isString(value) && (value.substr(0, 6) === "clamp(" || value.indexOf("max") > -1);
35981	  self["_" + type + "Clamp"] = clamp;
35982	  return clamp ? value.substr(6, value.length - 7) : value;
35983	},
35984		_keepClamp = function _keepClamp(value, clamp) {
35985	  return clamp && (!_isString(value) || value.substr(0, 6) !== "clamp(") ? "clamp(" + value + ")" : value;
35986	},
35987		_rafBugFix = function _rafBugFix() {
35988	  return _enabled && requestAnimationFrame(_rafBugFix);
35989	},
35990		_pointerDownHandler = function _pointerDownHandler() {
35991	  return _pointerIsDown = 1;
35992	},
35993		_pointerUpHandler = function _pointerUpHandler() {
35994	  return _pointerIsDown = 0;
35995	},
35996		_passThrough = function _passThrough(v) {
35997	  return v;
35998	},
35999		_round = function _round(value) {
36000	  return Math.round(value * 100000) / 100000 || 0;
36001	},
36002		_windowExists = function _windowExists() {
36003	  return typeof window !== "undefined";
36004	},
36005		_getGSAP$1 = function _getGSAP() {
36006	  return gsap$1 || _windowExists() && (gsap$1 = window.gsap) && gsap$1.registerPlugin && gsap$1;
36007	},
36008		_isViewport$1 = function _isViewport(e) {
36009	  return !!~_root$1.indexOf(e);
36010	},
36011		_getViewportDimension = function _getViewportDimension(dimensionProperty) {
36012	  return (dimensionProperty === "Height" ? _100vh : _win$1["inner" + dimensionProperty]) || _docEl$1["client" + dimensionProperty] || _body$1["client" + dimensionProperty];
36013	},
36014		_getBoundsFunc = function _getBoundsFunc(element) {
36015	  return _getProxyProp(element, "getBoundingClientRect") || (_isViewport$1(element) ? function () {
36016		_winOffsets.width = _win$1.innerWidth;
36017		_winOffsets.height = _100vh;
36018		return _winOffsets;
36019	  } : function () {
36020		return _getBounds(element);
36021	  });
36022	},
36023		_getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref) {
36024	  var d = _ref.d,
36025		  d2 = _ref.d2,
36026		  a = _ref.a;
36027	  return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () {
36028		return a()[d];
36029	  } : function () {
36030		return (isViewport ? _getViewportDimension(d2) : scroller["client" + d2]) || 0;
36031	  };
36032	},
36033		_getOffsetsFunc = function _getOffsetsFunc(element, isViewport) {
36034	  return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () {
36035		return _winOffsets;
36036	  };
36037	},
36038		_maxScroll = function _maxScroll(element, _ref2) {
36039	  var s = _ref2.s,
36040		  d2 = _ref2.d2,
36041		  d = _ref2.d,
36042		  a = _ref2.a;
36043	  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]);
36044	},
36045		_iterateAutoRefresh = function _iterateAutoRefresh(func, events) {
36046	  for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 14,082 bytes, lines 36047-36518
36047		(!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]);
36048	  }
36049	},
36050		_isString = function _isString(value) {
36051	  return typeof value === "string";
36052	},
36053		_isFunction = function _isFunction(value) {
36054	  return typeof value === "function";
36055	},
36056		_isNumber = function _isNumber(value) {
36057	  return typeof value === "number";
36058	},
36059		_isObject = function _isObject(value) {
36060	  return typeof value === "object";
36061	},
36062		_endAnimation = function _endAnimation(animation, reversed, pause) {
36063	  return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause();
36064	},
36065		_callback = function _callback(self, func) {
36066	  if (self.enabled) {
36067		var result = self._ctx ? self._ctx.add(function () {
36068		  return func(self);
36069		}) : func(self);
36070		result && result.totalTime && (self.callbackAnimation = result);
36071	  }
36072	},
36073		_abs = Math.abs,
36074		_left = "left",
36075		_top = "top",
36076		_right = "right",
36077		_bottom = "bottom",
36078		_width = "width",
36079		_height = "height",
36080		_Right = "Right",
36081		_Left = "Left",
36082		_Top = "Top",
36083		_Bottom = "Bottom",
36084		_padding = "padding",
36085		_margin = "margin",
36086		_Width = "Width",
36087		_Height = "Height",
36088		_px = "px",
36089		_getComputedStyle = function _getComputedStyle(element) {
36090	  return _win$1.getComputedStyle(element);
36091	},
36092		_makePositionable = function _makePositionable(element) {
36093	  var position = _getComputedStyle(element).position;
36094  
36095	  element.style.position = position === "absolute" || position === "fixed" ? position : "relative";
36096	},
36097		_setDefaults = function _setDefaults(obj, defaults) {
36098	  for (var p in defaults) {
36099		p in obj || (obj[p] = defaults[p]);
36100	  }
36101  
36102	  return obj;
36103	},
36104		_getBounds = function _getBounds(element, withoutTransforms) {
36105	  var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap$1.to(element, {
36106		x: 0,
36107		y: 0,
36108		xPercent: 0,
36109		yPercent: 0,
36110		rotation: 0,
36111		rotationX: 0,
36112		rotationY: 0,
36113		scale: 1,
36114		skewX: 0,
36115		skewY: 0
36116	  }).progress(1),
36117		  bounds = element.getBoundingClientRect();
36118	  tween && tween.progress(0).kill();
36119	  return bounds;
36120	},
36121		_getSize = function _getSize(element, _ref3) {
36122	  var d2 = _ref3.d2;
36123	  return element["offset" + d2] || element["client" + d2] || 0;
36124	},
36125		_getLabelRatioArray = function _getLabelRatioArray(timeline) {
36126	  var a = [],
36127		  labels = timeline.labels,
36128		  duration = timeline.duration(),
36129		  p;
36130  
36131	  for (p in labels) {
36132		a.push(labels[p] / duration);
36133	  }
36134  
36135	  return a;
36136	},
36137		_getClosestLabel = function _getClosestLabel(animation) {
36138	  return function (value) {
36139		return gsap$1.utils.snap(_getLabelRatioArray(animation), value);
36140	  };
36141	},
36142		_snapDirectional = function _snapDirectional(snapIncrementOrArray) {
36143	  var snap = gsap$1.utils.snap(snapIncrementOrArray),
36144		  a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) {
36145		return a - b;
36146	  });
36147	  return a ? function (value, direction, threshold) {
36148		if (threshold === void 0) {
36149		  threshold = 1e-3;
36150		}
36151  
36152		var i;
36153  
36154		if (!direction) {
36155		  return snap(value);
36156		}
36157  
36158		if (direction > 0) {
36159		  value -= threshold;
36160  
36161		  for (i = 0; i < a.length; i++) {
36162			if (a[i] >= value) {
36163			  return a[i];
36164			}
36165		  }
36166  
36167		  return a[i - 1];
36168		} else {
36169		  i = a.length;
36170		  value += threshold;
36171  
36172		  while (i--) {
36173			if (a[i] <= value) {
36174			  return a[i];
36175			}
36176		  }
36177		}
36178  
36179		return a[0];
36180	  } : function (value, direction, threshold) {
36181		if (threshold === void 0) {
36182		  threshold = 1e-3;
36183		}
36184  
36185		var snapped = snap(value);
36186		return !direction || Math.abs(snapped - value) < threshold || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray);
36187	  };
36188	},
36189		_getLabelAtDirection = function _getLabelAtDirection(timeline) {
36190	  return function (value, st) {
36191		return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction);
36192	  };
36193	},
36194		_multiListener = function _multiListener(func, element, types, callback) {
36195	  return types.split(",").forEach(function (type) {
36196		return func(element, type, callback);
36197	  });
36198	},
36199		_addListener$1 = function _addListener(element, type, func, nonPassive, capture) {
36200	  return element.addEventListener(type, func, {
36201		passive: !nonPassive,
36202		capture: !!capture
36203	  });
36204	},
36205		_removeListener$1 = function _removeListener(element, type, func, capture) {
36206	  return element.removeEventListener(type, func, !!capture);
36207	},
36208		_wheelListener = function _wheelListener(func, el, scrollFunc) {
36209	  scrollFunc = scrollFunc && scrollFunc.wheelHandler;
36210  
36211	  if (scrollFunc) {
36212		func(el, "wheel", scrollFunc);
36213		func(el, "touchmove", scrollFunc);
36214	  }
36215	},
36216		_markerDefaults = {
36217	  startColor: "green",
36218	  endColor: "red",
36219	  indent: 0,
36220	  fontSize: "16px",
36221	  fontWeight: "normal"
36222	},
36223		_defaults = {
36224	  toggleActions: "play",
36225	  anticipatePin: 0
36226	},
36227		_keywords = {
36228	  top: 0,
36229	  left: 0,
36230	  center: 0.5,
36231	  bottom: 1,
36232	  right: 1
36233	},
36234		_offsetToPx = function _offsetToPx(value, size) {
36235	  if (_isString(value)) {
36236		var eqIndex = value.indexOf("="),
36237			relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0;
36238  
36239		if (~eqIndex) {
36240		  value.indexOf("%") > eqIndex && (relative *= size / 100);
36241		  value = value.substr(0, eqIndex - 1);
36242		}
36243  
36244		value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0);
36245	  }
36246  
36247	  return value;
36248	},
36249		_createMarker = function _createMarker(type, name, container, direction, _ref4, offset, matchWidthEl, containerAnimation) {
36250	  var startColor = _ref4.startColor,
36251		  endColor = _ref4.endColor,
36252		  fontSize = _ref4.fontSize,
36253		  indent = _ref4.indent,
36254		  fontWeight = _ref4.fontWeight;
36255  
36256	  var e = _doc$1.createElement("div"),
36257		  useFixedPosition = _isViewport$1(container) || _getProxyProp(container, "pinType") === "fixed",
36258		  isScroller = type.indexOf("scroller") !== -1,
36259		  parent = useFixedPosition ? _body$1 : container,
36260		  isStart = type.indexOf("start") !== -1,
36261		  color = isStart ? startColor : endColor,
36262		  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;";
36263  
36264	  css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;");
36265	  (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;");
36266	  matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;");
36267	  e._isStart = isStart;
36268	  e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : ""));
36269	  e.style.cssText = css;
36270	  e.innerText = name || name === 0 ? type + "-" + name : type;
36271	  parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e);
36272	  e._offset = e["offset" + direction.op.d2];
36273  
36274	  _positionMarker(e, 0, direction, isStart);
36275  
36276	  return e;
36277	},
36278		_positionMarker = function _positionMarker(marker, start, direction, flipped) {
36279	  var vars = {
36280		display: "block"
36281	  },
36282		  side = direction[flipped ? "os2" : "p2"],
36283		  oppositeSide = direction[flipped ? "p2" : "os2"];
36284	  marker._isFlipped = flipped;
36285	  vars[direction.a + "Percent"] = flipped ? -100 : 0;
36286	  vars[direction.a] = flipped ? "1px" : 0;
36287	  vars["border" + side + _Width] = 1;
36288	  vars["border" + oppositeSide + _Width] = 0;
36289	  vars[direction.p] = start + "px";
36290	  gsap$1.set(marker, vars);
36291	},
36292		_triggers = [],
36293		_ids = {},
36294		_rafID,
36295		_sync = function _sync() {
36296	  return _getTime$1() - _lastScrollTime > 34 && (_rafID || (_rafID = requestAnimationFrame(_updateAll)));
36297	},
36298		_onScroll$1 = function _onScroll() {
36299	  if (!_normalizer$1 || !_normalizer$1.isPressed || _normalizer$1.startX > _body$1.clientWidth) {
36300		_scrollers.cache++;
36301  
36302		if (_normalizer$1) {
36303		  _rafID || (_rafID = requestAnimationFrame(_updateAll));
36304		} else {
36305		  _updateAll();
36306		}
36307  
36308		_lastScrollTime || _dispatch("scrollStart");
36309		_lastScrollTime = _getTime$1();
36310	  }
36311	},
36312		_setBaseDimensions = function _setBaseDimensions() {
36313	  _baseScreenWidth = _win$1.innerWidth;
36314	  _baseScreenHeight = _win$1.innerHeight;
36315	},
36316		_onResize = function _onResize() {
36317	  _scrollers.cache++;
36318	  !_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);
36319	},
36320		_listeners = {},
36321		_emptyArray = [],
36322		_softRefresh = function _softRefresh() {
36323	  return _removeListener$1(ScrollTrigger$1, "scrollEnd", _softRefresh) || _refreshAll(true);
36324	},
36325		_dispatch = function _dispatch(type) {
36326	  return _listeners[type] && _listeners[type].map(function (f) {
36327		return f();
36328	  }) || _emptyArray;
36329	},
36330		_savedStyles = [],
36331		_revertRecorded = function _revertRecorded(media) {
36332	  for (var i = 0; i < _savedStyles.length; i += 5) {
36333		if (!media || _savedStyles[i + 4] && _savedStyles[i + 4].query === media) {
36334		  _savedStyles[i].style.cssText = _savedStyles[i + 1];
36335		  _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || "");
36336		  _savedStyles[i + 3].uncache = 1;
36337		}
36338	  }
36339	},
36340		_revertAll = function _revertAll(kill, media) {
36341	  var trigger;
36342  
36343	  for (_i = 0; _i < _triggers.length; _i++) {
36344		trigger = _triggers[_i];
36345  
36346		if (trigger && (!media || trigger._ctx === media)) {
36347		  if (kill) {
36348			trigger.kill(1);
36349		  } else {
36350			trigger.revert(true, true);
36351		  }
36352		}
36353	  }
36354  
36355	  _isReverted = true;
36356	  media && _revertRecorded(media);
36357	  media || _dispatch("revert");
36358	},
36359		_clearScrollMemory = function _clearScrollMemory(scrollRestoration, force) {
36360	  _scrollers.cache++;
36361	  (force || !_refreshingAll) && _scrollers.forEach(function (obj) {
36362		return _isFunction(obj) && obj.cacheID++ && (obj.rec = 0);
36363	  });
36364	  _isString(scrollRestoration) && (_win$1.history.scrollRestoration = _scrollRestoration = scrollRestoration);
36365	},
36366		_refreshingAll,
36367		_refreshID = 0,
36368		_queueRefreshID,
36369		_queueRefreshAll = function _queueRefreshAll() {
36370	  if (_queueRefreshID !== _refreshID) {
36371		var id = _queueRefreshID = _refreshID;
36372		requestAnimationFrame(function () {
36373		  return id === _refreshID && _refreshAll(true);
36374		});
36375	  }
36376	},
36377		_refresh100vh = function _refresh100vh() {
36378	  _body$1.appendChild(_div100vh);
36379  
36380	  _100vh = !_normalizer$1 && _div100vh.offsetHeight || _win$1.innerHeight;
36381  
36382	  _body$1.removeChild(_div100vh);
36383	},
36384		_hideAllMarkers = function _hideAllMarkers(hide) {
36385	  return _toArray(".gsap-marker-start, .gsap-marker-end, .gsap-marker-scroller-start, .gsap-marker-scroller-end").forEach(function (el) {
36386		return el.style.display = hide ? "none" : "block";
36387	  });
36388	},
36389		_refreshAll = function _refreshAll(force, skipRevert) {
36390	  if (_lastScrollTime && !force && !_isReverted) {
36391		_addListener$1(ScrollTrigger$1, "scrollEnd", _softRefresh);
36392  
36393		return;
36394	  }
36395  
36396	  _refresh100vh();
36397  
36398	  _refreshingAll = ScrollTrigger$1.isRefreshing = true;
36399  
36400	  _scrollers.forEach(function (obj) {
36401		return _isFunction(obj) && ++obj.cacheID && (obj.rec = obj());
36402	  });
36403  
36404	  var refreshInits = _dispatch("refreshInit");
36405  
36406	  _sort && ScrollTrigger$1.sort();
36407	  skipRevert || _revertAll();
36408  
36409	  _scrollers.forEach(function (obj) {
36410		if (_isFunction(obj)) {
36411		  obj.smooth && (obj.target.style.scrollBehavior = "auto");
36412		  obj(0);
36413		}
36414	  });
36415  
36416	  _triggers.slice(0).forEach(function (t) {
36417		return t.refresh();
36418	  });
36419  
36420	  _isReverted = false;
36421  
36422	  _triggers.forEach(function (t) {
36423		if (t._subPinOffset && t.pin) {
36424		  var prop = t.vars.horizontal ? "offsetWidth" : "offsetHeight",
36425			  original = t.pin[prop];
36426		  t.revert(true, 1);
36427		  t.adjustPinSpacing(t.pin[prop] - original);
36428		  t.refresh();
36429		}
36430	  });
36431  
36432	  _clampingMax = 1;
36433  
36434	  _hideAllMarkers(true);
36435  
36436	  _triggers.forEach(function (t) {
36437		var max = _maxScroll(t.scroller, t._dir),
36438			endClamp = t.vars.end === "max" || t._endClamp && t.end > max,
36439			startClamp = t._startClamp && t.start >= max;
36440  
36441		(endClamp || startClamp) && t.setPositions(startClamp ? max - 1 : t.start, endClamp ? Math.max(startClamp ? max : t.start + 1, max) : t.end, true);
36442	  });
36443  
36444	  _hideAllMarkers(false);
36445  
36446	  _clampingMax = 0;
36447	  refreshInits.forEach(function (result) {
36448		return result && result.render && result.render(-1);
36449	  });
36450  
36451	  _scrollers.forEach(function (obj) {
36452		if (_isFunction(obj)) {
36453		  obj.smooth && requestAnimationFrame(function () {
36454			return obj.target.style.scrollBehavior = "smooth";
36455		  });
36456		  obj.rec && obj(obj.rec);
36457		}
36458	  });
36459  
36460	  _clearScrollMemory(_scrollRestoration, 1);
36461  
36462	  _resizeDelay.pause();
36463  
36464	  _refreshID++;
36465	  _refreshingAll = 2;
36466  
36467	  _updateAll(2);
36468  
36469	  _triggers.forEach(function (t) {
36470		return _isFunction(t.vars.onRefresh) && t.vars.onRefresh(t);
36471	  });
36472  
36473	  _refreshingAll = ScrollTrigger$1.isRefreshing = false;
36474  
36475	  _dispatch("refresh");
36476	},
36477		_lastScroll = 0,
36478		_direction = 1,
36479		_primary,
36480		_updateAll = function _updateAll(force) {
36481	  if (force === 2 || !_refreshingAll && !_isReverted) {
36482		ScrollTrigger$1.isUpdating = true;
36483		_primary && _primary.update(0);
36484  
36485		var l = _triggers.length,
36486			time = _getTime$1(),
36487			recordVelocity = time - _time1 >= 50,
36488			scroll = l && _triggers[0].scroll();
36489  
36490		_direction = _lastScroll > scroll ? -1 : 1;
36491		_refreshingAll || (_lastScroll = scroll);
36492  
36493		if (recordVelocity) {
36494		  if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) {
36495			_lastScrollTime = 0;
36496  
36497			_dispatch("scrollEnd");
36498		  }
36499  
36500		  _time2 = _time1;
36501		  _time1 = time;
36502		}
36503  
36504		if (_direction < 0) {
36505		  _i = l;
36506  
36507		  while (_i-- > 0) {
36508			_triggers[_i] && _triggers[_i].update(0, recordVelocity);
36509		  }
36510  
36511		  _direction = 1;
36512		} else {
36513		  for (_i = 0; _i < l; _i++) {
36514			_triggers[_i] && _triggers[_i].update(0, recordVelocity);
36515		  }
36516		}
36517  
36518		ScrollTrigger$1.isUpdating = false;
vendor: 4,937 bytes, lines 36519-36669
36519	  }
36520  
36521	  _rafID = 0;
36522	},
36523		_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"],
36524		_stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]),
36525		_swapPinOut = function _swapPinOut(pin, spacer, state) {
36526	  _setState(state);
36527  
36528	  var cache = pin._gsap;
36529  
36530	  if (cache.spacerIsNative) {
36531		_setState(cache.spacerState);
36532	  } else if (pin._gsap.swappedIn) {
36533		var parent = spacer.parentNode;
36534  
36535		if (parent) {
36536		  parent.insertBefore(pin, spacer);
36537		  parent.removeChild(spacer);
36538		}
36539	  }
36540  
36541	  pin._gsap.swappedIn = false;
36542	},
36543		_swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) {
36544	  if (!pin._gsap.swappedIn) {
36545		var i = _propNamesToCopy.length,
36546			spacerStyle = spacer.style,
36547			pinStyle = pin.style,
36548			p;
36549  
36550		while (i--) {
36551		  p = _propNamesToCopy[i];
36552		  spacerStyle[p] = cs[p];
36553		}
36554  
36555		spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative";
36556		cs.display === "inline" && (spacerStyle.display = "inline-block");
36557		pinStyle[_bottom] = pinStyle[_right] = "auto";
36558		spacerStyle.flexBasis = cs.flexBasis || "auto";
36559		spacerStyle.overflow = "visible";
36560		spacerStyle.boxSizing = "border-box";
36561		spacerStyle[_width] = _getSize(pin, _horizontal) + _px;
36562		spacerStyle[_height] = _getSize(pin, _vertical) + _px;
36563		spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0";
36564  
36565		_setState(spacerState);
36566  
36567		pinStyle[_width] = pinStyle["max" + _Width] = cs[_width];
36568		pinStyle[_height] = pinStyle["max" + _Height] = cs[_height];
36569		pinStyle[_padding] = cs[_padding];
36570  
36571		if (pin.parentNode !== spacer) {
36572		  pin.parentNode.insertBefore(spacer, pin);
36573		  spacer.appendChild(pin);
36574		}
36575  
36576		pin._gsap.swappedIn = true;
36577	  }
36578	},
36579		_capsExp = /([A-Z])/g,
36580		_setState = function _setState(state) {
36581	  if (state) {
36582		var style = state.t.style,
36583			l = state.length,
36584			i = 0,
36585			p,
36586			value;
36587		(state.t._gsap || gsap$1.core.getCache(state.t)).uncache = 1;
36588  
36589		for (; i < l; i += 2) {
36590		  value = state[i + 1];
36591		  p = state[i];
36592  
36593		  if (value) {
36594			style[p] = value;
36595		  } else if (style[p]) {
36596			style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());
36597		  }
36598		}
36599	  }
36600	},
36601		_getState = function _getState(element) {
36602	  var l = _stateProps.length,
36603		  style = element.style,
36604		  state = [],
36605		  i = 0;
36606  
36607	  for (; i < l; i++) {
36608		state.push(_stateProps[i], style[_stateProps[i]]);
36609	  }
36610  
36611	  state.t = element;
36612	  return state;
36613	},
36614		_copyState = function _copyState(state, override, omitOffsets) {
36615	  var result = [],
36616		  l = state.length,
36617		  i = omitOffsets ? 8 : 0,
36618		  p;
36619  
36620	  for (; i < l; i += 2) {
36621		p = state[i];
36622		result.push(p, p in override ? override[p] : state[i + 1]);
36623	  }
36624  
36625	  result.t = state.t;
36626	  return result;
36627	},
36628		_winOffsets = {
36629	  left: 0,
36630	  top: 0
36631	},
36632		_parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation, clampZeroProp) {
36633	  _isFunction(value) && (value = value(self));
36634  
36635	  if (_isString(value) && value.substr(0, 3) === "max") {
36636		value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0);
36637	  }
36638  
36639	  var time = containerAnimation ? containerAnimation.time() : 0,
36640		  p1,
36641		  p2,
36642		  element;
36643	  containerAnimation && containerAnimation.seek(0);
36644	  isNaN(value) || (value = +value);
36645  
36646	  if (!_isNumber(value)) {
36647		_isFunction(trigger) && (trigger = trigger(self));
36648		var offsets = (value || "0").split(" "),
36649			bounds,
36650			localOffset,
36651			globalOffset,
36652			display;
36653		element = _getTarget(trigger, self) || _body$1;
36654		bounds = _getBounds(element) || {};
36655  
36656		if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") {
36657		  display = element.style.display;
36658		  element.style.display = "block";
36659		  bounds = _getBounds(element);
36660		  display ? element.style.display = display : element.style.removeProperty("display");
36661		}
36662  
36663		localOffset = _offsetToPx(offsets[0], bounds[direction.d]);
36664		globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize);
36665		value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset;
36666		markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20);
36667		scrollerSize -= scrollerSize - globalOffset;
36668	  } else {
36669		containerAnimation && (value = gsap$1.utils.mapRange(containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, 0, scrollerMa
vendor: 4,541 bytes, lines 36669-36825
36669x, value));
36670		markerScroller && _positionMarker(markerScroller, scrollerSize, direction, true);
36671	  }
36672  
36673	  if (clampZeroProp) {
36674		self[clampZeroProp] = value || -0.001;
36675		value < 0 && (value = 0);
36676	  }
36677  
36678	  if (marker) {
36679		var position = value + scrollerSize,
36680			isStart = marker._isStart;
36681		p1 = "scroll" + direction.d2;
36682  
36683		_positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body$1[p1], _docEl$1[p1]) : marker.parentNode[p1]) <= position + 1);
36684  
36685		if (useFixedPosition) {
36686		  scrollerBounds = _getBounds(markerScroller);
36687		  useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px);
36688		}
36689	  }
36690  
36691	  if (containerAnimation && element) {
36692		p1 = _getBounds(element);
36693		containerAnimation.seek(scrollerMax);
36694		p2 = _getBounds(element);
36695		containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p];
36696		value = value / containerAnimation._caScrollDist * scrollerMax;
36697	  }
36698  
36699	  containerAnimation && containerAnimation.seek(time);
36700	  return containerAnimation ? value : Math.round(value);
36701	},
36702		_prefixExp = /(webkit|moz|length|cssText|inset)/i,
36703		_reparent = function _reparent(element, parent, top, left) {
36704	  if (element.parentNode !== parent) {
36705		var style = element.style,
36706			p,
36707			cs;
36708  
36709		if (parent === _body$1) {
36710		  element._stOrig = style.cssText;
36711		  cs = _getComputedStyle(element);
36712  
36713		  for (p in cs) {
36714			if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") {
36715			  style[p] = cs[p];
36716			}
36717		  }
36718  
36719		  style.top = top;
36720		  style.left = left;
36721		} else {
36722		  style.cssText = element._stOrig;
36723		}
36724  
36725		gsap$1.core.getCache(element).uncache = 1;
36726		parent.appendChild(element);
36727	  }
36728	},
36729		_interruptionTracker = function _interruptionTracker(getValueFunc, initialValue, onInterrupt) {
36730	  var last1 = initialValue,
36731		  last2 = last1;
36732	  return function (value) {
36733		var current = Math.round(getValueFunc());
36734  
36735		if (current !== last1 && current !== last2 && Math.abs(current - last1) > 3 && Math.abs(current - last2) > 3) {
36736		  value = current;
36737		  onInterrupt && onInterrupt();
36738		}
36739  
36740		last2 = last1;
36741		last1 = value;
36742		return value;
36743	  };
36744	},
36745		_shiftMarker = function _shiftMarker(marker, direction, value) {
36746	  var vars = {};
36747	  vars[direction.p] = "+=" + value;
36748	  gsap$1.set(marker, vars);
36749	},
36750		_getTweenCreator = function _getTweenCreator(scroller, direction) {
36751	  var getScroll = _getScrollFunc(scroller, direction),
36752		  prop = "_scroll" + direction.p2,
36753		  getTween = function getTween(scrollTo, vars, initialValue, change1, change2) {
36754		var tween = getTween.tween,
36755			onComplete = vars.onComplete,
36756			modifiers = {};
36757		initialValue = initialValue || getScroll();
36758  
36759		var checkForInterruption = _interruptionTracker(getScroll, initialValue, function () {
36760		  tween.kill();
36761		  getTween.tween = 0;
36762		});
36763  
36764		change2 = change1 && change2 || 0;
36765		change1 = change1 || scrollTo - initialValue;
36766		tween && tween.kill();
36767		vars[prop] = scrollTo;
36768		vars.inherit = false;
36769		vars.modifiers = modifiers;
36770  
36771		modifiers[prop] = function () {
36772		  return checkForInterruption(initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio);
36773		};
36774  
36775		vars.onUpdate = function () {
36776		  _scrollers.cache++;
36777		  getTween.tween && _updateAll();
36778		};
36779  
36780		vars.onComplete = function () {
36781		  getTween.tween = 0;
36782		  onComplete && onComplete.call(tween);
36783		};
36784  
36785		tween = getTween.tween = gsap$1.to(scroller, vars);
36786		return tween;
36787	  };
36788  
36789	  scroller[prop] = getScroll;
36790  
36791	  getScroll.wheelHandler = function () {
36792		return getTween.tween && getTween.tween.kill() && (getTween.tween = 0);
36793	  };
36794  
36795	  _addListener$1(scroller, "wheel", getScroll.wheelHandler);
36796  
36797	  ScrollTrigger$1.isTouch && _addListener$1(scroller, "touchmove", getScroll.wheelHandler);
36798	  return getTween;
36799	};
36800  
36801	var ScrollTrigger$1 = function () {
36802	  function ScrollTrigger(vars, animation) {
36803		_coreInitted$1 || ScrollTrigger.register(gsap$1) || console.warn("Please gsap.registerPlugin(ScrollTrigger)");
36804  
36805		_context$1(this);
36806  
36807		this.init(vars, animation);
36808	  }
36809  
36810	  var _proto = ScrollTrigger.prototype;
36811  
36812	  _proto.init = function init(vars, animation) {
36813		this.progress = this.start = 0;
36814		this.vars && this.kill(true, true);
36815  
36816		if (!_enabled) {
36817		  this.update = this.refresh = this.kill = _passThrough;
36818		  return;
36819		}
36820  
36821		vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? {
36822		  trigger: vars
36823		} : vars, _defaults);
36824  
36825		var _vars = vars,
vendor: 4,184 bytes, lines 36826-36966
36826			onUpdate = _vars.onUpdate,
36827			toggleClass = _vars.toggleClass,
36828			id = _vars.id,
36829			onToggle = _vars.onToggle,
36830			onRefresh = _vars.onRefresh,
36831			scrub = _vars.scrub,
36832			trigger = _vars.trigger,
36833			pin = _vars.pin,
36834			pinSpacing = _vars.pinSpacing,
36835			invalidateOnRefresh = _vars.invalidateOnRefresh,
36836			anticipatePin = _vars.anticipatePin,
36837			onScrubComplete = _vars.onScrubComplete,
36838			onSnapComplete = _vars.onSnapComplete,
36839			once = _vars.once,
36840			snap = _vars.snap,
36841			pinReparent = _vars.pinReparent,
36842			pinSpacer = _vars.pinSpacer,
36843			containerAnimation = _vars.containerAnimation,
36844			fastScrollEnd = _vars.fastScrollEnd,
36845			preventOverlaps = _vars.preventOverlaps,
36846			direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical,
36847			isToggle = !scrub && scrub !== 0,
36848			scroller = _getTarget(vars.scroller || _win$1),
36849			scrollerCache = gsap$1.core.getCache(scroller),
36850			isViewport = _isViewport$1(scroller),
36851			useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed",
36852			callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack],
36853			toggleActions = isToggle && vars.toggleActions.split(" "),
36854			markers = "markers" in vars ? vars.markers : _defaults.markers,
36855			borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0,
36856			self = this,
36857			onRefreshInit = vars.onRefreshInit && function () {
36858		  return vars.onRefreshInit(self);
36859		},
36860			getScrollerSize = _getSizeFunc(scroller, isViewport, direction),
36861			getScrollerOffsets = _getOffsetsFunc(scroller, isViewport),
36862			lastSnap = 0,
36863			lastRefresh = 0,
36864			prevProgress = 0,
36865			scrollFunc = _getScrollFunc(scroller, direction),
36866			tweenTo,
36867			pinCache,
36868			snapFunc,
36869			scroll1,
36870			scroll2,
36871			start,
36872			end,
36873			markerStart,
36874			markerEnd,
36875			markerStartTrigger,
36876			markerEndTrigger,
36877			markerVars,
36878			executingOnRefresh,
36879			change,
36880			pinOriginalState,
36881			pinActiveState,
36882			pinState,
36883			spacer,
36884			offset,
36885			pinGetter,
36886			pinSetter,
36887			pinStart,
36888			pinChange,
36889			spacingStart,
36890			spacerState,
36891			markerStartSetter,
36892			pinMoves,
36893			markerEndSetter,
36894			cs,
36895			snap1,
36896			snap2,
36897			scrubTween,
36898			scrubSmooth,
36899			snapDurClamp,
36900			snapDelayedCall,
36901			prevScroll,
36902			prevAnimProgress,
36903			caMarkerSetter,
36904			customRevertReturn;
36905  
36906		self._startClamp = self._endClamp = false;
36907		self._dir = direction;
36908		anticipatePin *= 45;
36909		self.scroller = scroller;
36910		self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc;
36911		scroll1 = scrollFunc();
36912		self.vars = vars;
36913		animation = animation || vars.animation;
36914  
36915		if ("refreshPriority" in vars) {
36916		  _sort = 1;
36917		  vars.refreshPriority === -9999 && (_primary = self);
36918		}
36919  
36920		scrollerCache.tweenScroll = scrollerCache.tweenScroll || {
36921		  top: _getTweenCreator(scroller, _vertical),
36922		  left: _getTweenCreator(scroller, _horizontal)
36923		};
36924		self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p];
36925  
36926		self.scrubDuration = function (value) {
36927		  scrubSmooth = _isNumber(value) && value;
36928  
36929		  if (!scrubSmooth) {
36930			scrubTween && scrubTween.progress(1).kill();
36931			scrubTween = 0;
36932		  } else {
36933			scrubTween ? scrubTween.duration(value) : scrubTween = gsap$1.to(animation, {
36934			  ease: "expo",
36935			  totalProgress: "+=0",
36936			  inherit: false,
36937			  duration: scrubSmooth,
36938			  paused: true,
36939			  onComplete: function onComplete() {
36940				return onScrubComplete && onScrubComplete(self);
36941			  }
36942			});
36943		  }
36944		};
36945  
36946		if (animation) {
36947		  animation.vars.lazy = false;
36948		  animation._initted && !self.isReverted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.duration() && animation.render(0, true, true);
36949		  self.animation = animation.pause();
36950		  animation.scrollTrigger = self;
36951		  self.scrubDuration(scrub);
36952		  snap1 = 0;
36953		  id || (id = animation.vars.id);
36954		}
36955  
36956		if (snap) {
36957		  if (!_isObject(snap) || snap.push) {
36958			snap = {
36959			  snapTo: snap
36960			};
36961		  }
36962  
36963		  "scrollBehavior" in _body$1.style && gsap$1.set(isViewport ? [_body$1, _docEl$1] : scroller, {
36964			scrollBehavior: "auto"
36965		  });
36966  
vendor: 4,259 bytes, lines 36967-37062
36967		  _scrollers.forEach(function (o) {
36968			return _isFunction(o) && o.target === (isViewport ? _doc$1.scrollingElement || _docEl$1 : scroller) && (o.smooth = false);
36969		  });
36970  
36971		  snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) {
36972			return _snapDirectional(snap.snapTo)(value, _getTime$1() - lastRefresh < 500 ? 0 : st.direction);
36973		  } : gsap$1.utils.snap(snap.snapTo);
36974		  snapDurClamp = snap.duration || {
36975			min: 0.1,
36976			max: 2
36977		  };
36978		  snapDurClamp = _isObject(snapDurClamp) ? _clamp$1(snapDurClamp.min, snapDurClamp.max) : _clamp$1(snapDurClamp, snapDurClamp);
36979		  snapDelayedCall = gsap$1.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () {
36980			var scroll = scrollFunc(),
36981				refreshedRecently = _getTime$1() - lastRefresh < 500,
36982				tween = tweenTo.tween;
36983  
36984			if ((refreshedRecently || Math.abs(self.getVelocity()) < 10) && !tween && !_pointerIsDown && lastSnap !== scroll) {
36985			  var progress = (scroll - start) / change,
36986				  totalProgress = animation && !isToggle ? animation.totalProgress() : progress,
36987				  velocity = refreshedRecently ? 0 : (totalProgress - snap2) / (_getTime$1() - _time2) * 1000 || 0,
36988				  change1 = gsap$1.utils.clamp(-progress, 1 - progress, _abs(velocity / 2) * velocity / 0.185),
36989				  naturalEnd = progress + (snap.inertia === false ? 0 : change1),
36990				  endValue,
36991				  endScroll,
36992				  _snap = snap,
36993				  onStart = _snap.onStart,
36994				  _onInterrupt = _snap.onInterrupt,
36995				  _onComplete = _snap.onComplete;
36996			  endValue = snapFunc(naturalEnd, self);
36997			  _isNumber(endValue) || (endValue = naturalEnd);
36998			  endScroll = Math.round(start + endValue * change);
36999  
37000			  if (scroll <= end && scroll >= start && endScroll !== scroll) {
37001				if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) {
37002				  return;
37003				}
37004  
37005				if (snap.inertia === false) {
37006				  change1 = endValue - progress;
37007				}
37008  
37009				tweenTo(endScroll, {
37010				  duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)),
37011				  ease: snap.ease || "power3",
37012				  data: _abs(endScroll - scroll),
37013				  onInterrupt: function onInterrupt() {
37014					return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self);
37015				  },
37016				  onComplete: function onComplete() {
37017					self.update();
37018					lastSnap = scrollFunc();
37019  
37020					if (animation) {
37021					  scrubTween ? scrubTween.resetTo("totalProgress", endValue, animation._tTime / animation._tDur) : animation.progress(endValue);
37022					}
37023  
37024					snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress;
37025					onSnapComplete && onSnapComplete(self);
37026					_onComplete && _onComplete(self);
37027				  }
37028				}, scroll, change1 * change, endScroll - scroll - change1 * change);
37029				onStart && onStart(self, tweenTo.tween);
37030			  }
37031			} else if (self.isActive && lastSnap !== scroll) {
37032			  snapDelayedCall.restart(true);
37033			}
37034		  }).pause();
37035		}
37036  
37037		id && (_ids[id] = self);
37038		trigger = self.trigger = _getTarget(trigger || pin !== true && pin);
37039		customRevertReturn = trigger && trigger._gsap && trigger._gsap.stRevert;
37040		customRevertReturn && (customRevertReturn = customRevertReturn(self));
37041		pin = pin === true ? trigger : _getTarget(pin);
37042		_isString(toggleClass) && (toggleClass = {
37043		  targets: trigger,
37044		  className: toggleClass
37045		});
37046  
37047		if (pin) {
37048		  pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && pin.parentNode && pin.parentNode.style && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding);
37049		  self.pin = pin;
37050		  pinCache = gsap$1.core.getCache(pin);
37051  
37052		  if (!pinCache.spacer) {
37053			if (pinSpacer) {
37054			  pinSpacer = _getTarget(pinSpacer);
37055			  pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement);
37056			  pinCache.spacerIsNative = !!pinSpacer;
37057			  pinSpacer && (pinCache.spacerState = _getState(pinSpacer));
37058			}
37059  
37060			pinCache.spacer = spacer = pinSpacer || _doc$1.createElement("div");
37061			spacer.classList.add("pin-spacer");
37062			id && spacer.classList.add("pin-spacer-" + id);
vendor: 4,987 bytes, lines 37063-37217
37063			pinCache.pinState = pinOriginalState = _getState(pin);
37064		  } else {
37065			pinOriginalState = pinCache.pinState;
37066		  }
37067  
37068		  vars.force3D !== false && gsap$1.set(pin, {
37069			force3D: true
37070		  });
37071		  self.spacer = spacer = pinCache.spacer;
37072		  cs = _getComputedStyle(pin);
37073		  spacingStart = cs[pinSpacing + direction.os2];
37074		  pinGetter = gsap$1.getProperty(pin);
37075		  pinSetter = gsap$1.quickSetter(pin, direction.a, _px);
37076  
37077		  _swapPinIn(pin, spacer, cs);
37078  
37079		  pinState = _getState(pin);
37080		}
37081  
37082		if (markers) {
37083		  markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults;
37084		  markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0);
37085		  markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger);
37086		  offset = markerStartTrigger["offset" + direction.op.d2];
37087  
37088		  var content = _getTarget(_getProxyProp(scroller, "content") || scroller);
37089  
37090		  markerStart = this.markerStart = _createMarker("start", id, content, direction, markerVars, offset, 0, containerAnimation);
37091		  markerEnd = this.markerEnd = _createMarker("end", id, content, direction, markerVars, offset, 0, containerAnimation);
37092		  containerAnimation && (caMarkerSetter = gsap$1.quickSetter([markerStart, markerEnd], direction.a, _px));
37093  
37094		  if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) {
37095			_makePositionable(isViewport ? _body$1 : scroller);
37096  
37097			gsap$1.set([markerStartTrigger, markerEndTrigger], {
37098			  force3D: true
37099			});
37100			markerStartSetter = gsap$1.quickSetter(markerStartTrigger, direction.a, _px);
37101			markerEndSetter = gsap$1.quickSetter(markerEndTrigger, direction.a, _px);
37102		  }
37103		}
37104  
37105		if (containerAnimation) {
37106		  var oldOnUpdate = containerAnimation.vars.onUpdate,
37107			  oldParams = containerAnimation.vars.onUpdateParams;
37108		  containerAnimation.eventCallback("onUpdate", function () {
37109			self.update(0, 0, 1);
37110			oldOnUpdate && oldOnUpdate.apply(containerAnimation, oldParams || []);
37111		  });
37112		}
37113  
37114		self.previous = function () {
37115		  return _triggers[_triggers.indexOf(self) - 1];
37116		};
37117  
37118		self.next = function () {
37119		  return _triggers[_triggers.indexOf(self) + 1];
37120		};
37121  
37122		self.revert = function (revert, temp) {
37123		  if (!temp) {
37124			return self.kill(true);
37125		  }
37126  
37127		  var r = revert !== false || !self.enabled,
37128			  prevRefreshing = _refreshing;
37129  
37130		  if (r !== self.isReverted) {
37131			if (r) {
37132			  prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0);
37133			  prevProgress = self.progress;
37134			  prevAnimProgress = animation && animation.progress();
37135			}
37136  
37137			markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {
37138			  return m.style.display = r ? "none" : "block";
37139			});
37140  
37141			if (r) {
37142			  _refreshing = self;
37143			  self.update(r);
37144			}
37145  
37146			if (pin && (!pinReparent || !self.isActive)) {
37147			  if (r) {
37148				_swapPinOut(pin, spacer, pinOriginalState);
37149			  } else {
37150				_swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState);
37151			  }
37152			}
37153  
37154			r || self.update(r);
37155			_refreshing = prevRefreshing;
37156			self.isReverted = r;
37157		  }
37158		};
37159  
37160		self.refresh = function (soft, force, position, pinOffset) {
37161		  if ((_refreshing || !self.enabled) && !force) {
37162			return;
37163		  }
37164  
37165		  if (pin && soft && _lastScrollTime) {
37166			_addListener$1(ScrollTrigger, "scrollEnd", _softRefresh);
37167  
37168			return;
37169		  }
37170  
37171		  !_refreshingAll && onRefreshInit && onRefreshInit(self);
37172		  _refreshing = self;
37173  
37174		  if (tweenTo.tween && !position) {
37175			tweenTo.tween.kill();
37176			tweenTo.tween = 0;
37177		  }
37178  
37179		  scrubTween && scrubTween.pause();
37180		  invalidateOnRefresh && animation && animation.revert({
37181			kill: false
37182		  }).invalidate();
37183		  self.isReverted || self.revert(true, true);
37184		  self._subPinOffset = false;
37185  
37186		  var size = getScrollerSize(),
37187			  scrollerBounds = getScrollerOffsets(),
37188			  max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction),
37189			  isFirstRefresh = change <= 0.01,
37190			  offset = 0,
37191			  otherPinOffset = pinOffset || 0,
37192			  parsedEnd = _isObject(position) ? position.end : vars.end,
37193			  parsedEndTrigger = vars.endTrigger || trigger,
37194			  parsedStart = _isObject(position) ? position.start : vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"),
37195			  pinnedContainer = self.pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer, self),
37196			  triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0,
37197			  i = triggerIndex,
37198			  cs,
37199			  bounds,
37200			  scroll,
37201			  isVertical,
37202			  override,
37203			  curTrigger,
37204			  curPin,
37205			  oppositeScroll,
37206			  initted,
37207			  revertedPins,
37208			  forcedOverflow,
37209			  markerStartOffset,
37210			  markerEndOffset;
37211  
37212		  if (markers && _isObject(position)) {
37213			markerStartOffset = gsap$1.getProperty(markerStartTrigger, direction.p);
37214			markerEndOffset = gsap$1.getProperty(markerEndTrigger, direction.p);
37215		  }
37216  
37217		  while (i--) {
vendor: 4,360 bytes, lines 37218-37329
37218			curTrigger = _triggers[i];
37219			curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = self);
37220			curPin = curTrigger.pin;
37221  
37222			if (curPin && (curPin === trigger || curPin === pin || curPin === pinnedContainer) && !curTrigger.isReverted) {
37223			  revertedPins || (revertedPins = []);
37224			  revertedPins.unshift(curTrigger);
37225			  curTrigger.revert(true, true);
37226			}
37227  
37228			if (curTrigger !== _triggers[i]) {
37229			  triggerIndex--;
37230			  i--;
37231			}
37232		  }
37233  
37234		  _isFunction(parsedStart) && (parsedStart = parsedStart(self));
37235		  parsedStart = _parseClamp(parsedStart, "start", self);
37236		  start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._startClamp && "_startClamp") || (pin ? -0.001 : 0);
37237		  _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self));
37238  
37239		  if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) {
37240			if (~parsedEnd.indexOf(" ")) {
37241			  parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd;
37242			} else {
37243			  offset = _offsetToPx(parsedEnd.substr(2), size);
37244			  parsedEnd = _isString(parsedStart) ? parsedStart : (containerAnimation ? gsap$1.utils.mapRange(0, containerAnimation.duration(), containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, start) : start) + offset;
37245			  parsedEndTrigger = trigger;
37246			}
37247		  }
37248  
37249		  parsedEnd = _parseClamp(parsedEnd, "end", self);
37250		  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;
37251		  offset = 0;
37252		  i = triggerIndex;
37253  
37254		  while (i--) {
37255			curTrigger = _triggers[i];
37256			curPin = curTrigger.pin;
37257  
37258			if (curPin && curTrigger.start - curTrigger._pinPush <= start && !containerAnimation && curTrigger.end > 0) {
37259			  cs = curTrigger.end - (self._startClamp ? Math.max(0, curTrigger.start) : curTrigger.start);
37260  
37261			  if ((curPin === trigger && curTrigger.start - curTrigger._pinPush < start || curPin === pinnedContainer) && isNaN(parsedStart)) {
37262				offset += cs * (1 - curTrigger.progress);
37263			  }
37264  
37265			  curPin === pin && (otherPinOffset += cs);
37266			}
37267		  }
37268  
37269		  start += offset;
37270		  end += offset;
37271		  self._startClamp && (self._startClamp += offset);
37272  
37273		  if (self._endClamp && !_refreshingAll) {
37274			self._endClamp = end || -0.001;
37275			end = Math.min(end, _maxScroll(scroller, direction));
37276		  }
37277  
37278		  change = end - start || (start -= 0.01) && 0.001;
37279  
37280		  if (isFirstRefresh) {
37281			prevProgress = gsap$1.utils.clamp(0, 1, gsap$1.utils.normalize(start, end, prevScroll));
37282		  }
37283  
37284		  self._pinPush = otherPinOffset;
37285  
37286		  if (markerStart && offset) {
37287			cs = {};
37288			cs[direction.a] = "+=" + offset;
37289			pinnedContainer && (cs[direction.p] = "-=" + scrollFunc());
37290			gsap$1.set([markerStart, markerEnd], cs);
37291		  }
37292  
37293		  if (pin && !(_clampingMax && self.end >= _maxScroll(scroller, direction))) {
37294			cs = _getComputedStyle(pin);
37295			isVertical = direction === _vertical;
37296			scroll = scrollFunc();
37297			pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset;
37298  
37299			if (!max && end > 1) {
37300			  forcedOverflow = (isViewport ? _doc$1.scrollingElement || _docEl$1 : scroller).style;
37301			  forcedOverflow = {
37302				style: forcedOverflow,
37303				value: forcedOverflow["overflow" + direction.a.toUpperCase()]
37304			  };
37305  
37306			  if (isViewport && _getComputedStyle(_body$1)["overflow" + direction.a.toUpperCase()] !== "scroll") {
37307				forcedOverflow.style["overflow" + direction.a.toUpperCase()] = "scroll";
37308			  }
37309			}
37310  
37311			_swapPinIn(pin, spacer, cs);
37312  
37313			pinState = _getState(pin);
37314			bounds = _getBounds(pin, true);
37315			oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)();
37316  
37317			if (pinSpacing) {
37318			  spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px];
37319			  spacerState.t = spacer;
37320			  i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0;
37321  
37322			  if (i) {
37323				spacerState.push(direction.d, i + _px);
37324				spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px);
37325			  }
37326  
37327			  _setState(spacerState);
37328  
37329			  if (pinnedContainer) {
vendor: 9,034 bytes, lines 37330-37572
37330				_triggers.forEach(function (t) {
37331				  if (t.pin === pinnedContainer && t.vars.pinSpacing !== false) {
37332					t._subPinOffset = true;
37333				  }
37334				});
37335			  }
37336  
37337			  useFixedPosition && scrollFunc(prevScroll);
37338			} else {
37339			  i = _getSize(pin, direction);
37340			  i && spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px);
37341			}
37342  
37343			if (useFixedPosition) {
37344			  override = {
37345				top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px,
37346				left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px,
37347				boxSizing: "border-box",
37348				position: "fixed"
37349			  };
37350			  override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px;
37351			  override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px;
37352			  override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0";
37353			  override[_padding] = cs[_padding];
37354			  override[_padding + _Top] = cs[_padding + _Top];
37355			  override[_padding + _Right] = cs[_padding + _Right];
37356			  override[_padding + _Bottom] = cs[_padding + _Bottom];
37357			  override[_padding + _Left] = cs[_padding + _Left];
37358			  pinActiveState = _copyState(pinOriginalState, override, pinReparent);
37359			  _refreshingAll && scrollFunc(0);
37360			}
37361  
37362			if (animation) {
37363			  initted = animation._initted;
37364  
37365			  _suppressOverwrites(1);
37366  
37367			  animation.render(animation.duration(), true, true);
37368			  pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset;
37369			  pinMoves = Math.abs(change - pinChange) > 1;
37370			  useFixedPosition && pinMoves && pinActiveState.splice(pinActiveState.length - 2, 2);
37371			  animation.render(0, true, true);
37372			  initted || animation.invalidate(true);
37373			  animation.parent || animation.totalTime(animation.totalTime());
37374  
37375			  _suppressOverwrites(0);
37376			} else {
37377			  pinChange = change;
37378			}
37379  
37380			forcedOverflow && (forcedOverflow.value ? forcedOverflow.style["overflow" + direction.a.toUpperCase()] = forcedOverflow.value : forcedOverflow.style.removeProperty("overflow-" + direction.a));
37381		  } else if (trigger && scrollFunc() && !containerAnimation) {
37382			bounds = trigger.parentNode;
37383  
37384			while (bounds && bounds !== _body$1) {
37385			  if (bounds._pinOffset) {
37386				start -= bounds._pinOffset;
37387				end -= bounds._pinOffset;
37388			  }
37389  
37390			  bounds = bounds.parentNode;
37391			}
37392		  }
37393  
37394		  revertedPins && revertedPins.forEach(function (t) {
37395			return t.revert(false, true);
37396		  });
37397		  self.start = start;
37398		  self.end = end;
37399		  scroll1 = scroll2 = _refreshingAll ? prevScroll : scrollFunc();
37400  
37401		  if (!containerAnimation && !_refreshingAll) {
37402			scroll1 < prevScroll && scrollFunc(prevScroll);
37403			self.scroll.rec = 0;
37404		  }
37405  
37406		  self.revert(false, true);
37407		  lastRefresh = _getTime$1();
37408  
37409		  if (snapDelayedCall) {
37410			lastSnap = -1;
37411			snapDelayedCall.restart(true);
37412		  }
37413  
37414		  _refreshing = 0;
37415		  animation && isToggle && (animation._initted || prevAnimProgress) && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress || 0, true).render(animation.time(), true, true);
37416  
37417		  if (isFirstRefresh || prevProgress !== self.progress || containerAnimation || invalidateOnRefresh) {
37418			animation && !isToggle && animation.totalProgress(containerAnimation && start < -0.001 && !prevProgress ? gsap$1.utils.normalize(start, end, 0) : prevProgress, true);
37419			self.progress = isFirstRefresh || (scroll1 - start) / change === prevProgress ? 0 : prevProgress;
37420		  }
37421  
37422		  pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange));
37423		  scrubTween && scrubTween.invalidate();
37424  
37425		  if (!isNaN(markerStartOffset)) {
37426			markerStartOffset -= gsap$1.getProperty(markerStartTrigger, direction.p);
37427			markerEndOffset -= gsap$1.getProperty(markerEndTrigger, direction.p);
37428  
37429			_shiftMarker(markerStartTrigger, direction, markerStartOffset);
37430  
37431			_shiftMarker(markerStart, direction, markerStartOffset - (pinOffset || 0));
37432  
37433			_shiftMarker(markerEndTrigger, direction, markerEndOffset);
37434  
37435			_shiftMarker(markerEnd, direction, markerEndOffset - (pinOffset || 0));
37436		  }
37437  
37438		  isFirstRefresh && !_refreshingAll && self.update();
37439  
37440		  if (onRefresh && !_refreshingAll && !executingOnRefresh) {
37441			executingOnRefresh = true;
37442			onRefresh(self);
37443			executingOnRefresh = false;
37444		  }
37445		};
37446  
37447		self.getVelocity = function () {
37448		  return (scrollFunc() - scroll2) / (_getTime$1() - _time2) * 1000 || 0;
37449		};
37450  
37451		self.endAnimation = function () {
37452		  _endAnimation(self.callbackAnimation);
37453  
37454		  if (animation) {
37455			scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1);
37456		  }
37457		};
37458  
37459		self.labelToScroll = function (label) {
37460		  return animation && animation.labels && (start || self.refresh() || start) + animation.labels[label] / animation.duration() * change || 0;
37461		};
37462  
37463		self.getTrailing = function (name) {
37464		  var i = _triggers.indexOf(self),
37465			  a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1);
37466  
37467		  return (_isString(name) ? a.filter(function (t) {
37468			return t.vars.preventOverlaps === name;
37469		  }) : a).filter(function (t) {
37470			return self.direction > 0 ? t.end <= start : t.start >= end;
37471		  });
37472		};
37473  
37474		self.update = function (reset, recordVelocity, forceFake) {
37475		  if (containerAnimation && !forceFake && !reset) {
37476			return;
37477		  }
37478  
37479		  var scroll = _refreshingAll === true ? prevScroll : self.scroll(),
37480			  p = reset ? 0 : (scroll - start) / change,
37481			  clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0,
37482			  prevProgress = self.progress,
37483			  isActive,
37484			  wasActive,
37485			  toggleState,
37486			  action,
37487			  stateChanged,
37488			  toggled,
37489			  isAtMax,
37490			  isTakingAction;
37491  
37492		  if (recordVelocity) {
37493			scroll2 = scroll1;
37494			scroll1 = containerAnimation ? scrollFunc() : scroll;
37495  
37496			if (snap) {
37497			  snap2 = snap1;
37498			  snap1 = animation && !isToggle ? animation.totalProgress() : clipped;
37499			}
37500		  }
37501  
37502		  if (anticipatePin && pin && !_refreshing && !_startup$1 && _lastScrollTime) {
37503			if (!clipped && start < scroll + (scroll - scroll2) / (_getTime$1() - _time2) * anticipatePin) {
37504			  clipped = 0.0001;
37505			} else if (clipped === 1 && end > scroll + (scroll - scroll2) / (_getTime$1() - _time2) * anticipatePin) {
37506			  clipped = 0.9999;
37507			}
37508		  }
37509  
37510		  if (clipped !== prevProgress && self.enabled) {
37511			isActive = self.isActive = !!clipped && clipped < 1;
37512			wasActive = !!prevProgress && prevProgress < 1;
37513			toggled = isActive !== wasActive;
37514			stateChanged = toggled || !!clipped !== !!prevProgress;
37515			self.direction = clipped > prevProgress ? 1 : -1;
37516			self.progress = clipped;
37517  
37518			if (stateChanged && !_refreshing) {
37519			  toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3;
37520  
37521			  if (isToggle) {
37522				action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState];
37523				isTakingAction = animation && (action === "complete" || action === "reset" || action in animation);
37524			  }
37525			}
37526  
37527			preventOverlaps && (toggled || isTakingAction) && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) {
37528			  return t.endAnimation();
37529			}));
37530  
37531			if (!isToggle) {
37532			  if (scrubTween && !_refreshing && !_startup$1) {
37533				scrubTween._dp._time - scrubTween._start !== scrubTween._time && scrubTween.render(scrubTween._dp._time - scrubTween._start);
37534  
37535				if (scrubTween.resetTo) {
37536				  scrubTween.resetTo("totalProgress", clipped, animation._tTime / animation._tDur);
37537				} else {
37538				  scrubTween.vars.totalProgress = clipped;
37539				  scrubTween.invalidate().restart();
37540				}
37541			  } else if (animation) {
37542				animation.totalProgress(clipped, !!(_refreshing && (lastRefresh || reset)));
37543			  }
37544			}
37545  
37546			if (pin) {
37547			  reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart);
37548  
37549			  if (!useFixedPosition) {
37550				pinSetter(_round(pinStart + pinChange * clipped));
37551			  } else if (stateChanged) {
37552				isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction);
37553  
37554				if (pinReparent) {
37555				  if (!reset && (isActive || isAtMax)) {
37556					var bounds = _getBounds(pin, true),
37557						_offset = scroll - start;
37558  
37559					_reparent(pin, _body$1, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px);
37560				  } else {
37561					_reparent(pin, spacer);
37562				  }
37563				}
37564  
37565				_setState(isActive || isAtMax ? pinActiveState : pinState);
37566  
37567				pinMoves && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0));
37568			  }
37569			}
37570  
37571			snap && !tweenTo.tween && !_refreshing && !_startup$1 && snapDelayedCall.restart(true);
37572			toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEac
vendor: 10,394 bytes, lines 37572-37939
37572h(function (el) {
37573			  return el.classList[isActive || once ? "add" : "remove"](toggleClass.className);
37574			});
37575			onUpdate && !isToggle && !reset && onUpdate(self);
37576  
37577			if (stateChanged && !_refreshing) {
37578			  if (isToggle) {
37579				if (isTakingAction) {
37580				  if (action === "complete") {
37581					animation.pause().totalProgress(1);
37582				  } else if (action === "reset") {
37583					animation.restart(true).pause();
37584				  } else if (action === "restart") {
37585					animation.restart(true);
37586				  } else {
37587					animation[action]();
37588				  }
37589				}
37590  
37591				onUpdate && onUpdate(self);
37592			  }
37593  
37594			  if (toggled || !_limitCallbacks) {
37595				onToggle && toggled && _callback(self, onToggle);
37596				callbacks[toggleState] && _callback(self, callbacks[toggleState]);
37597				once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0);
37598  
37599				if (!toggled) {
37600				  toggleState = clipped === 1 ? 1 : 3;
37601				  callbacks[toggleState] && _callback(self, callbacks[toggleState]);
37602				}
37603			  }
37604  
37605			  if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) {
37606				_endAnimation(self.callbackAnimation);
37607  
37608				scrubTween ? scrubTween.progress(1) : _endAnimation(animation, action === "reverse" ? 1 : !clipped, 1);
37609			  }
37610			} else if (isToggle && onUpdate && !_refreshing) {
37611			  onUpdate(self);
37612			}
37613		  }
37614  
37615		  if (markerEndSetter) {
37616			var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll;
37617			markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0));
37618			markerEndSetter(n);
37619		  }
37620  
37621		  caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0));
37622		};
37623  
37624		self.enable = function (reset, refresh) {
37625		  if (!self.enabled) {
37626			self.enabled = true;
37627  
37628			_addListener$1(scroller, "resize", _onResize);
37629  
37630			isViewport || _addListener$1(scroller, "scroll", _onScroll$1);
37631			onRefreshInit && _addListener$1(ScrollTrigger, "refreshInit", onRefreshInit);
37632  
37633			if (reset !== false) {
37634			  self.progress = prevProgress = 0;
37635			  scroll1 = scroll2 = lastSnap = scrollFunc();
37636			}
37637  
37638			refresh !== false && self.refresh();
37639		  }
37640		};
37641  
37642		self.getTween = function (snap) {
37643		  return snap && tweenTo ? tweenTo.tween : scrubTween;
37644		};
37645  
37646		self.setPositions = function (newStart, newEnd, keepClamp, pinOffset) {
37647		  if (containerAnimation) {
37648			var st = containerAnimation.scrollTrigger,
37649				duration = containerAnimation.duration(),
37650				_change = st.end - st.start;
37651  
37652			newStart = st.start + _change * newStart / duration;
37653			newEnd = st.start + _change * newEnd / duration;
37654		  }
37655  
37656		  self.refresh(false, false, {
37657			start: _keepClamp(newStart, keepClamp && !!self._startClamp),
37658			end: _keepClamp(newEnd, keepClamp && !!self._endClamp)
37659		  }, pinOffset);
37660		  self.update();
37661		};
37662  
37663		self.adjustPinSpacing = function (amount) {
37664		  if (spacerState && amount) {
37665			var i = spacerState.indexOf(direction.d) + 1;
37666			spacerState[i] = parseFloat(spacerState[i]) + amount + _px;
37667			spacerState[1] = parseFloat(spacerState[1]) + amount + _px;
37668  
37669			_setState(spacerState);
37670		  }
37671		};
37672  
37673		self.disable = function (reset, allowAnimation) {
37674		  if (self.enabled) {
37675			reset !== false && self.revert(true, true);
37676			self.enabled = self.isActive = false;
37677			allowAnimation || scrubTween && scrubTween.pause();
37678			prevScroll = 0;
37679			pinCache && (pinCache.uncache = 1);
37680			onRefreshInit && _removeListener$1(ScrollTrigger, "refreshInit", onRefreshInit);
37681  
37682			if (snapDelayedCall) {
37683			  snapDelayedCall.pause();
37684			  tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0);
37685			}
37686  
37687			if (!isViewport) {
37688			  var i = _triggers.length;
37689  
37690			  while (i--) {
37691				if (_triggers[i].scroller === scroller && _triggers[i] !== self) {
37692				  return;
37693				}
37694			  }
37695  
37696			  _removeListener$1(scroller, "resize", _onResize);
37697  
37698			  isViewport || _removeListener$1(scroller, "scroll", _onScroll$1);
37699			}
37700		  }
37701		};
37702  
37703		self.kill = function (revert, allowAnimation) {
37704		  self.disable(revert, allowAnimation);
37705		  scrubTween && !allowAnimation && scrubTween.kill();
37706		  id && delete _ids[id];
37707  
37708		  var i = _triggers.indexOf(self);
37709  
37710		  i >= 0 && _triggers.splice(i, 1);
37711		  i === _i && _direction > 0 && _i--;
37712		  i = 0;
37713  
37714		  _triggers.forEach(function (t) {
37715			return t.scroller === self.scroller && (i = 1);
37716		  });
37717  
37718		  i || _refreshingAll || (self.scroll.rec = 0);
37719  
37720		  if (animation) {
37721			animation.scrollTrigger = null;
37722			revert && animation.revert({
37723			  kill: false
37724			});
37725			allowAnimation || animation.kill();
37726		  }
37727  
37728		  markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {
37729			return m.parentNode && m.parentNode.removeChild(m);
37730		  });
37731		  _primary === self && (_primary = 0);
37732  
37733		  if (pin) {
37734			pinCache && (pinCache.uncache = 1);
37735			i = 0;
37736  
37737			_triggers.forEach(function (t) {
37738			  return t.pin === pin && i++;
37739			});
37740  
37741			i || (pinCache.spacer = 0);
37742		  }
37743  
37744		  vars.onKill && vars.onKill(self);
37745		};
37746  
37747		_triggers.push(self);
37748  
37749		self.enable(false, false);
37750		customRevertReturn && customRevertReturn(self);
37751  
37752		if (animation && animation.add && !change) {
37753		  var updateFunc = self.update;
37754  
37755		  self.update = function () {
37756			self.update = updateFunc;
37757			start || end || self.refresh();
37758		  };
37759  
37760		  gsap$1.delayedCall(0.01, self.update);
37761		  change = 0.01;
37762		  start = end = 0;
37763		} else {
37764		  self.refresh();
37765		}
37766  
37767		pin && _queueRefreshAll();
37768	  };
37769  
37770	  ScrollTrigger.register = function register(core) {
37771		if (!_coreInitted$1) {
37772		  gsap$1 = core || _getGSAP$1();
37773		  _windowExists() && window.document && ScrollTrigger.enable();
37774		  _coreInitted$1 = _enabled;
37775		}
37776  
37777		return _coreInitted$1;
37778	  };
37779  
37780	  ScrollTrigger.defaults = function defaults(config) {
37781		if (config) {
37782		  for (var p in config) {
37783			_defaults[p] = config[p];
37784		  }
37785		}
37786  
37787		return _defaults;
37788	  };
37789  
37790	  ScrollTrigger.disable = function disable(reset, kill) {
37791		_enabled = 0;
37792  
37793		_triggers.forEach(function (trigger) {
37794		  return trigger[kill ? "kill" : "disable"](reset);
37795		});
37796  
37797		_removeListener$1(_win$1, "wheel", _onScroll$1);
37798  
37799		_removeListener$1(_doc$1, "scroll", _onScroll$1);
37800  
37801		clearInterval(_syncInterval);
37802  
37803		_removeListener$1(_doc$1, "touchcancel", _passThrough);
37804  
37805		_removeListener$1(_body$1, "touchstart", _passThrough);
37806  
37807		_multiListener(_removeListener$1, _doc$1, "pointerdown,touchstart,mousedown", _pointerDownHandler);
37808  
37809		_multiListener(_removeListener$1, _doc$1, "pointerup,touchend,mouseup", _pointerUpHandler);
37810  
37811		_resizeDelay.kill();
37812  
37813		_iterateAutoRefresh(_removeListener$1);
37814  
37815		for (var i = 0; i < _scrollers.length; i += 3) {
37816		  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 1]);
37817  
37818		  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 2]);
37819		}
37820	  };
37821  
37822	  ScrollTrigger.enable = function enable() {
37823		_win$1 = window;
37824		_doc$1 = document;
37825		_docEl$1 = _doc$1.documentElement;
37826		_body$1 = _doc$1.body;
37827  
37828		if (gsap$1) {
37829		  _toArray = gsap$1.utils.toArray;
37830		  _clamp$1 = gsap$1.utils.clamp;
37831		  _context$1 = gsap$1.core.context || _passThrough;
37832		  _suppressOverwrites = gsap$1.core.suppressOverwrites || _passThrough;
37833		  _scrollRestoration = _win$1.history.scrollRestoration || "auto";
37834		  _lastScroll = _win$1.pageYOffset;
37835		  gsap$1.core.globals("ScrollTrigger", ScrollTrigger);
37836  
37837		  if (_body$1) {
37838			_enabled = 1;
37839			_div100vh = document.createElement("div");
37840			_div100vh.style.height = "100vh";
37841			_div100vh.style.position = "absolute";
37842  
37843			_refresh100vh();
37844  
37845			_rafBugFix();
37846  
37847			Observer.register(gsap$1);
37848			ScrollTrigger.isTouch = Observer.isTouch;
37849			_fixIOSBug = Observer.isTouch && /(iPad|iPhone|iPod|Mac)/g.test(navigator.userAgent);
37850			_ignoreMobileResize = Observer.isTouch === 1;
37851  
37852			_addListener$1(_win$1, "wheel", _onScroll$1);
37853  
37854			_root$1 = [_win$1, _doc$1, _docEl$1, _body$1];
37855  
37856			if (gsap$1.matchMedia) {
37857			  ScrollTrigger.matchMedia = function (vars) {
37858				var mm = gsap$1.matchMedia(),
37859					p;
37860  
37861				for (p in vars) {
37862				  mm.add(p, vars[p]);
37863				}
37864  
37865				return mm;
37866			  };
37867  
37868			  gsap$1.addEventListener("matchMediaInit", function () {
37869				return _revertAll();
37870			  });
37871			  gsap$1.addEventListener("matchMediaRevert", function () {
37872				return _revertRecorded();
37873			  });
37874			  gsap$1.addEventListener("matchMedia", function () {
37875				_refreshAll(0, 1);
37876  
37877				_dispatch("matchMedia");
37878			  });
37879			  gsap$1.matchMedia("(orientation: portrait)", function () {
37880				_setBaseDimensions();
37881  
37882				return _setBaseDimensions;
37883			  });
37884			} else {
37885			  console.warn("Requires GSAP 3.11.0 or later");
37886			}
37887  
37888			_setBaseDimensions();
37889  
37890			_addListener$1(_doc$1, "scroll", _onScroll$1);
37891  
37892			var bodyStyle = _body$1.style,
37893				border = bodyStyle.borderTopStyle,
37894				AnimationProto = gsap$1.core.Animation.prototype,
37895				bounds,
37896				i;
37897			AnimationProto.revert || Object.defineProperty(AnimationProto, "revert", {
37898			  value: function value() {
37899				return this.time(-0.01, true);
37900			  }
37901			});
37902			bodyStyle.borderTopStyle = "solid";
37903			bounds = _getBounds(_body$1);
37904			_vertical.m = Math.round(bounds.top + _vertical.sc()) || 0;
37905			_horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0;
37906			border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style");
37907			_syncInterval = setInterval(_sync, 250);
37908			gsap$1.delayedCall(0.5, function () {
37909			  return _startup$1 = 0;
37910			});
37911  
37912			_addListener$1(_doc$1, "touchcancel", _passThrough);
37913  
37914			_addListener$1(_body$1, "touchstart", _passThrough);
37915  
37916			_multiListener(_addListener$1, _doc$1, "pointerdown,touchstart,mousedown", _pointerDownHandler);
37917  
37918			_multiListener(_addListener$1, _doc$1, "pointerup,touchend,mouseup", _pointerUpHandler);
37919  
37920			_transformProp = gsap$1.utils.checkPrefix("transform");
37921  
37922			_stateProps.push(_transformProp);
37923  
37924			_coreInitted$1 = _getTime$1();
37925			_resizeDelay = gsap$1.delayedCall(0.2, _refreshAll).pause();
37926			_autoRefresh = [_doc$1, "visibilitychange", function () {
37927			  var w = _win$1.innerWidth,
37928				  h = _win$1.innerHeight;
37929  
37930			  if (_doc$1.hidden) {
37931				_prevWidth = w;
37932				_prevHeight = h;
37933			  } else if (_prevWidth !== w || _prevHeight !== h) {
37934				_onResize();
37935			  }
37936			}, _doc$1, "DOMContentLoaded", _refreshAll, _win$1, "load", _refreshAll, _win$1, "resize", _onResize];
37937  
37938			_iterateAutoRefresh(_addListener$1);
37939  
vendor: 4,962 bytes, lines 37940-38085
37940			_triggers.forEach(function (trigger) {
37941			  return trigger.enable(0, 1);
37942			});
37943  
37944			for (i = 0; i < _scrollers.length; i += 3) {
37945			  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 1]);
37946  
37947			  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 2]);
37948			}
37949		  }
37950		}
37951	  };
37952  
37953	  ScrollTrigger.config = function config(vars) {
37954		"limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks);
37955		var ms = vars.syncInterval;
37956		ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms);
37957		"ignoreMobileResize" in vars && (_ignoreMobileResize = ScrollTrigger.isTouch === 1 && vars.ignoreMobileResize);
37958  
37959		if ("autoRefreshEvents" in vars) {
37960		  _iterateAutoRefresh(_removeListener$1) || _iterateAutoRefresh(_addListener$1, vars.autoRefreshEvents || "none");
37961		  _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1;
37962		}
37963	  };
37964  
37965	  ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) {
37966		var t = _getTarget(target),
37967			i = _scrollers.indexOf(t),
37968			isViewport = _isViewport$1(t);
37969  
37970		if (~i) {
37971		  _scrollers.splice(i, isViewport ? 6 : 2);
37972		}
37973  
37974		if (vars) {
37975		  isViewport ? _proxies.unshift(_win$1, vars, _body$1, vars, _docEl$1, vars) : _proxies.unshift(t, vars);
37976		}
37977	  };
37978  
37979	  ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) {
37980		_triggers.forEach(function (t) {
37981		  return t._ctx && t._ctx.query === query && t._ctx.kill(true, true);
37982		});
37983	  };
37984  
37985	  ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) {
37986		var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(),
37987			offset = bounds[horizontal ? _width : _height] * ratio || 0;
37988		return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win$1.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win$1.innerHeight;
37989	  };
37990  
37991	  ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) {
37992		_isString(element) && (element = _getTarget(element));
37993		var bounds = element.getBoundingClientRect(),
37994			size = bounds[horizontal ? _width : _height],
37995			offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0;
37996		return horizontal ? (bounds.left + offset) / _win$1.innerWidth : (bounds.top + offset) / _win$1.innerHeight;
37997	  };
37998  
37999	  ScrollTrigger.killAll = function killAll(allowListeners) {
38000		_triggers.slice(0).forEach(function (t) {
38001		  return t.vars.id !== "ScrollSmoother" && t.kill();
38002		});
38003  
38004		if (allowListeners !== true) {
38005		  var listeners = _listeners.killAll || [];
38006		  _listeners = {};
38007		  listeners.forEach(function (f) {
38008			return f();
38009		  });
38010		}
38011	  };
38012  
38013	  return ScrollTrigger;
38014	}();
38015	ScrollTrigger$1.version = "3.12.5";
38016  
38017	ScrollTrigger$1.saveStyles = function (targets) {
38018	  return targets ? _toArray(targets).forEach(function (target) {
38019		if (target && target.style) {
38020		  var i = _savedStyles.indexOf(target);
38021  
38022		  i >= 0 && _savedStyles.splice(i, 5);
38023  
38024		  _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap$1.core.getCache(target), _context$1());
38025		}
38026	  }) : _savedStyles;
38027	};
38028  
38029	ScrollTrigger$1.revert = function (soft, media) {
38030	  return _revertAll(!soft, media);
38031	};
38032  
38033	ScrollTrigger$1.create = function (vars, animation) {
38034	  return new ScrollTrigger$1(vars, animation);
38035	};
38036  
38037	ScrollTrigger$1.refresh = function (safe) {
38038	  return safe ? _onResize() : (_coreInitted$1 || ScrollTrigger$1.register()) && _refreshAll(true);
38039	};
38040  
38041	ScrollTrigger$1.update = function (force) {
38042	  return ++_scrollers.cache && _updateAll(force === true ? 2 : 0);
38043	};
38044  
38045	ScrollTrigger$1.clearScrollMemory = _clearScrollMemory;
38046  
38047	ScrollTrigger$1.maxScroll = function (element, horizontal) {
38048	  return _maxScroll(element, horizontal ? _horizontal : _vertical);
38049	};
38050  
38051	ScrollTrigger$1.getScrollFunc = function (element, horizontal) {
38052	  return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical);
38053	};
38054  
38055	ScrollTrigger$1.getById = function (id) {
38056	  return _ids[id];
38057	};
38058  
38059	ScrollTrigger$1.getAll = function () {
38060	  return _triggers.filter(function (t) {
38061		return t.vars.id !== "ScrollSmoother";
38062	  });
38063	};
38064  
38065	ScrollTrigger$1.isScrolling = function () {
38066	  return !!_lastScrollTime;
38067	};
38068  
38069	ScrollTrigger$1.snapDirectional = _snapDirectional;
38070  
38071	ScrollTrigger$1.addEventListener = function (type, callback) {
38072	  var a = _listeners[type] || (_listeners[type] = []);
38073	  ~a.indexOf(callback) || a.push(callback);
38074	};
38075  
38076	ScrollTrigger$1.removeEventListener = function (type, callback) {
38077	  var a = _listeners[type],
38078		  i = a && a.indexOf(callback);
38079	  i >= 0 && a.splice(i, 1);
38080	};
38081  
38082	ScrollTrigger$1.batch = function (targets, vars) {
38083	  var result = [],
38084		  varsCopy = {},
38085		  interval = vars.interval || 0.016,
vendor: 4,448 bytes, lines 38086-38220
38086		  batchMax = vars.batchMax || 1e9,
38087		  proxyCallback = function proxyCallback(type, callback) {
38088		var elements = [],
38089			triggers = [],
38090			delay = gsap$1.delayedCall(interval, function () {
38091		  callback(elements, triggers);
38092		  elements = [];
38093		  triggers = [];
38094		}).pause();
38095		return function (self) {
38096		  elements.length || delay.restart(true);
38097		  elements.push(self.trigger);
38098		  triggers.push(self);
38099		  batchMax <= elements.length && delay.progress(1);
38100		};
38101	  },
38102		  p;
38103  
38104	  for (p in vars) {
38105		varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p];
38106	  }
38107  
38108	  if (_isFunction(batchMax)) {
38109		batchMax = batchMax();
38110  
38111		_addListener$1(ScrollTrigger$1, "refresh", function () {
38112		  return batchMax = vars.batchMax();
38113		});
38114	  }
38115  
38116	  _toArray(targets).forEach(function (target) {
38117		var config = {};
38118  
38119		for (p in varsCopy) {
38120		  config[p] = varsCopy[p];
38121		}
38122  
38123		config.trigger = target;
38124		result.push(ScrollTrigger$1.create(config));
38125	  });
38126  
38127	  return result;
38128	};
38129  
38130	var _clampScrollAndGetDurationMultiplier = function _clampScrollAndGetDurationMultiplier(scrollFunc, current, end, max) {
38131	  current > max ? scrollFunc(max) : current < 0 && scrollFunc(0);
38132	  return end > max ? (max - current) / (end - current) : end < 0 ? current / (current - end) : 1;
38133	},
38134		_allowNativePanning = function _allowNativePanning(target, direction) {
38135	  if (direction === true) {
38136		target.style.removeProperty("touch-action");
38137	  } else {
38138		target.style.touchAction = direction === true ? "auto" : direction ? "pan-" + direction + (Observer.isTouch ? " pinch-zoom" : "") : "none";
38139	  }
38140  
38141	  target === _docEl$1 && _allowNativePanning(_body$1, direction);
38142	},
38143		_overflow = {
38144	  auto: 1,
38145	  scroll: 1
38146	},
38147		_nestedScroll = function _nestedScroll(_ref5) {
38148	  var event = _ref5.event,
38149		  target = _ref5.target,
38150		  axis = _ref5.axis;
38151  
38152	  var node = (event.changedTouches ? event.changedTouches[0] : event).target,
38153		  cache = node._gsap || gsap$1.core.getCache(node),
38154		  time = _getTime$1(),
38155		  cs;
38156  
38157	  if (!cache._isScrollT || time - cache._isScrollT > 2000) {
38158		while (node && node !== _body$1 && (node.scrollHeight <= node.clientHeight && node.scrollWidth <= node.clientWidth || !(_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]))) {
38159		  node = node.parentNode;
38160		}
38161  
38162		cache._isScroll = node && node !== target && !_isViewport$1(node) && (_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]);
38163		cache._isScrollT = time;
38164	  }
38165  
38166	  if (cache._isScroll || axis === "x") {
38167		event.stopPropagation();
38168		event._gsapAllow = true;
38169	  }
38170	},
38171		_inputObserver = function _inputObserver(target, type, inputs, nested) {
38172	  return Observer.create({
38173		target: target,
38174		capture: true,
38175		debounce: false,
38176		lockAxis: true,
38177		type: type,
38178		onWheel: nested = nested && _nestedScroll,
38179		onPress: nested,
38180		onDrag: nested,
38181		onScroll: nested,
38182		onEnable: function onEnable() {
38183		  return inputs && _addListener$1(_doc$1, Observer.eventTypes[0], _captureInputs, false, true);
38184		},
38185		onDisable: function onDisable() {
38186		  return _removeListener$1(_doc$1, Observer.eventTypes[0], _captureInputs, true);
38187		}
38188	  });
38189	},
38190		_inputExp = /(input|label|select|textarea)/i,
38191		_inputIsFocused,
38192		_captureInputs = function _captureInputs(e) {
38193	  var isInput = _inputExp.test(e.target.tagName);
38194  
38195	  if (isInput || _inputIsFocused) {
38196		e._gsapAllow = true;
38197		_inputIsFocused = isInput;
38198	  }
38199	},
38200		_getScrollNormalizer = function _getScrollNormalizer(vars) {
38201	  _isObject(vars) || (vars = {});
38202	  vars.preventDefault = vars.isNormalizer = vars.allowClicks = true;
38203	  vars.type || (vars.type = "wheel,touch");
38204	  vars.debounce = !!vars.debounce;
38205	  vars.id = vars.id || "normalizer";
38206  
38207	  var _vars2 = vars,
38208		  normalizeScrollX = _vars2.normalizeScrollX,
38209		  momentum = _vars2.momentum,
38210		  allowNestedScroll = _vars2.allowNestedScroll,
38211		  onRelease = _vars2.onRelease,
38212		  self,
38213		  maxY,
38214		  target = _getTarget(vars.target) || _docEl$1,
38215		  smoother = gsap$1.core.globals().ScrollSmoother,
38216		  smootherInstance = smoother && smoother.get(),
38217		  content = _fixIOSBug && (vars.content && _getTarget(vars.content) || smootherInstance && vars.content !== false && !smootherInstance.smooth() && smootherInstance.content()),
38218		  scrollFuncY = _getScrollFunc(target, _vertical),
38219		  scrollFuncX = _getScrollFunc(target, _horizontal),
38220		  scale = 1,
vendor: 4,132 bytes, lines 38221-38342
38221		  initialScale = (Observer.isTouch && _win$1.visualViewport ? _win$1.visualViewport.scale * _win$1.visualViewport.width : _win$1.outerWidth) / _win$1.innerWidth,
38222		  wheelRefresh = 0,
38223		  resolveMomentumDuration = _isFunction(momentum) ? function () {
38224		return momentum(self);
38225	  } : function () {
38226		return momentum || 2.8;
38227	  },
38228		  lastRefreshID,
38229		  skipTouchMove,
38230		  inputObserver = _inputObserver(target, vars.type, true, allowNestedScroll),
38231		  resumeTouchMove = function resumeTouchMove() {
38232		return skipTouchMove = false;
38233	  },
38234		  scrollClampX = _passThrough,
38235		  scrollClampY = _passThrough,
38236		  updateClamps = function updateClamps() {
38237		maxY = _maxScroll(target, _vertical);
38238		scrollClampY = _clamp$1(_fixIOSBug ? 1 : 0, maxY);
38239		normalizeScrollX && (scrollClampX = _clamp$1(0, _maxScroll(target, _horizontal)));
38240		lastRefreshID = _refreshID;
38241	  },
38242		  removeContentOffset = function removeContentOffset() {
38243		content._gsap.y = _round(parseFloat(content._gsap.y) + scrollFuncY.offset) + "px";
38244		content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + parseFloat(content._gsap.y) + ", 0, 1)";
38245		scrollFuncY.offset = scrollFuncY.cacheID = 0;
38246	  },
38247		  ignoreDrag = function ignoreDrag() {
38248		if (skipTouchMove) {
38249		  requestAnimationFrame(resumeTouchMove);
38250  
38251		  var offset = _round(self.deltaY / 2),
38252			  scroll = scrollClampY(scrollFuncY.v - offset);
38253  
38254		  if (content && scroll !== scrollFuncY.v + scrollFuncY.offset) {
38255			scrollFuncY.offset = scroll - scrollFuncY.v;
38256  
38257			var y = _round((parseFloat(content && content._gsap.y) || 0) - scrollFuncY.offset);
38258  
38259			content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + y + ", 0, 1)";
38260			content._gsap.y = y + "px";
38261			scrollFuncY.cacheID = _scrollers.cache;
38262  
38263			_updateAll();
38264		  }
38265  
38266		  return true;
38267		}
38268  
38269		scrollFuncY.offset && removeContentOffset();
38270		skipTouchMove = true;
38271	  },
38272		  tween,
38273		  startScrollX,
38274		  startScrollY,
38275		  onStopDelayedCall,
38276		  onResize = function onResize() {
38277		updateClamps();
38278  
38279		if (tween.isActive() && tween.vars.scrollY > maxY) {
38280		  scrollFuncY() > maxY ? tween.progress(1) && scrollFuncY(maxY) : tween.resetTo("scrollY", maxY);
38281		}
38282	  };
38283  
38284	  content && gsap$1.set(content, {
38285		y: "+=0"
38286	  });
38287  
38288	  vars.ignoreCheck = function (e) {
38289		return _fixIOSBug && e.type === "touchmove" && ignoreDrag() || scale > 1.05 && e.type !== "touchstart" || self.isGesturing || e.touches && e.touches.length > 1;
38290	  };
38291  
38292	  vars.onPress = function () {
38293		skipTouchMove = false;
38294		var prevScale = scale;
38295		scale = _round((_win$1.visualViewport && _win$1.visualViewport.scale || 1) / initialScale);
38296		tween.pause();
38297		prevScale !== scale && _allowNativePanning(target, scale > 1.01 ? true : normalizeScrollX ? false : "x");
38298		startScrollX = scrollFuncX();
38299		startScrollY = scrollFuncY();
38300		updateClamps();
38301		lastRefreshID = _refreshID;
38302	  };
38303  
38304	  vars.onRelease = vars.onGestureStart = function (self, wasDragging) {
38305		scrollFuncY.offset && removeContentOffset();
38306  
38307		if (!wasDragging) {
38308		  onStopDelayedCall.restart(true);
38309		} else {
38310		  _scrollers.cache++;
38311		  var dur = resolveMomentumDuration(),
38312			  currentScroll,
38313			  endScroll;
38314  
38315		  if (normalizeScrollX) {
38316			currentScroll = scrollFuncX();
38317			endScroll = currentScroll + dur * 0.05 * -self.velocityX / 0.227;
38318			dur *= _clampScrollAndGetDurationMultiplier(scrollFuncX, currentScroll, endScroll, _maxScroll(target, _horizontal));
38319			tween.vars.scrollX = scrollClampX(endScroll);
38320		  }
38321  
38322		  currentScroll = scrollFuncY();
38323		  endScroll = currentScroll + dur * 0.05 * -self.velocityY / 0.227;
38324		  dur *= _clampScrollAndGetDurationMultiplier(scrollFuncY, currentScroll, endScroll, _maxScroll(target, _vertical));
38325		  tween.vars.scrollY = scrollClampY(endScroll);
38326		  tween.invalidate().duration(dur).play(0.01);
38327  
38328		  if (_fixIOSBug && tween.vars.scrollY >= maxY || currentScroll >= maxY - 1) {
38329			gsap$1.to({}, {
38330			  onUpdate: onResize,
38331			  duration: dur
38332			});
38333		  }
38334		}
38335  
38336		onRelease && onRelease(self);
38337	  };
38338  
38339	  vars.onWheel = function () {
38340		tween._ts && tween.pause();
38341  
38342		if (_getTime$1() - wheelRefresh > 1000) {
vendor: 28,617 bytes, lines 38343-39397
38343		  lastRefreshID = 0;
38344		  wheelRefresh = _getTime$1();
38345		}
38346	  };
38347  
38348	  vars.onChange = function (self, dx, dy, xArray, yArray) {
38349		_refreshID !== lastRefreshID && updateClamps();
38350		dx && normalizeScrollX && scrollFuncX(scrollClampX(xArray[2] === dx ? startScrollX + (self.startX - self.x) : scrollFuncX() + dx - xArray[1]));
38351  
38352		if (dy) {
38353		  scrollFuncY.offset && removeContentOffset();
38354		  var isTouch = yArray[2] === dy,
38355			  y = isTouch ? startScrollY + self.startY - self.y : scrollFuncY() + dy - yArray[1],
38356			  yClamped = scrollClampY(y);
38357		  isTouch && y !== yClamped && (startScrollY += yClamped - y);
38358		  scrollFuncY(yClamped);
38359		}
38360  
38361		(dy || dx) && _updateAll();
38362	  };
38363  
38364	  vars.onEnable = function () {
38365		_allowNativePanning(target, normalizeScrollX ? false : "x");
38366  
38367		ScrollTrigger$1.addEventListener("refresh", onResize);
38368  
38369		_addListener$1(_win$1, "resize", onResize);
38370  
38371		if (scrollFuncY.smooth) {
38372		  scrollFuncY.target.style.scrollBehavior = "auto";
38373		  scrollFuncY.smooth = scrollFuncX.smooth = false;
38374		}
38375  
38376		inputObserver.enable();
38377	  };
38378  
38379	  vars.onDisable = function () {
38380		_allowNativePanning(target, true);
38381  
38382		_removeListener$1(_win$1, "resize", onResize);
38383  
38384		ScrollTrigger$1.removeEventListener("refresh", onResize);
38385		inputObserver.kill();
38386	  };
38387  
38388	  vars.lockAxis = vars.lockAxis !== false;
38389	  self = new Observer(vars);
38390	  self.iOS = _fixIOSBug;
38391	  _fixIOSBug && !scrollFuncY() && scrollFuncY(1);
38392	  _fixIOSBug && gsap$1.ticker.add(_passThrough);
38393	  onStopDelayedCall = self._dc;
38394	  tween = gsap$1.to(self, {
38395		ease: "power4",
38396		paused: true,
38397		inherit: false,
38398		scrollX: normalizeScrollX ? "+=0.1" : "+=0",
38399		scrollY: "+=0.1",
38400		modifiers: {
38401		  scrollY: _interruptionTracker(scrollFuncY, scrollFuncY(), function () {
38402			return tween.pause();
38403		  })
38404		},
38405		onUpdate: _updateAll,
38406		onComplete: onStopDelayedCall.vars.onComplete
38407	  });
38408	  return self;
38409	};
38410  
38411	ScrollTrigger$1.sort = function (func) {
38412	  return _triggers.sort(func || function (a, b) {
38413		return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6);
38414	  });
38415	};
38416  
38417	ScrollTrigger$1.observe = function (vars) {
38418	  return new Observer(vars);
38419	};
38420  
38421	ScrollTrigger$1.normalizeScroll = function (vars) {
38422	  if (typeof vars === "undefined") {
38423		return _normalizer$1;
38424	  }
38425  
38426	  if (vars === true && _normalizer$1) {
38427		return _normalizer$1.enable();
38428	  }
38429  
38430	  if (vars === false) {
38431		_normalizer$1 && _normalizer$1.kill();
38432		_normalizer$1 = vars;
38433		return;
38434	  }
38435  
38436	  var normalizer = vars instanceof Observer ? vars : _getScrollNormalizer(vars);
38437	  _normalizer$1 && _normalizer$1.target === normalizer.target && _normalizer$1.kill();
38438	  _isViewport$1(normalizer.target) && (_normalizer$1 = normalizer);
38439	  return normalizer;
38440	};
38441  
38442	ScrollTrigger$1.core = {
38443	  _getVelocityProp: _getVelocityProp,
38444	  _inputObserver: _inputObserver,
38445	  _scrollers: _scrollers,
38446	  _proxies: _proxies,
38447	  bridge: {
38448		ss: function ss() {
38449		  _lastScrollTime || _dispatch("scrollStart");
38450		  _lastScrollTime = _getTime$1();
38451		},
38452		ref: function ref() {
38453		  return _refreshing;
38454		}
38455	  }
38456	};
38457	_getGSAP$1() && gsap$1.registerPlugin(ScrollTrigger$1);
38458  
38459	exports.ScrollTrigger = ScrollTrigger$1;
38460	exports.default = ScrollTrigger$1;
38461  
38462	if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;}
38463  
38464  })));
38465
38466/*!
38467 * CustomEase 3.12.7
38468 * https://gsap.com
38469 * 
38470 * @license Copyright 2025, GreenSock. All rights reserved.
38471 * Subject to the terms at https://gsap.com/standard-license or for Club GSAP members, the agreement issued with that membership.
38472 * @author: Jack Doyle, [email protected]
38473 */
38474
38475  (function (global, factory) {
38476	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
38477	typeof define === 'function' && define.amd ? define(['exports'], factory) :
38478	(global = global || self, factory(global.window = global.window || {}));
38479}(this, (function (exports) { 'use strict';
38480
38481	var _svgPathExp = /[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
38482	    _scientific = /[\+\-]?\d*\.?\d+e[\+\-]?\d+/ig,
38483	    _DEG2RAD = Math.PI / 180,
38484	    _sin = Math.sin,
38485	    _cos = Math.cos,
38486	    _abs = Math.abs,
38487	    _sqrt = Math.sqrt,
38488	    _isNumber = function _isNumber(value) {
38489	  return typeof value === "number";
38490	},
38491	    _roundingNum = 1e5,
38492	    _round = function _round(value) {
38493	  return Math.round(value * _roundingNum) / _roundingNum || 0;
38494	};
38495	function transformRawPath(rawPath, a, b, c, d, tx, ty) {
38496	  var j = rawPath.length,
38497	      segment,
38498	      l,
38499	      i,
38500	      x,
38501	      y;
38502
38503	  while (--j > -1) {
38504	    segment = rawPath[j];
38505	    l = segment.length;
38506
38507	    for (i = 0; i < l; i += 2) {
38508	      x = segment[i];
38509	      y = segment[i + 1];
38510	      segment[i] = x * a + y * c + tx;
38511	      segment[i + 1] = x * b + y * d + ty;
38512	    }
38513	  }
38514
38515	  rawPath._dirty = 1;
38516	  return rawPath;
38517	}
38518
38519	function arcToSegment(lastX, lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y) {
38520	  if (lastX === x && lastY === y) {
38521	    return;
38522	  }
38523
38524	  rx = _abs(rx);
38525	  ry = _abs(ry);
38526
38527	  var angleRad = angle % 360 * _DEG2RAD,
38528	      cosAngle = _cos(angleRad),
38529	      sinAngle = _sin(angleRad),
38530	      PI = Math.PI,
38531	      TWOPI = PI * 2,
38532	      dx2 = (lastX - x) / 2,
38533	      dy2 = (lastY - y) / 2,
38534	      x1 = cosAngle * dx2 + sinAngle * dy2,
38535	      y1 = -sinAngle * dx2 + cosAngle * dy2,
38536	      x1_sq = x1 * x1,
38537	      y1_sq = y1 * y1,
38538	      radiiCheck = x1_sq / (rx * rx) + y1_sq / (ry * ry);
38539
38540	  if (radiiCheck > 1) {
38541	    rx = _sqrt(radiiCheck) * rx;
38542	    ry = _sqrt(radiiCheck) * ry;
38543	  }
38544
38545	  var rx_sq = rx * rx,
38546	      ry_sq = ry * ry,
38547	      sq = (rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq) / (rx_sq * y1_sq + ry_sq * x1_sq);
38548
38549	  if (sq < 0) {
38550	    sq = 0;
38551	  }
38552
38553	  var coef = (largeArcFlag === sweepFlag ? -1 : 1) * _sqrt(sq),
38554	      cx1 = coef * (rx * y1 / ry),
38555	      cy1 = coef * -(ry * x1 / rx),
38556	      sx2 = (lastX + x) / 2,
38557	      sy2 = (lastY + y) / 2,
38558	      cx = sx2 + (cosAngle * cx1 - sinAngle * cy1),
38559	      cy = sy2 + (sinAngle * cx1 + cosAngle * cy1),
38560	      ux = (x1 - cx1) / rx,
38561	      uy = (y1 - cy1) / ry,
38562	      vx = (-x1 - cx1) / rx,
38563	      vy = (-y1 - cy1) / ry,
38564	      temp = ux * ux + uy * uy,
38565	      angleStart = (uy < 0 ? -1 : 1) * Math.acos(ux / _sqrt(temp)),
38566	      angleExtent = (ux * vy - uy * vx < 0 ? -1 : 1) * Math.acos((ux * vx + uy * vy) / _sqrt(temp * (vx * vx + vy * vy)));
38567
38568	  isNaN(angleExtent) && (angleExtent = PI);
38569
38570	  if (!sweepFlag && angleExtent > 0) {
38571	    angleExtent -= TWOPI;
38572	  } else if (sweepFlag && angleExtent < 0) {
38573	    angleExtent += TWOPI;
38574	  }
38575
38576	  angleStart %= TWOPI;
38577	  angleExtent %= TWOPI;
38578
38579	  var segments = Math.ceil(_abs(angleExtent) / (TWOPI / 4)),
38580	      rawPath = [],
38581	      angleIncrement = angleExtent / segments,
38582	      controlLength = 4 / 3 * _sin(angleIncrement / 2) / (1 + _cos(angleIncrement / 2)),
38583	      ma = cosAngle * rx,
38584	      mb = sinAngle * rx,
38585	      mc = sinAngle * -ry,
38586	      md = cosAngle * ry,
38587	      i;
38588
38589	  for (i = 0; i < segments; i++) {
38590	    angle = angleStart + i * angleIncrement;
38591	    x1 = _cos(angle);
38592	    y1 = _sin(angle);
38593	    ux = _cos(angle += angleIncrement);
38594	    uy = _sin(angle);
38595	    rawPath.push(x1 - controlLength * y1, y1 + controlLength * x1, ux + controlLength * uy, uy - controlLength * ux, ux, uy);
38596	  }
38597
38598	  for (i = 0; i < rawPath.length; i += 2) {
38599	    x1 = rawPath[i];
38600	    y1 = rawPath[i + 1];
38601	    rawPath[i] = x1 * ma + y1 * mc + cx;
38602	    rawPath[i + 1] = x1 * mb + y1 * md + cy;
38603	  }
38604
38605	  rawPath[i - 2] = x;
38606	  rawPath[i - 1] = y;
38607	  return rawPath;
38608	}
38609
38610	function stringToRawPath(d) {
38611	  var a = (d + "").replace(_scientific, function (m) {
38612	    var n = +m;
38613	    return n < 0.0001 && n > -0.0001 ? 0 : n;
38614	  }).match(_svgPathExp) || [],
38615	      path = [],
38616	      relativeX = 0,
38617	      relativeY = 0,
38618	      twoThirds = 2 / 3,
38619	      elements = a.length,
38620	      points = 0,
38621	      errorMessage = "ERROR: malformed path: " + d,
38622	      i,
38623	      j,
38624	      x,
38625	      y,
38626	      command,
38627	      isRelative,
38628	      segment,
38629	      startX,
38630	      startY,
38631	      difX,
38632	      difY,
38633	      beziers,
38634	      prevCommand,
38635	      flag1,
38636	      flag2,
38637	      line = function line(sx, sy, ex, ey) {
38638	    difX = (ex - sx) / 3;
38639	    difY = (ey - sy) / 3;
38640	    segment.push(sx + difX, sy + difY, ex - difX, ey - difY, ex, ey);
38641	  };
38642
38643	  if (!d || !isNaN(a[0]) || isNaN(a[1])) {
38644	    console.log(errorMessage);
38645	    return path;
38646	  }
38647
38648	  for (i = 0; i < elements; i++) {
38649	    prevCommand = command;
38650
38651	    if (isNaN(a[i])) {
38652	      command = a[i].toUpperCase();
38653	      isRelative = command !== a[i];
38654	    } else {
38655	      i--;
38656	    }
38657
38658	    x = +a[i + 1];
38659	    y = +a[i + 2];
38660
38661	    if (isRelative) {
38662	      x += relativeX;
38663	      y += relativeY;
38664	    }
38665
38666	    if (!i) {
38667	      startX = x;
38668	      startY = y;
38669	    }
38670
38671	    if (command === "M") {
38672	      if (segment) {
38673	        if (segment.length < 8) {
38674	          path.length -= 1;
38675	        } else {
38676	          points += segment.length;
38677	        }
38678	      }
38679
38680	      relativeX = startX = x;
38681	      relativeY = startY = y;
38682	      segment = [x, y];
38683	      path.push(segment);
38684	      i += 2;
38685	      command = "L";
38686	    } else if (command === "C") {
38687	      if (!segment) {
38688	        segment = [0, 0];
38689	      }
38690
38691	      if (!isRelative) {
38692	        relativeX = relativeY = 0;
38693	      }
38694
38695	      segment.push(x, y, relativeX + a[i + 3] * 1, relativeY + a[i + 4] * 1, relativeX += a[i + 5] * 1, relativeY += a[i + 6] * 1);
38696	      i += 6;
38697	    } else if (command === "S") {
38698	      difX = relativeX;
38699	      difY = relativeY;
38700
38701	      if (prevCommand === "C" || prevCommand === "S") {
38702	        difX += relativeX - segment[segment.length - 4];
38703	        difY += relativeY - segment[segment.length - 3];
38704	      }
38705
38706	      if (!isRelative) {
38707	        relativeX = relativeY = 0;
38708	      }
38709
38710	      segment.push(difX, difY, x, y, relativeX += a[i + 3] * 1, relativeY += a[i + 4] * 1);
38711	      i += 4;
38712	    } else if (command === "Q") {
38713	      difX = relativeX + (x - relativeX) * twoThirds;
38714	      difY = relativeY + (y - relativeY) * twoThirds;
38715
38716	      if (!isRelative) {
38717	        relativeX = relativeY = 0;
38718	      }
38719
38720	      relativeX += a[i + 3] * 1;
38721	      relativeY += a[i + 4] * 1;
38722	      segment.push(difX, difY, relativeX + (x - relativeX) * twoThirds, relativeY + (y - relativeY) * twoThirds, relativeX, relativeY);
38723	      i += 4;
38724	    } else if (command === "T") {
38725	      difX = relativeX - segment[segment.length - 4];
38726	      difY = relativeY - segment[segment.length - 3];
38727	      segment.push(relativeX + difX, relativeY + difY, x + (relativeX + difX * 1.5 - x) * twoThirds, y + (relativeY + difY * 1.5 - y) * twoThirds, relativeX = x, relativeY = y);
38728	      i += 2;
38729	    } else if (command === "H") {
38730	      line(relativeX, relativeY, relativeX = x, relativeY);
38731	      i += 1;
38732	    } else if (command === "V") {
38733	      line(relativeX, relativeY, relativeX, relativeY = x + (isRelative ? relativeY - relativeX : 0));
38734	      i += 1;
38735	    } else if (command === "L" || command === "Z") {
38736	      if (command === "Z") {
38737	        x = startX;
38738	        y = startY;
38739	        segment.closed = true;
38740	      }
38741
38742	      if (command === "L" || _abs(relativeX - x) > 0.5 || _abs(relativeY - y) > 0.5) {
38743	        line(relativeX, relativeY, x, y);
38744
38745	        if (command === "L") {
38746	          i += 2;
38747	        }
38748	      }
38749
38750	      relativeX = x;
38751	      relativeY = y;
38752	    } else if (command === "A") {
38753	      flag1 = a[i + 4];
38754	      flag2 = a[i + 5];
38755	      difX = a[i + 6];
38756	      difY = a[i + 7];
38757	      j = 7;
38758
38759	      if (flag1.length > 1) {
38760	        if (flag1.length < 3) {
38761	          difY = difX;
38762	          difX = flag2;
38763	          j--;
38764	        } else {
38765	          difY = flag2;
38766	          difX = flag1.substr(2);
38767	          j -= 2;
38768	        }
38769
38770	        flag2 = flag1.charAt(1);
38771	        flag1 = flag1.charAt(0);
38772	      }
38773
38774	      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);
38775	      i += j;
38776
38777	      if (beziers) {
38778	        for (j = 0; j < beziers.length; j++) {
38779	          segment.push(beziers[j]);
38780	        }
38781	      }
38782
38783	      relativeX = segment[segment.length - 2];
38784	      relativeY = segment[segment.length - 1];
38785	    } else {
38786	      console.log(errorMessage);
38787	    }
38788	  }
38789
38790	  i = segment.length;
38791
38792	  if (i < 6) {
38793	    path.pop();
38794	    i = 0;
38795	  } else if (segment[0] === segment[i - 2] && segment[1] === segment[i - 1]) {
38796	    segment.closed = true;
38797	  }
38798
38799	  path.totalPoints = points + i;
38800	  return path;
38801	}
38802	function rawPathToString(rawPath) {
38803	  if (_isNumber(rawPath[0])) {
38804	    rawPath = [rawPath];
38805	  }
38806
38807	  var result = "",
38808	      l = rawPath.length,
38809	      sl,
38810	      s,
38811	      i,
38812	      segment;
38813
38814	  for (s = 0; s < l; s++) {
38815	    segment = rawPath[s];
38816	    result += "M" + _round(segment[0]) + "," + _round(segment[1]) + " C";
38817	    sl = segment.length;
38818
38819	    for (i = 2; i < sl; i++) {
38820	      result += _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i]) + " ";
38821	    }
38822
38823	    if (segment.closed) {
38824	      result += "z";
38825	    }
38826	  }
38827
38828	  return result;
38829	}
38830
38831	/*!
38832	 * CustomEase 3.12.7
38833	 * https://gsap.com
38834	 *
38835	 * @license Copyright 2008-2025, GreenSock. All rights reserved.
38836	 * Subject to the terms at https://gsap.com/standard-license or for
38837	 * Club GSAP members, the agreement issued with that membership.
38838	 * @author: Jack Doyle, [email protected]
38839	*/
38840
38841	var gsap,
38842	    _coreInitted,
38843	    _getGSAP = function _getGSAP() {
38844	  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;
38845	},
38846	    _initCore = function _initCore() {
38847	  gsap = _getGSAP();
38848
38849	  if (gsap) {
38850	    gsap.registerEase("_CE", CustomEase.create);
38851	    _coreInitted = 1;
38852	  } else {
38853	    console.warn("Please gsap.registerPlugin(CustomEase)");
38854	  }
38855	},
38856	    _bigNum = 1e20,
38857	    _round$1 = function _round(value) {
38858	  return ~~(value * 1000 + (value < 0 ? -.5 : .5)) / 1000;
38859	},
38860	    _numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/gi,
38861	    _needsParsingExp = /[cLlsSaAhHvVtTqQ]/g,
38862	    _findMinimum = function _findMinimum(values) {
38863	  var l = values.length,
38864	      min = _bigNum,
38865	      i;
38866
38867	  for (i = 1; i < l; i += 6) {
38868	    +values[i] < min && (min = +values[i]);
38869	  }
38870
38871	  return min;
38872	},
38873	    _normalize = function _normalize(values, height, originY) {
38874	  if (!originY && originY !== 0) {
38875	    originY = Math.max(+values[values.length - 1], +values[1]);
38876	  }
38877
38878	  var tx = +values[0] * -1,
38879	      ty = -originY,
38880	      l = values.length,
38881	      sx = 1 / (+values[l - 2] + tx),
38882	      sy = -height || (Math.abs(+values[l - 1] - +values[1]) < 0.01 * (+values[l - 2] - +values[0]) ? _findMinimum(values) + ty : +values[l - 1] + ty),
38883	      i;
38884
38885	  if (sy) {
38886	    sy = 1 / sy;
38887	  } else {
38888	    sy = -sx;
38889	  }
38890
38891	  for (i = 0; i < l; i += 2) {
38892	    values[i] = (+values[i] + tx) * sx;
38893	    values[i + 1] = (+values[i + 1] + ty) * sy;
38894	  }
38895	},
38896	    _bezierToPoints = function _bezierToPoints(x1, y1, x2, y2, x3, y3, x4, y4, threshold, points, index) {
38897	  var x12 = (x1 + x2) / 2,
38898	      y12 = (y1 + y2) / 2,
38899	      x23 = (x2 + x3) / 2,
38900	      y23 = (y2 + y3) / 2,
38901	      x34 = (x3 + x4) / 2,
38902	      y34 = (y3 + y4) / 2,
38903	      x123 = (x12 + x23) / 2,
38904	      y123 = (y12 + y23) / 2,
38905	      x234 = (x23 + x34) / 2,
38906	      y234 = (y23 + y34) / 2,
38907	      x1234 = (x123 + x234) / 2,
38908	      y1234 = (y123 + y234) / 2,
38909	      dx = x4 - x1,
38910	      dy = y4 - y1,
38911	      d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx),
38912	      d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx),
38913	      length;
38914
38915	  if (!points) {
38916	    points = [{
38917	      x: x1,
38918	      y: y1
38919	    }, {
38920	      x: x4,
38921	      y: y4
38922	    }];
38923	    index = 1;
38924	  }
38925
38926	  points.splice(index || points.length - 1, 0, {
38927	    x: x1234,
38928	    y: y1234
38929	  });
38930
38931	  if ((d2 + d3) * (d2 + d3) > threshold * (dx * dx + dy * dy)) {
38932	    length = points.length;
38933
38934	    _bezierToPoints(x1, y1, x12, y12, x123, y123, x1234, y1234, threshold, points, index);
38935
38936	    _bezierToPoints(x1234, y1234, x234, y234, x34, y34, x4, y4, threshold, points, index + 1 + (points.length - length));
38937	  }
38938
38939	  return points;
38940	};
38941
38942	var CustomEase = function () {
38943	  function CustomEase(id, data, config) {
38944	    _coreInitted || _initCore();
38945	    this.id = id;
38946	     this.setData(data, config);
38947	  }
38948
38949	  var _proto = CustomEase.prototype;
38950
38951	  _proto.setData = function setData(data, config) {
38952	    config = config || {};
38953	    data = data || "0,0,1,1";
38954	    var values = data.match(_numExp),
38955	        closest = 1,
38956	        points = [],
38957	        lookup = [],
38958	        precision = config.precision || 1,
38959	        fast = precision <= 1,
38960	        l,
38961	        a1,
38962	        a2,
38963	        i,
38964	        inc,
38965	        j,
38966	        point,
38967	        prevPoint,
38968	        p;
38969	    this.data = data;
38970
38971	    if (_needsParsingExp.test(data) || ~data.indexOf("M") && data.indexOf("C") < 0) {
38972	      values = stringToRawPath(data)[0];
38973	    }
38974
38975	    l = values.length;
38976
38977	    if (l === 4) {
38978	      values.unshift(0, 0);
38979	      values.push(1, 1);
38980	      l = 8;
38981	    } else if ((l - 2) % 6) {
38982	      throw "Invalid CustomEase";
38983	    }
38984
38985	    if (+values[0] !== 0 || +values[l - 2] !== 1) {
38986	      _normalize(values, config.height, config.originY);
38987	    }
38988
38989	    this.segment = values;
38990
38991	    for (i = 2; i < l; i += 6) {
38992	      a1 = {
38993	        x: +values[i - 2],
38994	        y: +values[i - 1]
38995	      };
38996	      a2 = {
38997	        x: +values[i + 4],
38998	        y: +values[i + 5]
38999	      };
39000	      points.push(a1, a2);
39001
39002	      _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);
39003	    }
39004
39005	    l = points.length;
39006
39007	    for (i = 0; i < l; i++) {
39008	      point = points[i];
39009	      prevPoint = points[i - 1] || point;
39010
39011	      if ((point.x > prevPoint.x || prevPoint.y !== point.y && prevPoint.x === point.x || point === prevPoint) && point.x <= 1) {
39012	        prevPoint.cx = point.x - prevPoint.x;
39013	        prevPoint.cy = point.y - prevPoint.y;
39014	        prevPoint.n = point;
39015	        prevPoint.nx = point.x;
39016
39017	        if (fast && i > 1 && Math.abs(prevPoint.cy / prevPoint.cx - points[i - 2].cy / points[i - 2].cx) > 2) {
39018	          fast = 0;
39019	        }
39020
39021	        if (prevPoint.cx < closest) {
39022	          if (!prevPoint.cx) {
39023	            prevPoint.cx = 0.001;
39024
39025	            if (i === l - 1) {
39026	              prevPoint.x -= 0.001;
39027	              closest = Math.min(closest, 0.001);
39028	              fast = 0;
39029	            }
39030	          } else {
39031	            closest = prevPoint.cx;
39032	          }
39033	        }
39034	      } else {
39035	        points.splice(i--, 1);
39036	        l--;
39037	      }
39038	    }
39039
39040	    l = 1 / closest + 1 | 0;
39041	    inc = 1 / l;
39042	    j = 0;
39043	    point = points[0];
39044
39045	    if (fast) {
39046	      for (i = 0; i < l; i++) {
39047	        p = i * inc;
39048
39049	        if (point.nx < p) {
39050	          point = points[++j];
39051	        }
39052
39053	        a1 = point.y + (p - point.x) / point.cx * point.cy;
39054	        lookup[i] = {
39055	          x: p,
39056	          cx: inc,
39057	          y: a1,
39058	          cy: 0,
39059	          nx: 9
39060	        };
39061
39062	        if (i) {
39063	          lookup[i - 1].cy = a1 - lookup[i - 1].y;
39064	        }
39065	      }
39066
39067	      j = points[points.length - 1];
39068	      lookup[l - 1].cy = j.y - a1;
39069	      lookup[l - 1].cx = j.x - lookup[lookup.length - 1].x;
39070	    } else {
39071	      for (i = 0; i < l; i++) {
39072	        if (point.nx < i * inc) {
39073	          point = points[++j];
39074	        }
39075
39076	        lookup[i] = point;
39077	      }
39078
39079	      if (j < points.length - 1) {
39080	        lookup[i - 1] = points[points.length - 2];
39081	      }
39082	    }
39083
39084	    this.ease = function (p) {
39085	      var point = lookup[p * l | 0] || lookup[l - 1];
39086
39087	      if (point.nx < p) {
39088	        point = point.n;
39089	      }
39090
39091	      return point.y + (p - point.x) / point.cx * point.cy;
39092	    };
39093
39094	    this.ease.custom = this;
39095	    this.id && gsap && gsap.registerEase(this.id, this.ease);
39096	    return this;
39097	  };
39098
39099	  _proto.getSVGData = function getSVGData(config) {
39100	    return CustomEase.getSVGData(this, config);
39101	  };
39102
39103	  CustomEase.create = function create(id, data, config) {
39104	    return new CustomEase(id, data, config).ease;
39105	  };
39106
39107	  CustomEase.register = function register(core) {
39108	    gsap = core;
39109
39110	    _initCore();
39111	  };
39112
39113	  CustomEase.get = function get(id) {
39114	    return gsap.parseEase(id);
39115	  };
39116
39117	  CustomEase.getSVGData = function getSVGData(ease, config) {
39118	    config = config || {};
39119	    var width = config.width || 100,
39120	        height = config.height || 100,
39121	        x = config.x || 0,
39122	        y = (config.y || 0) + height,
39123	        e = gsap.utils.toArray(config.path)[0],
39124	        a,
39125	        slope,
39126	        i,
39127	        inc,
39128	        tx,
39129	        ty,
39130	        precision,
39131	        threshold,
39132	        prevX,
39133	        prevY;
39134
39135	    if (config.invert) {
39136	      height = -height;
39137	      y = 0;
39138	    }
39139
39140	    if (typeof ease === "string") {
39141	      ease = gsap.parseEase(ease);
39142	    }
39143
39144	    if (ease.custom) {
39145	      ease = ease.custom;
39146	    }
39147
39148	    if (ease instanceof CustomEase) {
39149	      a = rawPathToString(transformRawPath([ease.segment], width, 0, 0, -height, x, y));
39150	    } else {
39151	      a = [x, y];
39152	      precision = Math.max(5, (config.precision || 1) * 200);
39153	      inc = 1 / precision;
39154	      precision += 2;
39155	      threshold = 5 / precision;
39156	      prevX = _round$1(x + inc * width);
39157	      prevY = _round$1(y + ease(inc) * -height);
39158	      slope = (prevY - y) / (prevX - x);
39159
39160	      for (i = 2; i < precision; i++) {
39161	        tx = _round$1(x + i * inc * width);
39162	        ty = _round$1(y + ease(i * inc) * -height);
39163
39164	        if (Math.abs((ty - prevY) / (tx - prevX) - slope) > threshold || i === precision - 1) {
39165	          a.push(prevX, prevY);
39166	          slope = (ty - prevY) / (tx - prevX);
39167	        }
39168
39169	        prevX = tx;
39170	        prevY = ty;
39171	      }
39172
39173	      a = "M" + a.join(",");
39174	    }
39175
39176	    e && e.setAttribute("d", a);
39177	    return a;
39178	  };
39179
39180	  return CustomEase;
39181	}();
39182	CustomEase.version = "3.12.7";
39183	CustomEase.headless = true;
39184	_getGSAP() && gsap.registerPlugin(CustomEase);
39185
39186	exports.CustomEase = CustomEase;
39187	exports.default = CustomEase;
39188
39189	Object.defineProperty(exports, '__esModule', { value: true });
39190
39191})));
39192(function (global, factory) {
39193  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
39194  typeof define === 'function' && define.amd ? define(['exports'], factory) :
39195  (global = global || self, factory(global.window = global.window || {}));
39196}(this, (function (exports) { 'use strict';
39197
39198  function _inheritsLoose(subClass, superClass) {
39199    subClass.prototype = Object.create(superClass.prototype);
39200    subClass.prototype.constructor = subClass;
39201    subClass.__proto__ = superClass;
39202  }
39203
39204  function _assertThisInitialized(self) {
39205    if (self === void 0) {
39206      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
39207    }
39208
39209    return self;
39210  }
39211
39212  var _doc,
39213      _win,
39214      _docElement,
39215      _body,
39216      _divContainer,
39217      _svgContainer,
39218      _identityMatrix,
39219      _gEl,
39220      _transformProp = "transform",
39221      _transformOriginProp = _transformProp + "Origin",
39222      _hasOffsetBug,
39223      _setDoc = function _setDoc(element) {
39224    var doc = element.ownerDocument || element;
39225
39226    if (!(_transformProp in element.style) && "msTransform" in element.style) {
39227      _transformProp = "msTransform";
39228      _transformOriginProp = _transformProp + "Origin";
39229    }
39230
39231    while (doc.parentNode && (doc = doc.parentNode)) {}
39232
39233    _win = window;
39234    _identityMatrix = new Matrix2D();
39235
39236    if (doc) {
39237      _doc = doc;
39238      _docElement = doc.documentElement;
39239      _body = doc.body;
39240      _gEl = _doc.createElementNS("http://www.w3.org/2000/svg", "g");
39241      _gEl.style.transform = "none";
39242      var d1 = doc.createElement("div"),
39243          d2 = doc.createElement("div"),
39244          root = doc && (doc.body || doc.firstElementChild);
39245
39246      if (root && root.appendChild) {
39247        root.appendChild(d1);
39248        d1.appendChild(d2);
39249        d1.setAttribute("style", "position:static;transform:translate3d(0,0,1px)");
39250        _hasOffsetBug = d2.offsetParent !== d1;
39251        root.removeChild(d1);
39252      }
39253    }
39254
39255    return doc;
39256  },
39257      _forceNonZeroScale = function _forceNonZeroScale(e) {
39258    var a, cache;
39259
39260    while (e && e !== _body) {
39261      cache = e._gsap;
39262      cache && cache.uncache && cache.get(e, "x");
39263
39264      if (cache && !cache.scaleX && !cache.scaleY && cache.renderTransform) {
39265        cache.scaleX = cache.scaleY = 1e-4;
39266        cache.renderTransform(1, cache);
39267        a ? a.push(cache) : a = [cache];
39268      }
39269
39270      e = e.parentNode;
39271    }
39272
39273    return a;
39274  },
39275      _svgTemps = [],
39276      _divTemps = [],
39277      _getDocScrollTop = function _getDocScrollTop() {
39278    return _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0;
39279  },
39280      _getDocScrollLeft = function _getDocScrollLeft() {
39281    return _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0;
39282  },
39283      _svgOwner = function _svgOwner(element) {
39284    return element.ownerSVGElement || ((element.tagName + "").toLowerCase() === "svg" ? element : null);
39285  },
39286      _isFixed = function _isFixed(element) {
39287    if (_win.getComputedStyle(element).position === "fixed") {
39288      return true;
39289    }
39290
39291    element = element.parentNode;
39292
39293    if (element && element.nodeType === 1) {
39294      return _isFixed(element);
39295    }
39296  },
39297      _createSibling = function _createSibling(element, i) {
39298    if (element.parentNode && (_doc || _setDoc(element))) {
39299      var svg = _svgOwner(element),
39300          ns = svg ? svg.getAttribute("xmlns") || "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml",
39301          type = svg ? i ? "rect" : "g" : "div",
39302          x = i !== 2 ? 0 : 100,
39303          y = i === 3 ? 100 : 0,
39304          css = "position:absolute;display:block;pointer-events:none;margin:0;padding:0;",
39305          e = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, "http"), type) : _doc.createElement(type);
39306
39307      if (i) {
39308        if (!svg) {
39309          if (!_divContainer) {
39310            _divContainer = _createSibling(element);
39311            _divContainer.style.cssText = css;
39312          }
39313
39314          e.style.cssText = css + "width:0.1px;height:0.1px;top:" + y + "px;left:" + x + "px";
39315
39316          _divContainer.appendChild(e);
39317        } else {
39318          _svgContainer || (_svgContainer = _createSibling(element));
39319          e.setAttribute("width", 0.01);
39320          e.setAttribute("height", 0.01);
39321          e.setAttribute("transform", "translate(" + x + "," + y + ")");
39322
39323          _svgContainer.appendChild(e);
39324        }
39325      }
39326
39327      return e;
39328    }
39329
39330    throw "Need document and parent.";
39331  },
39332      _consolidate = function _consolidate(m) {
39333    var c = new Matrix2D(),
39334        i = 0;
39335
39336    for (; i < m.numberOfItems; i++) {
39337      c.multiply(m.getItem(i).matrix);
39338    }
39339
39340    return c;
39341  },
39342      _getCTM = function _getCTM(svg) {
39343    var m = svg.getCTM(),
39344        transform;
39345
39346    if (!m) {
39347      transform = svg.style[_transformProp];
39348      svg.style[_transformProp] = "none";
39349      svg.appendChild(_gEl);
39350      m = _gEl.getCTM();
39351      svg.removeChild(_gEl);
39352      transform ? svg.style[_transformProp] = transform : svg.style.removeProperty(_transformProp.replace(/([A-Z])/g, "-$1").toLowerCase());
39353    }
39354
39355    return m || _identityMatrix.clone();
39356  },
39357      _placeSiblings = function _placeSiblings(element, adjustGOffset) {
39358    var svg = _svgOwner(element),
39359        isRootSVG = element === svg,
39360        siblings = svg ? _svgTemps : _divTemps,
39361        parent = element.parentNode,
39362        container,
39363        m,
39364        b,
39365        x,
39366        y,
39367        cs;
39368
39369    if (element === _win) {
39370      return element;
39371    }
39372
39373    siblings.length || siblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3));
39374    container = svg ? _svgContainer : _divContainer;
39375
39376    if (svg) {
39377      if (isRootSVG) {
39378        b = _getCTM(element);
39379        x = -b.e / b.a;
39380        y = -b.f / b.d;
39381        m = _identityMatrix;
39382      } else if (element.getBBox) {
39383        b = element.getBBox();
39384        m = element.transform ? element.transform.baseVal : {};
39385        m = !m.numberOfItems ? _identityMatrix : m.numberOfItems > 1 ? _consolidate(m) : m.getItem(0).matrix;
39386        x = m.a * b.x + m.c * b.y;
39387        y = m.b * b.x + m.d * b.y;
39388      } else {
39389        m = new Matrix2D();
39390        x = y = 0;
39391      }
39392
39393      if (adjustGOffset && element.tagName.toLowerCase() === "g") {
39394        x = y = 0;
39395      }
39396
39397      (isRootSVG ? svg : parent).appendChild(container);
vendor: 1,139 bytes, lines 39398-39433
39398      container.setAttribute("transform", "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + (m.e + x) + "," + (m.f + y) + ")");
39399    } else {
39400      x = y = 0;
39401
39402      if (_hasOffsetBug) {
39403        m = element.offsetParent;
39404        b = element;
39405
39406        while (b && (b = b.parentNode) && b !== m && b.parentNode) {
39407          if ((_win.getComputedStyle(b)[_transformProp] + "").length > 4) {
39408            x = b.offsetLeft;
39409            y = b.offsetTop;
39410            b = 0;
39411          }
39412        }
39413      }
39414
39415      cs = _win.getComputedStyle(element);
39416
39417      if (cs.position !== "absolute" && cs.position !== "fixed") {
39418        m = element.offsetParent;
39419
39420        while (parent && parent !== m) {
39421          x += parent.scrollLeft || 0;
39422          y += parent.scrollTop || 0;
39423          parent = parent.parentNode;
39424        }
39425      }
39426
39427      b = container.style;
39428      b.top = element.offsetTop - y + "px";
39429      b.left = element.offsetLeft - x + "px";
39430      b[_transformProp] = cs[_transformProp];
39431      b[_transformOriginProp] = cs[_transformOriginProp];
39432      b.position = cs.position === "fixed" ? "fixed" : "absolute";
39433      element.parentNode
vendor: 37,456 bytes, lines 39433-40688
39433.appendChild(container);
39434    }
39435
39436    return container;
39437  },
39438      _setMatrix = function _setMatrix(m, a, b, c, d, e, f) {
39439    m.a = a;
39440    m.b = b;
39441    m.c = c;
39442    m.d = d;
39443    m.e = e;
39444    m.f = f;
39445    return m;
39446  };
39447
39448  var Matrix2D = function () {
39449    function Matrix2D(a, b, c, d, e, f) {
39450      if (a === void 0) {
39451        a = 1;
39452      }
39453
39454      if (b === void 0) {
39455        b = 0;
39456      }
39457
39458      if (c === void 0) {
39459        c = 0;
39460      }
39461
39462      if (d === void 0) {
39463        d = 1;
39464      }
39465
39466      if (e === void 0) {
39467        e = 0;
39468      }
39469
39470      if (f === void 0) {
39471        f = 0;
39472      }
39473
39474      _setMatrix(this, a, b, c, d, e, f);
39475    }
39476
39477    var _proto = Matrix2D.prototype;
39478
39479    _proto.inverse = function inverse() {
39480      var a = this.a,
39481          b = this.b,
39482          c = this.c,
39483          d = this.d,
39484          e = this.e,
39485          f = this.f,
39486          determinant = a * d - b * c || 1e-10;
39487      return _setMatrix(this, d / determinant, -b / determinant, -c / determinant, a / determinant, (c * f - d * e) / determinant, -(a * f - b * e) / determinant);
39488    };
39489
39490    _proto.multiply = function multiply(matrix) {
39491      var a = this.a,
39492          b = this.b,
39493          c = this.c,
39494          d = this.d,
39495          e = this.e,
39496          f = this.f,
39497          a2 = matrix.a,
39498          b2 = matrix.c,
39499          c2 = matrix.b,
39500          d2 = matrix.d,
39501          e2 = matrix.e,
39502          f2 = matrix.f;
39503      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);
39504    };
39505
39506    _proto.clone = function clone() {
39507      return new Matrix2D(this.a, this.b, this.c, this.d, this.e, this.f);
39508    };
39509
39510    _proto.equals = function equals(matrix) {
39511      var a = this.a,
39512          b = this.b,
39513          c = this.c,
39514          d = this.d,
39515          e = this.e,
39516          f = this.f;
39517      return a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f;
39518    };
39519
39520    _proto.apply = function apply(point, decoratee) {
39521      if (decoratee === void 0) {
39522        decoratee = {};
39523      }
39524
39525      var x = point.x,
39526          y = point.y,
39527          a = this.a,
39528          b = this.b,
39529          c = this.c,
39530          d = this.d,
39531          e = this.e,
39532          f = this.f;
39533      decoratee.x = x * a + y * c + e || 0;
39534      decoratee.y = x * b + y * d + f || 0;
39535      return decoratee;
39536    };
39537
39538    return Matrix2D;
39539  }();
39540  function getGlobalMatrix(element, inverse, adjustGOffset, includeScrollInFixed) {
39541    if (!element || !element.parentNode || (_doc || _setDoc(element)).documentElement === element) {
39542      return new Matrix2D();
39543    }
39544
39545    var zeroScales = _forceNonZeroScale(element),
39546        svg = _svgOwner(element),
39547        temps = svg ? _svgTemps : _divTemps,
39548        container = _placeSiblings(element, adjustGOffset),
39549        b1 = temps[0].getBoundingClientRect(),
39550        b2 = temps[1].getBoundingClientRect(),
39551        b3 = temps[2].getBoundingClientRect(),
39552        parent = container.parentNode,
39553        isFixed = !includeScrollInFixed && _isFixed(element),
39554        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()));
39555
39556    parent.removeChild(container);
39557
39558    if (zeroScales) {
39559      b1 = zeroScales.length;
39560
39561      while (b1--) {
39562        b2 = zeroScales[b1];
39563        b2.scaleX = b2.scaleY = 0;
39564        b2.renderTransform(1, b2);
39565      }
39566    }
39567
39568    return inverse ? m.inverse() : m;
39569  }
39570
39571  var gsap,
39572      _win$1,
39573      _doc$1,
39574      _docElement$1,
39575      _body$1,
39576      _tempDiv,
39577      _placeholderDiv,
39578      _coreInitted,
39579      _checkPrefix,
39580      _toArray,
39581      _supportsPassive,
39582      _isTouchDevice,
39583      _touchEventLookup,
39584      _isMultiTouching,
39585      _isAndroid,
39586      InertiaPlugin,
39587      _defaultCursor,
39588      _supportsPointer,
39589      _context,
39590      _getStyleSaver,
39591      _dragCount = 0,
39592      _windowExists = function _windowExists() {
39593    return typeof window !== "undefined";
39594  },
39595      _getGSAP = function _getGSAP() {
39596    return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap;
39597  },
39598      _isFunction = function _isFunction(value) {
39599    return typeof value === "function";
39600  },
39601      _isObject = function _isObject(value) {
39602    return typeof value === "object";
39603  },
39604      _isUndefined = function _isUndefined(value) {
39605    return typeof value === "undefined";
39606  },
39607      _emptyFunc = function _emptyFunc() {
39608    return false;
39609  },
39610      _transformProp$1 = "transform",
39611      _transformOriginProp$1 = "transformOrigin",
39612      _round = function _round(value) {
39613    return Math.round(value * 10000) / 10000;
39614  },
39615      _isArray = Array.isArray,
39616      _createElement = function _createElement(type, ns) {
39617    var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type);
39618    return e.style ? e : _doc$1.createElement(type);
39619  },
39620      _RAD2DEG = 180 / Math.PI,
39621      _bigNum = 1e20,
39622      _identityMatrix$1 = new Matrix2D(),
39623      _getTime = Date.now || function () {
39624    return new Date().getTime();
39625  },
39626      _renderQueue = [],
39627      _lookup = {},
39628      _lookupCount = 0,
39629      _clickableTagExp = /^(?:a|input|textarea|button|select)$/i,
39630      _lastDragTime = 0,
39631      _temp1 = {},
39632      _windowProxy = {},
39633      _copy = function _copy(obj, factor) {
39634    var copy = {},
39635        p;
39636
39637    for (p in obj) {
39638      copy[p] = factor ? obj[p] * factor : obj[p];
39639    }
39640
39641    return copy;
39642  },
39643      _extend = function _extend(obj, defaults) {
39644    for (var p in defaults) {
39645      if (!(p in obj)) {
39646        obj[p] = defaults[p];
39647      }
39648    }
39649
39650    return obj;
39651  },
39652      _setTouchActionForAllDescendants = function _setTouchActionForAllDescendants(elements, value) {
39653    var i = elements.length,
39654        children;
39655
39656    while (i--) {
39657      value ? elements[i].style.touchAction = value : elements[i].style.removeProperty("touch-action");
39658      children = elements[i].children;
39659      children && children.length && _setTouchActionForAllDescendants(children, value);
39660    }
39661  },
39662      _renderQueueTick = function _renderQueueTick() {
39663    return _renderQueue.forEach(function (func) {
39664      return func();
39665    });
39666  },
39667      _addToRenderQueue = function _addToRenderQueue(func) {
39668    _renderQueue.push(func);
39669
39670    if (_renderQueue.length === 1) {
39671      gsap.ticker.add(_renderQueueTick);
39672    }
39673  },
39674      _renderQueueTimeout = function _renderQueueTimeout() {
39675    return !_renderQueue.length && gsap.ticker.remove(_renderQueueTick);
39676  },
39677      _removeFromRenderQueue = function _removeFromRenderQueue(func) {
39678    var i = _renderQueue.length;
39679
39680    while (i--) {
39681      if (_renderQueue[i] === func) {
39682        _renderQueue.splice(i, 1);
39683      }
39684    }
39685
39686    gsap.to(_renderQueueTimeout, {
39687      overwrite: true,
39688      delay: 15,
39689      duration: 0,
39690      onComplete: _renderQueueTimeout,
39691      data: "_draggable"
39692    });
39693  },
39694      _setDefaults = function _setDefaults(obj, defaults) {
39695    for (var p in defaults) {
39696      if (!(p in obj)) {
39697        obj[p] = defaults[p];
39698      }
39699    }
39700
39701    return obj;
39702  },
39703      _addListener = function _addListener(element, type, func, capture) {
39704    if (element.addEventListener) {
39705      var touchType = _touchEventLookup[type];
39706      capture = capture || (_supportsPassive ? {
39707        passive: false
39708      } : null);
39709      element.addEventListener(touchType || type, func, capture);
39710      touchType && type !== touchType && element.addEventListener(type, func, capture);
39711    }
39712  },
39713      _removeListener = function _removeListener(element, type, func, capture) {
39714    if (element.removeEventListener) {
39715      var touchType = _touchEventLookup[type];
39716      element.removeEventListener(touchType || type, func, capture);
39717      touchType && type !== touchType && element.removeEventListener(type, func, capture);
39718    }
39719  },
39720      _preventDefault = function _preventDefault(event) {
39721    event.preventDefault && event.preventDefault();
39722    event.preventManipulation && event.preventManipulation();
39723  },
39724      _hasTouchID = function _hasTouchID(list, ID) {
39725    var i = list.length;
39726
39727    while (i--) {
39728      if (list[i].identifier === ID) {
39729        return true;
39730      }
39731    }
39732  },
39733      _onMultiTouchDocumentEnd = function _onMultiTouchDocumentEnd(event) {
39734    _isMultiTouching = event.touches && _dragCount < event.touches.length;
39735
39736    _removeListener(event.target, "touchend", _onMultiTouchDocumentEnd);
39737  },
39738      _onMultiTouchDocument = function _onMultiTouchDocument(event) {
39739    _isMultiTouching = event.touches && _dragCount < event.touches.length;
39740
39741    _addListener(event.target, "touchend", _onMultiTouchDocumentEnd);
39742  },
39743      _getDocScrollTop$1 = function _getDocScrollTop(doc) {
39744    return _win$1.pageYOffset || doc.scrollTop || doc.documentElement.scrollTop || doc.body.scrollTop || 0;
39745  },
39746      _getDocScrollLeft$1 = function _getDocScrollLeft(doc) {
39747    return _win$1.pageXOffset || doc.scrollLeft || doc.documentElement.scrollLeft || doc.body.scrollLeft || 0;
39748  },
39749      _addScrollListener = function _addScrollListener(e, callback) {
39750    _addListener(e, "scroll", callback);
39751
39752    if (!_isRoot(e.parentNode)) {
39753      _addScrollListener(e.parentNode, callback);
39754    }
39755  },
39756      _removeScrollListener = function _removeScrollListener(e, callback) {
39757    _removeListener(e, "scroll", callback);
39758
39759    if (!_isRoot(e.parentNode)) {
39760      _removeScrollListener(e.parentNode, callback);
39761    }
39762  },
39763      _isRoot = function _isRoot(e) {
39764    return !!(!e || e === _docElement$1 || e.nodeType === 9 || e === _doc$1.body || e === _win$1 || !e.nodeType || !e.parentNode);
39765  },
39766      _getMaxScroll = function _getMaxScroll(element, axis) {
39767    var dim = axis === "x" ? "Width" : "Height",
39768        scroll = "scroll" + dim,
39769        client = "client" + dim;
39770    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]);
39771  },
39772      _recordMaxScrolls = function _recordMaxScrolls(e, skipCurrent) {
39773    var x = _getMaxScroll(e, "x"),
39774        y = _getMaxScroll(e, "y");
39775
39776    if (_isRoot(e)) {
39777      e = _windowProxy;
39778    } else {
39779      _recordMaxScrolls(e.parentNode, skipCurrent);
39780    }
39781
39782    e._gsMaxScrollX = x;
39783    e._gsMaxScrollY = y;
39784
39785    if (!skipCurrent) {
39786      e._gsScrollX = e.scrollLeft || 0;
39787      e._gsScrollY = e.scrollTop || 0;
39788    }
39789  },
39790      _setStyle = function _setStyle(element, property, value) {
39791    var style = element.style;
39792
39793    if (!style) {
39794      return;
39795    }
39796
39797    if (_isUndefined(style[property])) {
39798      property = _checkPrefix(property, element) || property;
39799    }
39800
39801    if (value == null) {
39802      style.removeProperty && style.removeProperty(property.replace(/([A-Z])/g, "-$1").toLowerCase());
39803    } else {
39804      style[property] = value;
39805    }
39806  },
39807      _getComputedStyle = function _getComputedStyle(element) {
39808    return _win$1.getComputedStyle(element instanceof Element ? element : element.host || (element.parentNode || {}).host || element);
39809  },
39810      _tempRect = {},
39811      _parseRect = function _parseRect(e) {
39812    if (e === _win$1) {
39813      _tempRect.left = _tempRect.top = 0;
39814      _tempRect.width = _tempRect.right = _docElement$1.clientWidth || e.innerWidth || _body$1.clientWidth || 0;
39815      _tempRect.height = _tempRect.bottom = (e.innerHeight || 0) - 20 < _docElement$1.clientHeight ? _docElement$1.clientHeight : e.innerHeight || _body$1.clientHeight || 0;
39816      return _tempRect;
39817    }
39818
39819    var doc = e.ownerDocument || _doc$1,
39820        r = !_isUndefined(e.pageX) ? {
39821      left: e.pageX - _getDocScrollLeft$1(doc),
39822      top: e.pageY - _getDocScrollTop$1(doc),
39823      right: e.pageX - _getDocScrollLeft$1(doc) + 1,
39824      bottom: e.pageY - _getDocScrollTop$1(doc) + 1
39825    } : !e.nodeType && !_isUndefined(e.left) && !_isUndefined(e.top) ? e : _toArray(e)[0].getBoundingClientRect();
39826
39827    if (_isUndefined(r.right) && !_isUndefined(r.width)) {
39828      r.right = r.left + r.width;
39829      r.bottom = r.top + r.height;
39830    } else if (_isUndefined(r.width)) {
39831      r = {
39832        width: r.right - r.left,
39833        height: r.bottom - r.top,
39834        right: r.right,
39835        left: r.left,
39836        bottom: r.bottom,
39837        top: r.top
39838      };
39839    }
39840
39841    return r;
39842  },
39843      _dispatchEvent = function _dispatchEvent(target, type, callbackName) {
39844    var vars = target.vars,
39845        callback = vars[callbackName],
39846        listeners = target._listeners[type],
39847        result;
39848
39849    if (_isFunction(callback)) {
39850      result = callback.apply(vars.callbackScope || target, vars[callbackName + "Params"] || [target.pointerEvent]);
39851    }
39852
39853    if (listeners && target.dispatchEvent(type) === false) {
39854      result = false;
39855    }
39856
39857    return result;
39858  },
39859      _getBounds = function _getBounds(target, context) {
39860    var e = _toArray(target)[0],
39861        top,
39862        left,
39863        offset;
39864
39865    if (!e.nodeType && e !== _win$1) {
39866      if (!_isUndefined(target.left)) {
39867        offset = {
39868          x: 0,
39869          y: 0
39870        };
39871        return {
39872          left: target.left - offset.x,
39873          top: target.top - offset.y,
39874          width: target.width,
39875          height: target.height
39876        };
39877      }
39878
39879      left = target.min || target.minX || target.minRotation || 0;
39880      top = target.min || target.minY || 0;
39881      return {
39882        left: left,
39883        top: top,
39884        width: (target.max || target.maxX || target.maxRotation || 0) - left,
39885        height: (target.max || target.maxY || 0) - top
39886      };
39887    }
39888
39889    return _getElementBounds(e, context);
39890  },
39891      _point1 = {},
39892      _getElementBounds = function _getElementBounds(element, context) {
39893    context = _toArray(context)[0];
39894    var isSVG = element.getBBox && element.ownerSVGElement,
39895        doc = element.ownerDocument || _doc$1,
39896        left,
39897        right,
39898        top,
39899        bottom,
39900        matrix,
39901        p1,
39902        p2,
39903        p3,
39904        p4,
39905        bbox,
39906        width,
39907        height,
39908        cs;
39909
39910    if (element === _win$1) {
39911      top = _getDocScrollTop$1(doc);
39912      left = _getDocScrollLeft$1(doc);
39913      right = left + (doc.documentElement.clientWidth || element.innerWidth || doc.body.clientWidth || 0);
39914      bottom = top + ((element.innerHeight || 0) - 20 < doc.documentElement.clientHeight ? doc.documentElement.clientHeight : element.innerHeight || doc.body.clientHeight || 0);
39915    } else if (context === _win$1 || _isUndefined(context)) {
39916      return element.getBoundingClientRect();
39917    } else {
39918      left = top = 0;
39919
39920      if (isSVG) {
39921        bbox = element.getBBox();
39922        width = bbox.width;
39923        height = bbox.height;
39924      } else {
39925        if (element.viewBox && (bbox = element.viewBox.baseVal)) {
39926          left = bbox.x || 0;
39927          top = bbox.y || 0;
39928          width = bbox.width;
39929          height = bbox.height;
39930        }
39931
39932        if (!width) {
39933          cs = _getComputedStyle(element);
39934          bbox = cs.boxSizing === "border-box";
39935          width = (parseFloat(cs.width) || element.clientWidth || 0) + (bbox ? 0 : parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth));
39936          height = (parseFloat(cs.height) || element.clientHeight || 0) + (bbox ? 0 : parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth));
39937        }
39938      }
39939
39940      right = width;
39941      bottom = height;
39942    }
39943
39944    if (element === context) {
39945      return {
39946        left: left,
39947        top: top,
39948        width: right - left,
39949        height: bottom - top
39950      };
39951    }
39952
39953    matrix = getGlobalMatrix(context, true).multiply(getGlobalMatrix(element));
39954    p1 = matrix.apply({
39955      x: left,
39956      y: top
39957    });
39958    p2 = matrix.apply({
39959      x: right,
39960      y: top
39961    });
39962    p3 = matrix.apply({
39963      x: right,
39964      y: bottom
39965    });
39966    p4 = matrix.apply({
39967      x: left,
39968      y: bottom
39969    });
39970    left = Math.min(p1.x, p2.x, p3.x, p4.x);
39971    top = Math.min(p1.y, p2.y, p3.y, p4.y);
39972    return {
39973      left: left,
39974      top: top,
39975      width: Math.max(p1.x, p2.x, p3.x, p4.x) - left,
39976      height: Math.max(p1.y, p2.y, p3.y, p4.y) - top
39977    };
39978  },
39979      _parseInertia = function _parseInertia(draggable, snap, max, min, factor, forceZeroVelocity) {
39980    var vars = {},
39981        a,
39982        i,
39983        l;
39984
39985    if (snap) {
39986      if (factor !== 1 && snap instanceof Array) {
39987        vars.end = a = [];
39988        l = snap.length;
39989
39990        if (_isObject(snap[0])) {
39991          for (i = 0; i < l; i++) {
39992            a[i] = _copy(snap[i], factor);
39993          }
39994        } else {
39995          for (i = 0; i < l; i++) {
39996            a[i] = snap[i] * factor;
39997          }
39998        }
39999
40000        max += 1.1;
40001        min -= 1.1;
40002      } else if (_isFunction(snap)) {
40003        vars.end = function (value) {
40004          var result = snap.call(draggable, value),
40005              copy,
40006              p;
40007
40008          if (factor !== 1) {
40009            if (_isObject(result)) {
40010              copy = {};
40011
40012              for (p in result) {
40013                copy[p] = result[p] * factor;
40014              }
40015
40016              result = copy;
40017            } else {
40018              result *= factor;
40019            }
40020          }
40021
40022          return result;
40023        };
40024      } else {
40025        vars.end = snap;
40026      }
40027    }
40028
40029    if (max || max === 0) {
40030      vars.max = max;
40031    }
40032
40033    if (min || min === 0) {
40034      vars.min = min;
40035    }
40036
40037    if (forceZeroVelocity) {
40038      vars.velocity = 0;
40039    }
40040
40041    return vars;
40042  },
40043      _isClickable = function _isClickable(element) {
40044    var data;
40045    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);
40046  },
40047      _setSelectable = function _setSelectable(elements, selectable) {
40048    var i = elements.length,
40049        e;
40050
40051    while (i--) {
40052      e = elements[i];
40053      e.ondragstart = e.onselectstart = selectable ? null : _emptyFunc;
40054      gsap.set(e, {
40055        lazy: true,
40056        userSelect: selectable ? "text" : "none"
40057      });
40058    }
40059  },
40060      _isFixed$1 = function _isFixed(element) {
40061    if (_getComputedStyle(element).position === "fixed") {
40062      return true;
40063    }
40064
40065    element = element.parentNode;
40066
40067    if (element && element.nodeType === 1) {
40068      return _isFixed(element);
40069    }
40070  },
40071      _supports3D,
40072      _addPaddingBR,
40073      ScrollProxy = function ScrollProxy(element, vars) {
40074    element = gsap.utils.toArray(element)[0];
40075    vars = vars || {};
40076    var content = document.createElement("div"),
40077        style = content.style,
40078        node = element.firstChild,
40079        offsetTop = 0,
40080        offsetLeft = 0,
40081        prevTop = element.scrollTop,
40082        prevLeft = element.scrollLeft,
40083        scrollWidth = element.scrollWidth,
40084        scrollHeight = element.scrollHeight,
40085        extraPadRight = 0,
40086        maxLeft = 0,
40087        maxTop = 0,
40088        elementWidth,
40089        elementHeight,
40090        contentHeight,
40091        nextNode,
40092        transformStart,
40093        transformEnd;
40094
40095    if (_supports3D && vars.force3D !== false) {
40096      transformStart = "translate3d(";
40097      transformEnd = "px,0px)";
40098    } else if (_transformProp$1) {
40099      transformStart = "translate(";
40100      transformEnd = "px)";
40101    }
40102
40103    this.scrollTop = function (value, force) {
40104      if (!arguments.length) {
40105        return -this.top();
40106      }
40107
40108      this.top(-value, force);
40109    };
40110
40111    this.scrollLeft = function (value, force) {
40112      if (!arguments.length) {
40113        return -this.left();
40114      }
40115
40116      this.left(-value, force);
40117    };
40118
40119    this.left = function (value, force) {
40120      if (!arguments.length) {
40121        return -(element.scrollLeft + offsetLeft);
40122      }
40123
40124      var dif = element.scrollLeft - prevLeft,
40125          oldOffset = offsetLeft;
40126
40127      if ((dif > 2 || dif < -2) && !force) {
40128        prevLeft = element.scrollLeft;
40129        gsap.killTweensOf(this, {
40130          left: 1,
40131          scrollLeft: 1
40132        });
40133        this.left(-prevLeft);
40134
40135        if (vars.onKill) {
40136          vars.onKill();
40137        }
40138
40139        return;
40140      }
40141
40142      value = -value;
40143
40144      if (value < 0) {
40145        offsetLeft = value - 0.5 | 0;
40146        value = 0;
40147      } else if (value > maxLeft) {
40148        offsetLeft = value - maxLeft | 0;
40149        value = maxLeft;
40150      } else {
40151        offsetLeft = 0;
40152      }
40153
40154      if (offsetLeft || oldOffset) {
40155        if (!this._skip) {
40156          style[_transformProp$1] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd;
40157        }
40158
40159        if (offsetLeft + extraPadRight >= 0) {
40160          style.paddingRight = offsetLeft + extraPadRight + "px";
40161        }
40162      }
40163
40164      element.scrollLeft = value | 0;
40165      prevLeft = element.scrollLeft;
40166    };
40167
40168    this.top = function (value, force) {
40169      if (!arguments.length) {
40170        return -(element.scrollTop + offsetTop);
40171      }
40172
40173      var dif = element.scrollTop - prevTop,
40174          oldOffset = offsetTop;
40175
40176      if ((dif > 2 || dif < -2) && !force) {
40177        prevTop = element.scrollTop;
40178        gsap.killTweensOf(this, {
40179          top: 1,
40180          scrollTop: 1
40181        });
40182        this.top(-prevTop);
40183
40184        if (vars.onKill) {
40185          vars.onKill();
40186        }
40187
40188        return;
40189      }
40190
40191      value = -value;
40192
40193      if (value < 0) {
40194        offsetTop = value - 0.5 | 0;
40195        value = 0;
40196      } else if (value > maxTop) {
40197        offsetTop = value - maxTop | 0;
40198        value = maxTop;
40199      } else {
40200        offsetTop = 0;
40201      }
40202
40203      if (offsetTop || oldOffset) {
40204        if (!this._skip) {
40205          style[_transformProp$1] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd;
40206        }
40207      }
40208
40209      element.scrollTop = value | 0;
40210      prevTop = element.scrollTop;
40211    };
40212
40213    this.maxScrollTop = function () {
40214      return maxTop;
40215    };
40216
40217    this.maxScrollLeft = function () {
40218      return maxLeft;
40219    };
40220
40221    this.disable = function () {
40222      node = content.firstChild;
40223
40224      while (node) {
40225        nextNode = node.nextSibling;
40226        element.appendChild(node);
40227        node = nextNode;
40228      }
40229
40230      if (element === content.parentNode) {
40231        element.removeChild(content);
40232      }
40233    };
40234
40235    this.enable = function () {
40236      node = element.firstChild;
40237
40238      if (node === content) {
40239        return;
40240      }
40241
40242      while (node) {
40243        nextNode = node.nextSibling;
40244        content.appendChild(node);
40245        node = nextNode;
40246      }
40247
40248      element.appendChild(content);
40249      this.calibrate();
40250    };
40251
40252    this.calibrate = function (force) {
40253      var widthMatches = element.clientWidth === elementWidth,
40254          cs,
40255          x,
40256          y;
40257      prevTop = element.scrollTop;
40258      prevLeft = element.scrollLeft;
40259
40260      if (widthMatches && element.clientHeight === elementHeight && content.offsetHeight === contentHeight && scrollWidth === element.scrollWidth && scrollHeight === element.scrollHeight && !force) {
40261        return;
40262      }
40263
40264      if (offsetTop || offsetLeft) {
40265        x = this.left();
40266        y = this.top();
40267        this.left(-element.scrollLeft);
40268        this.top(-element.scrollTop);
40269      }
40270
40271      cs = _getComputedStyle(element);
40272
40273      if (!widthMatches || force) {
40274        style.display = "block";
40275        style.width = "auto";
40276        style.paddingRight = "0px";
40277        extraPadRight = Math.max(0, element.scrollWidth - element.clientWidth);
40278
40279        if (extraPadRight) {
40280          extraPadRight += parseFloat(cs.paddingLeft) + (_addPaddingBR ? parseFloat(cs.paddingRight) : 0);
40281        }
40282      }
40283
40284      style.display = "inline-block";
40285      style.position = "relative";
40286      style.overflow = "visible";
40287      style.verticalAlign = "top";
40288      style.boxSizing = "content-box";
40289      style.width = "100%";
40290      style.paddingRight = extraPadRight + "px";
40291
40292      if (_addPaddingBR) {
40293        style.paddingBottom = cs.paddingBottom;
40294      }
40295
40296      elementWidth = element.clientWidth;
40297      elementHeight = element.clientHeight;
40298      scrollWidth = element.scrollWidth;
40299      scrollHeight = element.scrollHeight;
40300      maxLeft = element.scrollWidth - elementWidth;
40301      maxTop = element.scrollHeight - elementHeight;
40302      contentHeight = content.offsetHeight;
40303      style.display = "block";
40304
40305      if (x || y) {
40306        this.left(x);
40307        this.top(y);
40308      }
40309    };
40310
40311    this.content = content;
40312    this.element = element;
40313    this._skip = false;
40314    this.enable();
40315  },
40316      _initCore = function _initCore(required) {
40317    if (_windowExists() && document.body) {
40318      var nav = window && window.navigator;
40319      _win$1 = window;
40320      _doc$1 = document;
40321      _docElement$1 = _doc$1.documentElement;
40322      _body$1 = _doc$1.body;
40323      _tempDiv = _createElement("div");
40324      _supportsPointer = !!window.PointerEvent;
40325      _placeholderDiv = _createElement("div");
40326      _placeholderDiv.style.cssText = "visibility:hidden;height:1px;top:-1px;pointer-events:none;position:relative;clear:both;cursor:grab";
40327      _defaultCursor = _placeholderDiv.style.cursor === "grab" ? "grab" : "move";
40328      _isAndroid = nav && nav.userAgent.toLowerCase().indexOf("android") !== -1;
40329      _isTouchDevice = "ontouchstart" in _docElement$1 && "orientation" in _win$1 || nav && (nav.MaxTouchPoints > 0 || nav.msMaxTouchPoints > 0);
40330
40331      _addPaddingBR = function () {
40332        var div = _createElement("div"),
40333            child = _createElement("div"),
40334            childStyle = child.style,
40335            parent = _body$1,
40336            val;
40337
40338        childStyle.display = "inline-block";
40339        childStyle.position = "relative";
40340        div.style.cssText = "width:90px;height:40px;padding:10px;overflow:auto;visibility:hidden";
40341        div.appendChild(child);
40342        parent.appendChild(div);
40343        val = child.offsetHeight + 18 > div.scrollHeight;
40344        parent.removeChild(div);
40345        return val;
40346      }();
40347
40348      _touchEventLookup = function (types) {
40349        var standard = types.split(","),
40350            converted = ("onpointerdown" in _tempDiv ? "pointerdown,pointermove,pointerup,pointercancel" : "onmspointerdown" in _tempDiv ? "MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancel" : types).split(","),
40351            obj = {},
40352            i = 4;
40353
40354        while (--i > -1) {
40355          obj[standard[i]] = converted[i];
40356          obj[converted[i]] = standard[i];
40357        }
40358
40359        try {
40360          _docElement$1.addEventListener("test", null, Object.defineProperty({}, "passive", {
40361            get: function get() {
40362              _supportsPassive = 1;
40363            }
40364          }));
40365        } catch (e) {}
40366
40367        return obj;
40368      }("touchstart,touchmove,touchend,touchcancel");
40369
40370      _addListener(_doc$1, "touchcancel", _emptyFunc);
40371
40372      _addListener(_win$1, "touchmove", _emptyFunc);
40373
40374      _body$1 && _body$1.addEventListener("touchstart", _emptyFunc);
40375
40376      _addListener(_doc$1, "contextmenu", function () {
40377        for (var p in _lookup) {
40378          if (_lookup[p].isPressed) {
40379            _lookup[p].endDrag();
40380          }
40381        }
40382      });
40383
40384      gsap = _coreInitted = _getGSAP();
40385    }
40386
40387    if (gsap) {
40388      InertiaPlugin = gsap.plugins.inertia;
40389
40390      _context = gsap.core.context || function () {};
40391
40392      _checkPrefix = gsap.utils.checkPrefix;
40393      _transformProp$1 = _checkPrefix(_transformProp$1);
40394      _transformOriginProp$1 = _checkPrefix(_transformOriginProp$1);
40395      _toArray = gsap.utils.toArray;
40396      _getStyleSaver = gsap.core.getStyleSaver;
40397      _supports3D = !!_checkPrefix("perspective");
40398    } else if (required) {
40399      console.warn("Please gsap.registerPlugin(Draggable)");
40400    }
40401  };
40402
40403  var EventDispatcher = function () {
40404    function EventDispatcher(target) {
40405      this._listeners = {};
40406      this.target = target || this;
40407    }
40408
40409    var _proto = EventDispatcher.prototype;
40410
40411    _proto.addEventListener = function addEventListener(type, callback) {
40412      var list = this._listeners[type] || (this._listeners[type] = []);
40413
40414      if (!~list.indexOf(callback)) {
40415        list.push(callback);
40416      }
40417    };
40418
40419    _proto.removeEventListener = function removeEventListener(type, callback) {
40420      var list = this._listeners[type],
40421          i = list && list.indexOf(callback);
40422      i >= 0 && list.splice(i, 1);
40423    };
40424
40425    _proto.dispatchEvent = function dispatchEvent(type) {
40426      var _this = this;
40427
40428      var result;
40429      (this._listeners[type] || []).forEach(function (callback) {
40430        return callback.call(_this, {
40431          type: type,
40432          target: _this.target
40433        }) === false && (result = false);
40434      });
40435      return result;
40436    };
40437
40438    return EventDispatcher;
40439  }();
40440
40441  var Draggable = function (_EventDispatcher) {
40442    _inheritsLoose(Draggable, _EventDispatcher);
40443
40444    function Draggable(target, vars) {
40445      var _this2;
40446
40447      _this2 = _EventDispatcher.call(this) || this;
40448      _coreInitted || _initCore(1);
40449      target = _toArray(target)[0];
40450      _this2.styles = _getStyleSaver && _getStyleSaver(target, "transform,left,top");
40451
40452      if (!InertiaPlugin) {
40453        InertiaPlugin = gsap.plugins.inertia;
40454      }
40455
40456      _this2.vars = vars = _copy(vars || {});
40457      _this2.target = target;
40458      _this2.x = _this2.y = _this2.rotation = 0;
40459      _this2.dragResistance = parseFloat(vars.dragResistance) || 0;
40460      _this2.edgeResistance = isNaN(vars.edgeResistance) ? 1 : parseFloat(vars.edgeResistance) || 0;
40461      _this2.lockAxis = vars.lockAxis;
40462      _this2.autoScroll = vars.autoScroll || 0;
40463      _this2.lockedAxis = null;
40464      _this2.allowEventDefault = !!vars.allowEventDefault;
40465      gsap.getProperty(target, "x");
40466
40467      var type = (vars.type || "x,y").toLowerCase(),
40468          xyMode = ~type.indexOf("x") || ~type.indexOf("y"),
40469          rotationMode = type.indexOf("rotation") !== -1,
40470          xProp = rotationMode ? "rotation" : xyMode ? "x" : "left",
40471          yProp = xyMode ? "y" : "top",
40472          allowX = !!(~type.indexOf("x") || ~type.indexOf("left") || type === "scroll"),
40473          allowY = !!(~type.indexOf("y") || ~type.indexOf("top") || type === "scroll"),
40474          minimumMovement = vars.minimumMovement || 2,
40475          self = _assertThisInitialized(_this2),
40476          triggers = _toArray(vars.trigger || vars.handle || target),
40477          killProps = {},
40478          dragEndTime = 0,
40479          checkAutoScrollBounds = false,
40480          autoScrollMarginTop = vars.autoScrollMarginTop || 40,
40481          autoScrollMarginRight = vars.autoScrollMarginRight || 40,
40482          autoScrollMarginBottom = vars.autoScrollMarginBottom || 40,
40483          autoScrollMarginLeft = vars.autoScrollMarginLeft || 40,
40484          isClickable = vars.clickableTest || _isClickable,
40485          clickTime = 0,
40486          gsCache = target._gsap || gsap.core.getCache(target),
40487          isFixed = _isFixed$1(target),
40488          getPropAsNum = function getPropAsNum(property, unit) {
40489        return parseFloat(gsCache.get(target, property, unit));
40490      },
40491          ownerDoc = target.ownerDocument || _doc$1,
40492          enabled,
40493          scrollProxy,
40494          startPointerX,
40495          startPointerY,
40496          startElementX,
40497          startElementY,
40498          hasBounds,
40499          hasDragCallback,
40500          hasMoveCallback,
40501          maxX,
40502          minX,
40503          maxY,
40504          minY,
40505          touch,
40506          touchID,
40507          rotationOrigin,
40508          dirty,
40509          old,
40510          snapX,
40511          snapY,
40512          snapXY,
40513          isClicking,
40514          touchEventTarget,
40515          matrix,
40516          interrupted,
40517          allowNativeTouchScrolling,
40518          touchDragAxis,
40519          isDispatching,
40520          clickDispatch,
40521          trustedClickDispatch,
40522          isPreventingDefault,
40523          innerMatrix,
40524          dragged,
40525          onContextMenu = function onContextMenu(e) {
40526        _preventDefault(e);
40527
40528        e.stopImmediatePropagation && e.stopImmediatePropagation();
40529        return false;
40530      },
40531          render = function render(suppressEvents) {
40532        if (self.autoScroll && self.isDragging && (checkAutoScrollBounds || dirty)) {
40533          var e = target,
40534              autoScrollFactor = self.autoScroll * 15,
40535              parent,
40536              isRoot,
40537              rect,
40538              pointerX,
40539              pointerY,
40540              changeX,
40541              changeY,
40542              gap;
40543          checkAutoScrollBounds = false;
40544          _windowProxy.scrollTop = _win$1.pageYOffset != null ? _win$1.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop;
40545          _windowProxy.scrollLeft = _win$1.pageXOffset != null ? _win$1.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft;
40546          pointerX = self.pointerX - _windowProxy.scrollLeft;
40547          pointerY = self.pointerY - _windowProxy.scrollTop;
40548
40549          while (e && !isRoot) {
40550            isRoot = _isRoot(e.parentNode);
40551            parent = isRoot ? _windowProxy : e.parentNode;
40552            rect = isRoot ? {
40553              bottom: Math.max(_docElement$1.clientHeight, _win$1.innerHeight || 0),
40554              right: Math.max(_docElement$1.clientWidth, _win$1.innerWidth || 0),
40555              left: 0,
40556              top: 0
40557            } : parent.getBoundingClientRect();
40558            changeX = changeY = 0;
40559
40560            if (allowY) {
40561              gap = parent._gsMaxScrollY - parent.scrollTop;
40562
40563              if (gap < 0) {
40564                changeY = gap;
40565              } else if (pointerY > rect.bottom - autoScrollMarginBottom && gap) {
40566                checkAutoScrollBounds = true;
40567                changeY = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.bottom - pointerY) / autoScrollMarginBottom) | 0);
40568              } else if (pointerY < rect.top + autoScrollMarginTop && parent.scrollTop) {
40569                checkAutoScrollBounds = true;
40570                changeY = -Math.min(parent.scrollTop, autoScrollFactor * (1 - Math.max(0, pointerY - rect.top) / autoScrollMarginTop) | 0);
40571              }
40572
40573              if (changeY) {
40574                parent.scrollTop += changeY;
40575              }
40576            }
40577
40578            if (allowX) {
40579              gap = parent._gsMaxScrollX - parent.scrollLeft;
40580
40581              if (gap < 0) {
40582                changeX = gap;
40583              } else if (pointerX > rect.right - autoScrollMarginRight && gap) {
40584                checkAutoScrollBounds = true;
40585                changeX = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.right - pointerX) / autoScrollMarginRight) | 0);
40586              } else if (pointerX < rect.left + autoScrollMarginLeft && parent.scrollLeft) {
40587                checkAutoScrollBounds = true;
40588                changeX = -Math.min(parent.scrollLeft, autoScrollFactor * (1 - Math.max(0, pointerX - rect.left) / autoScrollMarginLeft) | 0);
40589              }
40590
40591              if (changeX) {
40592                parent.scrollLeft += changeX;
40593              }
40594            }
40595
40596            if (isRoot && (changeX || changeY)) {
40597              _win$1.scrollTo(parent.scrollLeft, parent.scrollTop);
40598
40599              setPointerPosition(self.pointerX + changeX, self.pointerY + changeY);
40600            }
40601
40602            e = parent;
40603          }
40604        }
40605
40606        if (dirty) {
40607          var x = self.x,
40608              y = self.y;
40609
40610          if (rotationMode) {
40611            self.deltaX = x - parseFloat(gsCache.rotation);
40612            self.rotation = x;
40613            gsCache.rotation = x + "deg";
40614            gsCache.renderTransform(1, gsCache);
40615          } else {
40616            if (scrollProxy) {
40617              if (allowY) {
40618                self.deltaY = y - scrollProxy.top();
40619                scrollProxy.top(y);
40620              }
40621
40622              if (allowX) {
40623                self.deltaX = x - scrollProxy.left();
40624                scrollProxy.left(x);
40625              }
40626            } else if (xyMode) {
40627              if (allowY) {
40628                self.deltaY = y - parseFloat(gsCache.y);
40629                gsCache.y = y + "px";
40630              }
40631
40632              if (allowX) {
40633                self.deltaX = x - parseFloat(gsCache.x);
40634                gsCache.x = x + "px";
40635              }
40636
40637              gsCache.renderTransform(1, gsCache);
40638            } else {
40639              if (allowY) {
40640                self.deltaY = y - parseFloat(target.style.top || 0);
40641                target.style.top = y + "px";
40642              }
40643
40644              if (allowX) {
40645                self.deltaX = x - parseFloat(target.style.left || 0);
40646                target.style.left = x + "px";
40647              }
40648            }
40649          }
40650
40651          if (hasDragCallback && !suppressEvents && !isDispatching) {
40652            isDispatching = true;
40653
40654            if (_dispatchEvent(self, "drag", "onDrag") === false) {
40655              if (allowX) {
40656                self.x -= self.deltaX;
40657              }
40658
40659              if (allowY) {
40660                self.y -= self.deltaY;
40661              }
40662
40663              render(true);
40664            }
40665
40666            isDispatching = false;
40667          }
40668        }
40669
40670        dirty = false;
40671      },
40672          syncXY = function syncXY(skipOnUpdate, skipSnap) {
40673        var x = self.x,
40674            y = self.y,
40675            snappedValue,
40676            cs;
40677
40678        if (!target._gsap) {
40679          gsCache = gsap.core.getCache(target);
40680        }
40681
40682        gsCache.uncache && gsap.getProperty(target, "x");
40683
40684        if (xyMode) {
40685          self.x = parseFloat(gsCache.x);
40686          self.y = parseFloat(gsCache.y);
40687        } else if (rotationMode) {
40688          self.x = self.rotation = 
40688parseFloat(gsCache.rotation
vendor: 18,327 bytes, lines 40688-41238
40688);
40689        } else if (scrollProxy) {
40690          self.y = scrollProxy.top();
40691          self.x = scrollProxy.left();
40692        } else {
40693          self.y = parseFloat(target.style.top || (cs = _getComputedStyle(target)) && cs.top) || 0;
40694          self.x = parseFloat(target.style.left || (cs || {}).left) || 0;
40695        }
40696
40697        if ((snapX || snapY || snapXY) && !skipSnap && (self.isDragging || self.isThrowing)) {
40698          if (snapXY) {
40699            _temp1.x = self.x;
40700            _temp1.y = self.y;
40701            snappedValue = snapXY(_temp1);
40702
40703            if (snappedValue.x !== self.x) {
40704              self.x = snappedValue.x;
40705              dirty = true;
40706            }
40707
40708            if (snappedValue.y !== self.y) {
40709              self.y = snappedValue.y;
40710              dirty = true;
40711            }
40712          }
40713
40714          if (snapX) {
40715            snappedValue = snapX(self.x);
40716
40717            if (snappedValue !== self.x) {
40718              self.x = snappedValue;
40719
40720              if (rotationMode) {
40721                self.rotation = snappedValue;
40722              }
40723
40724              dirty = true;
40725            }
40726          }
40727
40728          if (snapY) {
40729            snappedValue = snapY(self.y);
40730
40731            if (snappedValue !== self.y) {
40732              self.y = snappedValue;
40733            }
40734
40735            dirty = true;
40736          }
40737        }
40738
40739        dirty && render(true);
40740
40741        if (!skipOnUpdate) {
40742          self.deltaX = self.x - x;
40743          self.deltaY = self.y - y;
40744
40745          _dispatchEvent(self, "throwupdate", "onThrowUpdate");
40746        }
40747      },
40748          buildSnapFunc = function buildSnapFunc(snap, min, max, factor) {
40749        if (min == null) {
40750          min = -_bigNum;
40751        }
40752
40753        if (max == null) {
40754          max = _bigNum;
40755        }
40756
40757        if (_isFunction(snap)) {
40758          return function (n) {
40759            var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance;
40760            return snap.call(self, (n > max ? max + (n - max) * edgeTolerance : n < min ? min + (n - min) * edgeTolerance : n) * factor) * factor;
40761          };
40762        }
40763
40764        if (_isArray(snap)) {
40765          return function (n) {
40766            var i = snap.length,
40767                closest = 0,
40768                absDif = _bigNum,
40769                val,
40770                dif;
40771
40772            while (--i > -1) {
40773              val = snap[i];
40774              dif = val - n;
40775
40776              if (dif < 0) {
40777                dif = -dif;
40778              }
40779
40780              if (dif < absDif && val >= min && val <= max) {
40781                closest = i;
40782                absDif = dif;
40783              }
40784            }
40785
40786            return snap[closest];
40787          };
40788        }
40789
40790        return isNaN(snap) ? function (n) {
40791          return n;
40792        } : function () {
40793          return snap * factor;
40794        };
40795      },
40796          buildPointSnapFunc = function buildPointSnapFunc(snap, minX, maxX, minY, maxY, radius, factor) {
40797        radius = radius && radius < _bigNum ? radius * radius : _bigNum;
40798
40799        if (_isFunction(snap)) {
40800          return function (point) {
40801            var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance,
40802                x = point.x,
40803                y = point.y,
40804                result,
40805                dx,
40806                dy;
40807            point.x = x = x > maxX ? maxX + (x - maxX) * edgeTolerance : x < minX ? minX + (x - minX) * edgeTolerance : x;
40808            point.y = y = y > maxY ? maxY + (y - maxY) * edgeTolerance : y < minY ? minY + (y - minY) * edgeTolerance : y;
40809            result = snap.call(self, point);
40810
40811            if (result !== point) {
40812              point.x = result.x;
40813              point.y = result.y;
40814            }
40815
40816            if (factor !== 1) {
40817              point.x *= factor;
40818              point.y *= factor;
40819            }
40820
40821            if (radius < _bigNum) {
40822              dx = point.x - x;
40823              dy = point.y - y;
40824
40825              if (dx * dx + dy * dy > radius) {
40826                point.x = x;
40827                point.y = y;
40828              }
40829            }
40830
40831            return point;
40832          };
40833        }
40834
40835        if (_isArray(snap)) {
40836          return function (p) {
40837            var i = snap.length,
40838                closest = 0,
40839                minDist = _bigNum,
40840                x,
40841                y,
40842                point,
40843                dist;
40844
40845            while (--i > -1) {
40846              point = snap[i];
40847              x = point.x - p.x;
40848              y = point.y - p.y;
40849              dist = x * x + y * y;
40850
40851              if (dist < minDist) {
40852                closest = i;
40853                minDist = dist;
40854              }
40855            }
40856
40857            return minDist <= radius ? snap[closest] : p;
40858          };
40859        }
40860
40861        return function (n) {
40862          return n;
40863        };
40864      },
40865          calculateBounds = function calculateBounds() {
40866        var bounds, targetBounds, snap, snapIsRaw;
40867        hasBounds = false;
40868
40869        if (scrollProxy) {
40870          scrollProxy.calibrate();
40871          self.minX = minX = -scrollProxy.maxScrollLeft();
40872          self.minY = minY = -scrollProxy.maxScrollTop();
40873          self.maxX = maxX = self.maxY = maxY = 0;
40874          hasBounds = true;
40875        } else if (!!vars.bounds) {
40876          bounds = _getBounds(vars.bounds, target.parentNode);
40877
40878          if (rotationMode) {
40879            self.minX = minX = bounds.left;
40880            self.maxX = maxX = bounds.left + bounds.width;
40881            self.minY = minY = self.maxY = maxY = 0;
40882          } else if (!_isUndefined(vars.bounds.maxX) || !_isUndefined(vars.bounds.maxY)) {
40883            bounds = vars.bounds;
40884            self.minX = minX = bounds.minX;
40885            self.minY = minY = bounds.minY;
40886            self.maxX = maxX = bounds.maxX;
40887            self.maxY = maxY = bounds.maxY;
40888          } else {
40889            targetBounds = _getBounds(target, target.parentNode);
40890            self.minX = minX = Math.round(getPropAsNum(xProp, "px") + bounds.left - targetBounds.left);
40891            self.minY = minY = Math.round(getPropAsNum(yProp, "px") + bounds.top - targetBounds.top);
40892            self.maxX = maxX = Math.round(minX + (bounds.width - targetBounds.width));
40893            self.maxY = maxY = Math.round(minY + (bounds.height - targetBounds.height));
40894          }
40895
40896          if (minX > maxX) {
40897            self.minX = maxX;
40898            self.maxX = maxX = minX;
40899            minX = self.minX;
40900          }
40901
40902          if (minY > maxY) {
40903            self.minY = maxY;
40904            self.maxY = maxY = minY;
40905            minY = self.minY;
40906          }
40907
40908          if (rotationMode) {
40909            self.minRotation = minX;
40910            self.maxRotation = maxX;
40911          }
40912
40913          hasBounds = true;
40914        }
40915
40916        if (vars.liveSnap) {
40917          snap = vars.liveSnap === true ? vars.snap || {} : vars.liveSnap;
40918          snapIsRaw = _isArray(snap) || _isFunction(snap);
40919
40920          if (rotationMode) {
40921            snapX = buildSnapFunc(snapIsRaw ? snap : snap.rotation, minX, maxX, 1);
40922            snapY = null;
40923          } else {
40924            if (snap.points) {
40925              snapXY = buildPointSnapFunc(snapIsRaw ? snap : snap.points, minX, maxX, minY, maxY, snap.radius, scrollProxy ? -1 : 1);
40926            } else {
40927              if (allowX) {
40928                snapX = buildSnapFunc(snapIsRaw ? snap : snap.x || snap.left || snap.scrollLeft, minX, maxX, scrollProxy ? -1 : 1);
40929              }
40930
40931              if (allowY) {
40932                snapY = buildSnapFunc(snapIsRaw ? snap : snap.y || snap.top || snap.scrollTop, minY, maxY, scrollProxy ? -1 : 1);
40933              }
40934            }
40935          }
40936        }
40937      },
40938          onThrowComplete = function onThrowComplete() {
40939        self.isThrowing = false;
40940
40941        _dispatchEvent(self, "throwcomplete", "onThrowComplete");
40942      },
40943          onThrowInterrupt = function onThrowInterrupt() {
40944        self.isThrowing = false;
40945      },
40946          animate = function animate(inertia, forceZeroVelocity) {
40947        var snap, snapIsRaw, tween, overshootTolerance;
40948
40949        if (inertia && InertiaPlugin) {
40950          if (inertia === true) {
40951            snap = vars.snap || vars.liveSnap || {};
40952            snapIsRaw = _isArray(snap) || _isFunction(snap);
40953            inertia = {
40954              resistance: (vars.throwResistance || vars.resistance || 1000) / (rotationMode ? 10 : 1)
40955            };
40956
40957            if (rotationMode) {
40958              inertia.rotation = _parseInertia(self, snapIsRaw ? snap : snap.rotation, maxX, minX, 1, forceZeroVelocity);
40959            } else {
40960              if (allowX) {
40961                inertia[xProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.x || snap.left, maxX, minX, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "x");
40962              }
40963
40964              if (allowY) {
40965                inertia[yProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.y || snap.top, maxY, minY, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "y");
40966              }
40967
40968              if (snap.points || _isArray(snap) && _isObject(snap[0])) {
40969                inertia.linkedProps = xProp + "," + yProp;
40970                inertia.radius = snap.radius;
40971              }
40972            }
40973          }
40974
40975          self.isThrowing = true;
40976          overshootTolerance = !isNaN(vars.overshootTolerance) ? vars.overshootTolerance : vars.edgeResistance === 1 ? 0 : 1 - self.edgeResistance + 0.2;
40977
40978          if (!inertia.duration) {
40979            inertia.duration = {
40980              max: Math.max(vars.minDuration || 0, "maxDuration" in vars ? vars.maxDuration : 2),
40981              min: !isNaN(vars.minDuration) ? vars.minDuration : overshootTolerance === 0 || _isObject(inertia) && inertia.resistance > 1000 ? 0 : 0.5,
40982              overshoot: overshootTolerance
40983            };
40984          }
40985
40986          self.tween = tween = gsap.to(scrollProxy || target, {
40987            inertia: inertia,
40988            data: "_draggable",
40989            inherit: false,
40990            onComplete: onThrowComplete,
40991            onInterrupt: onThrowInterrupt,
40992            onUpdate: vars.fastMode ? _dispatchEvent : syncXY,
40993            onUpdateParams: vars.fastMode ? [self, "onthrowupdate", "onThrowUpdate"] : snap && snap.radius ? [false, true] : []
40994          });
40995
40996          if (!vars.fastMode) {
40997            if (scrollProxy) {
40998              scrollProxy._skip = true;
40999            }
41000
41001            tween.render(1e9, true, true);
41002            syncXY(true, true);
41003            self.endX = self.x;
41004            self.endY = self.y;
41005
41006            if (rotationMode) {
41007              self.endRotation = self.x;
41008            }
41009
41010            tween.play(0);
41011            syncXY(true, true);
41012
41013            if (scrollProxy) {
41014              scrollProxy._skip = false;
41015            }
41016          }
41017        } else if (hasBounds) {
41018          self.applyBounds();
41019        }
41020      },
41021          updateMatrix = function updateMatrix(shiftStart) {
41022        var start = matrix,
41023            p;
41024        matrix = getGlobalMatrix(target.parentNode, true);
41025
41026        if (shiftStart && self.isPressed && !matrix.equals(start || new Matrix2D())) {
41027          p = start.inverse().apply({
41028            x: startPointerX,
41029            y: startPointerY
41030          });
41031          matrix.apply(p, p);
41032          startPointerX = p.x;
41033          startPointerY = p.y;
41034        }
41035
41036        if (matrix.equals(_identityMatrix$1)) {
41037          matrix = null;
41038        }
41039      },
41040          recordStartPositions = function recordStartPositions() {
41041        var edgeTolerance = 1 - self.edgeResistance,
41042            offsetX = isFixed ? _getDocScrollLeft$1(ownerDoc) : 0,
41043            offsetY = isFixed ? _getDocScrollTop$1(ownerDoc) : 0,
41044            parsedOrigin,
41045            x,
41046            y;
41047
41048        if (xyMode) {
41049          gsCache.x = getPropAsNum(xProp, "px") + "px";
41050          gsCache.y = getPropAsNum(yProp, "px") + "px";
41051          gsCache.renderTransform();
41052        }
41053
41054        updateMatrix(false);
41055        _point1.x = self.pointerX - offsetX;
41056        _point1.y = self.pointerY - offsetY;
41057        matrix && matrix.apply(_point1, _point1);
41058        startPointerX = _point1.x;
41059        startPointerY = _point1.y;
41060
41061        if (dirty) {
41062          setPointerPosition(self.pointerX, self.pointerY);
41063          render(true);
41064        }
41065
41066        innerMatrix = getGlobalMatrix(target);
41067
41068        if (scrollProxy) {
41069          calculateBounds();
41070          startElementY = scrollProxy.top();
41071          startElementX = scrollProxy.left();
41072        } else {
41073          if (isTweening()) {
41074            syncXY(true, true);
41075            calculateBounds();
41076          } else {
41077            self.applyBounds();
41078          }
41079
41080          if (rotationMode) {
41081            parsedOrigin = target.ownerSVGElement ? [gsCache.xOrigin - target.getBBox().x, gsCache.yOrigin - target.getBBox().y] : (_getComputedStyle(target)[_transformOriginProp$1] || "0 0").split(" ");
41082            rotationOrigin = self.rotationOrigin = getGlobalMatrix(target).apply({
41083              x: parseFloat(parsedOrigin[0]) || 0,
41084              y: parseFloat(parsedOrigin[1]) || 0
41085            });
41086            syncXY(true, true);
41087            x = self.pointerX - rotationOrigin.x - offsetX;
41088            y = rotationOrigin.y - self.pointerY + offsetY;
41089            startElementX = self.x;
41090            startElementY = self.y = Math.atan2(y, x) * _RAD2DEG;
41091          } else {
41092            startElementY = getPropAsNum(yProp, "px");
41093            startElementX = getPropAsNum(xProp, "px");
41094          }
41095        }
41096
41097        if (hasBounds && edgeTolerance) {
41098          if (startElementX > maxX) {
41099            startElementX = maxX + (startElementX - maxX) / edgeTolerance;
41100          } else if (startElementX < minX) {
41101            startElementX = minX - (minX - startElementX) / edgeTolerance;
41102          }
41103
41104          if (!rotationMode) {
41105            if (startElementY > maxY) {
41106              startElementY = maxY + (startElementY - maxY) / edgeTolerance;
41107            } else if (startElementY < minY) {
41108              startElementY = minY - (minY - startElementY) / edgeTolerance;
41109            }
41110          }
41111        }
41112
41113        self.startX = startElementX = _round(startElementX);
41114        self.startY = startElementY = _round(startElementY);
41115      },
41116          isTweening = function isTweening() {
41117        return self.tween && self.tween.isActive();
41118      },
41119          removePlaceholder = function removePlaceholder() {
41120        if (_placeholderDiv.parentNode && !isTweening() && !self.isDragging) {
41121          _placeholderDiv.parentNode.removeChild(_placeholderDiv);
41122        }
41123      },
41124          onPress = function onPress(e, force) {
41125        var i;
41126
41127        if (!enabled || self.isPressed || !e || (e.type === "mousedown" || e.type === "pointerdown") && !force && _getTime() - clickTime < 30 && _touchEventLookup[self.pointerEvent.type]) {
41128          isPreventingDefault && e && enabled && _preventDefault(e);
41129          return;
41130        }
41131
41132        interrupted = isTweening();
41133        dragged = false;
41134        self.pointerEvent = e;
41135
41136        if (_touchEventLookup[e.type]) {
41137          touchEventTarget = ~e.type.indexOf("touch") ? e.currentTarget || e.target : ownerDoc;
41138
41139          _addListener(touchEventTarget, "touchend", onRelease);
41140
41141          _addListener(touchEventTarget, "touchmove", onMove);
41142
41143          _addListener(touchEventTarget, "touchcancel", onRelease);
41144
41145          _addListener(ownerDoc, "touchstart", _onMultiTouchDocument);
41146        } else {
41147          touchEventTarget = null;
41148
41149          _addListener(ownerDoc, "mousemove", onMove);
41150        }
41151
41152        touchDragAxis = null;
41153
41154        if (!_supportsPointer || !touchEventTarget) {
41155          _addListener(ownerDoc, "mouseup", onRelease);
41156
41157          e && e.target && _addListener(e.target, "mouseup", onRelease);
41158        }
41159
41160        isClicking = isClickable.call(self, e.target) && vars.dragClickables === false && !force;
41161
41162        if (isClicking) {
41163          _addListener(e.target, "change", onRelease);
41164
41165          _dispatchEvent(self, "pressInit", "onPressInit");
41166
41167          _dispatchEvent(self, "press", "onPress");
41168
41169          _setSelectable(triggers, true);
41170
41171          isPreventingDefault = false;
41172          return;
41173        }
41174
41175        allowNativeTouchScrolling = !touchEventTarget || allowX === allowY || self.vars.allowNativeTouchScrolling === false || self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2) ? false : allowX ? "y" : "x";
41176        isPreventingDefault = !allowNativeTouchScrolling && !self.allowEventDefault;
41177
41178        if (isPreventingDefault) {
41179          _preventDefault(e);
41180
41181          _addListener(_win$1, "touchforcechange", _preventDefault);
41182        }
41183
41184        if (e.changedTouches) {
41185          e = touch = e.changedTouches[0];
41186          touchID = e.identifier;
41187        } else if (e.pointerId) {
41188          touchID = e.pointerId;
41189        } else {
41190          touch = touchID = null;
41191        }
41192
41193        _dragCount++;
41194
41195        _addToRenderQueue(render);
41196
41197        startPointerY = self.pointerY = e.pageY;
41198        startPointerX = self.pointerX = e.pageX;
41199
41200        _dispatchEvent(self, "pressInit", "onPressInit");
41201
41202        if (allowNativeTouchScrolling || self.autoScroll) {
41203          _recordMaxScrolls(target.parentNode);
41204        }
41205
41206        if (target.parentNode && self.autoScroll && !scrollProxy && !rotationMode && target.parentNode._gsMaxScrollX && !_placeholderDiv.parentNode && !target.getBBox) {
41207          _placeholderDiv.style.width = target.parentNode.scrollWidth + "px";
41208          target.parentNode.appendChild(_placeholderDiv);
41209        }
41210
41211        recordStartPositions();
41212        self.tween && self.tween.kill();
41213        self.isThrowing = false;
41214        gsap.killTweensOf(scrollProxy || target, killProps, true);
41215        scrollProxy && gsap.killTweensOf(target, {
41216          scrollTo: 1
41217        }, true);
41218        self.tween = self.lockedAxis = null;
41219
41220        if (vars.zIndexBoost || !rotationMode && !scrollProxy && vars.zIndexBoost !== false) {
41221          target.style.zIndex = Draggable.zIndex++;
41222        }
41223
41224        self.isPressed = true;
41225        hasDragCallback = !!(vars.onDrag || self._listeners.drag);
41226        hasMoveCallback = !!(vars.onMove || self._listeners.move);
41227
41228        if (vars.cursor !== false || vars.activeCursor) {
41229          i = triggers.length;
41230
41231          while (--i > -1) {
41232            gsap.set(triggers[i], {
41233              cursor: vars.activeCursor || vars.cursor || (_defaultCursor === "grab" ? "grabbing" : _defaultCursor)
41234            });
41235          }
41236        }
41237
41238        _dispatchEvent(self, "press", "onPress");
vendor: 2,447 bytes, lines 41239-41306
41239      },
41240          onMove = function onMove(e) {
41241        var originalEvent = e,
41242            touches,
41243            pointerX,
41244            pointerY,
41245            i,
41246            dx,
41247            dy;
41248
41249        if (!enabled || _isMultiTouching || !self.isPressed || !e) {
41250          isPreventingDefault && e && enabled && _preventDefault(e);
41251          return;
41252        }
41253
41254        self.pointerEvent = e;
41255        touches = e.changedTouches;
41256
41257        if (touches) {
41258          e = touches[0];
41259
41260          if (e !== touch && e.identifier !== touchID) {
41261            i = touches.length;
41262
41263            while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {}
41264
41265            if (i < 0) {
41266              return;
41267            }
41268          }
41269        } else if (e.pointerId && touchID && e.pointerId !== touchID) {
41270          return;
41271        }
41272
41273        if (touchEventTarget && allowNativeTouchScrolling && !touchDragAxis) {
41274          _point1.x = e.pageX - (isFixed ? _getDocScrollLeft$1(ownerDoc) : 0);
41275          _point1.y = e.pageY - (isFixed ? _getDocScrollTop$1(ownerDoc) : 0);
41276          matrix && matrix.apply(_point1, _point1);
41277          pointerX = _point1.x;
41278          pointerY = _point1.y;
41279          dx = Math.abs(pointerX - startPointerX);
41280          dy = Math.abs(pointerY - startPointerY);
41281
41282          if (dx !== dy && (dx > minimumMovement || dy > minimumMovement) || _isAndroid && allowNativeTouchScrolling === touchDragAxis) {
41283            touchDragAxis = dx > dy && allowX ? "x" : "y";
41284
41285            if (allowNativeTouchScrolling && touchDragAxis !== allowNativeTouchScrolling) {
41286              _addListener(_win$1, "touchforcechange", _preventDefault);
41287            }
41288
41289            if (self.vars.lockAxisOnTouchScroll !== false && allowX && allowY) {
41290              self.lockedAxis = touchDragAxis === "x" ? "y" : "x";
41291              _isFunction(self.vars.onLockAxis) && self.vars.onLockAxis.call(self, originalEvent);
41292            }
41293
41294            if (_isAndroid && allowNativeTouchScrolling === touchDragAxis) {
41295              onRelease(originalEvent);
41296              return;
41297            }
41298          }
41299        }
41300
41301        if (!self.allowEventDefault && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling !== touchDragAxis) && originalEvent.cancelable !== false) {
41302          _preventDefault(originalEvent);
41303
41304          isPreventingDefault = true;
41305        } else if (isPreventingDefault) {
41306          isPreventingDefault = false;
vendor: 3,917 bytes, lines 41307-41435
41307        }
41308
41309        if (self.autoScroll) {
41310          checkAutoScrollBounds = true;
41311        }
41312
41313        setPointerPosition(e.pageX, e.pageY, hasMoveCallback);
41314      },
41315          setPointerPosition = function setPointerPosition(pointerX, pointerY, invokeOnMove) {
41316        var dragTolerance = 1 - self.dragResistance,
41317            edgeTolerance = 1 - self.edgeResistance,
41318            prevPointerX = self.pointerX,
41319            prevPointerY = self.pointerY,
41320            prevStartElementY = startElementY,
41321            prevX = self.x,
41322            prevY = self.y,
41323            prevEndX = self.endX,
41324            prevEndY = self.endY,
41325            prevEndRotation = self.endRotation,
41326            prevDirty = dirty,
41327            xChange,
41328            yChange,
41329            x,
41330            y,
41331            dif,
41332            temp;
41333        self.pointerX = pointerX;
41334        self.pointerY = pointerY;
41335
41336        if (isFixed) {
41337          pointerX -= _getDocScrollLeft$1(ownerDoc);
41338          pointerY -= _getDocScrollTop$1(ownerDoc);
41339        }
41340
41341        if (rotationMode) {
41342          y = Math.atan2(rotationOrigin.y - pointerY, pointerX - rotationOrigin.x) * _RAD2DEG;
41343          dif = self.y - y;
41344
41345          if (dif > 180) {
41346            startElementY -= 360;
41347            self.y = y;
41348          } else if (dif < -180) {
41349            startElementY += 360;
41350            self.y = y;
41351          }
41352
41353          if (self.x !== startElementX || Math.abs(startElementY - y) > minimumMovement) {
41354            self.y = y;
41355            x = startElementX + (startElementY - y) * dragTolerance;
41356          } else {
41357            x = startElementX;
41358          }
41359        } else {
41360          if (matrix) {
41361            temp = pointerX * matrix.a + pointerY * matrix.c + matrix.e;
41362            pointerY = pointerX * matrix.b + pointerY * matrix.d + matrix.f;
41363            pointerX = temp;
41364          }
41365
41366          yChange = pointerY - startPointerY;
41367          xChange = pointerX - startPointerX;
41368
41369          if (yChange < minimumMovement && yChange > -minimumMovement) {
41370            yChange = 0;
41371          }
41372
41373          if (xChange < minimumMovement && xChange > -minimumMovement) {
41374            xChange = 0;
41375          }
41376
41377          if ((self.lockAxis || self.lockedAxis) && (xChange || yChange)) {
41378            temp = self.lockedAxis;
41379
41380            if (!temp) {
41381              self.lockedAxis = temp = allowX && Math.abs(xChange) > Math.abs(yChange) ? "y" : allowY ? "x" : null;
41382
41383              if (temp && _isFunction(self.vars.onLockAxis)) {
41384                self.vars.onLockAxis.call(self, self.pointerEvent);
41385              }
41386            }
41387
41388            if (temp === "y") {
41389              yChange = 0;
41390            } else if (temp === "x") {
41391              xChange = 0;
41392            }
41393          }
41394
41395          x = _round(startElementX + xChange * dragTolerance);
41396          y = _round(startElementY + yChange * dragTolerance);
41397        }
41398
41399        if ((snapX || snapY || snapXY) && (self.x !== x || self.y !== y && !rotationMode)) {
41400          if (snapXY) {
41401            _temp1.x = x;
41402            _temp1.y = y;
41403            temp = snapXY(_temp1);
41404            x = _round(temp.x);
41405            y = _round(temp.y);
41406          }
41407
41408          if (snapX) {
41409            x = _round(snapX(x));
41410          }
41411
41412          if (snapY) {
41413            y = _round(snapY(y));
41414          }
41415        }
41416
41417        if (hasBounds) {
41418          if (x > maxX) {
41419            x = maxX + Math.round((x - maxX) * edgeTolerance);
41420          } else if (x < minX) {
41421            x = minX + Math.round((x - minX) * edgeTolerance);
41422          }
41423
41424          if (!rotationMode) {
41425            if (y > maxY) {
41426              y = Math.round(maxY + (y - maxY) * edgeTolerance);
41427            } else if (y < minY) {
41428              y = Math.round(minY + (y - minY) * edgeTolerance);
41429            }
41430          }
41431        }
41432
41433        if (self.x !== x || self.y !== y && !rotationMode) {
41434          if (rotationMode) {
41435            self.endRotation = self.x = self.endX = x
vendor: 13,666 bytes, lines 41435-41842
41435;
41436            dirty = true;
41437          } else {
41438            if (allowY) {
41439              self.y = self.endY = y;
41440              dirty = true;
41441            }
41442
41443            if (allowX) {
41444              self.x = self.endX = x;
41445              dirty = true;
41446            }
41447          }
41448
41449          if (!invokeOnMove || _dispatchEvent(self, "move", "onMove") !== false) {
41450            if (!self.isDragging && self.isPressed) {
41451              self.isDragging = dragged = true;
41452
41453              _dispatchEvent(self, "dragstart", "onDragStart");
41454            }
41455          } else {
41456            self.pointerX = prevPointerX;
41457            self.pointerY = prevPointerY;
41458            startElementY = prevStartElementY;
41459            self.x = prevX;
41460            self.y = prevY;
41461            self.endX = prevEndX;
41462            self.endY = prevEndY;
41463            self.endRotation = prevEndRotation;
41464            dirty = prevDirty;
41465          }
41466        }
41467      },
41468          onRelease = function onRelease(e, force) {
41469        if (!enabled || !self.isPressed || e && touchID != null && !force && (e.pointerId && e.pointerId !== touchID && e.target !== target || e.changedTouches && !_hasTouchID(e.changedTouches, touchID))) {
41470          isPreventingDefault && e && enabled && _preventDefault(e);
41471          return;
41472        }
41473
41474        self.isPressed = false;
41475        var originalEvent = e,
41476            wasDragging = self.isDragging,
41477            isContextMenuRelease = self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2),
41478            placeholderDelayedCall = gsap.delayedCall(0.001, removePlaceholder),
41479            touches,
41480            i,
41481            syntheticEvent,
41482            eventTarget,
41483            syntheticClick;
41484
41485        if (touchEventTarget) {
41486          _removeListener(touchEventTarget, "touchend", onRelease);
41487
41488          _removeListener(touchEventTarget, "touchmove", onMove);
41489
41490          _removeListener(touchEventTarget, "touchcancel", onRelease);
41491
41492          _removeListener(ownerDoc, "touchstart", _onMultiTouchDocument);
41493        } else {
41494          _removeListener(ownerDoc, "mousemove", onMove);
41495        }
41496
41497        _removeListener(_win$1, "touchforcechange", _preventDefault);
41498
41499        if (!_supportsPointer || !touchEventTarget) {
41500          _removeListener(ownerDoc, "mouseup", onRelease);
41501
41502          e && e.target && _removeListener(e.target, "mouseup", onRelease);
41503        }
41504
41505        dirty = false;
41506
41507        if (wasDragging) {
41508          dragEndTime = _lastDragTime = _getTime();
41509          self.isDragging = false;
41510        }
41511
41512        _removeFromRenderQueue(render);
41513
41514        if (isClicking && !isContextMenuRelease) {
41515          if (e) {
41516            _removeListener(e.target, "change", onRelease);
41517
41518            self.pointerEvent = originalEvent;
41519          }
41520
41521          _setSelectable(triggers, false);
41522
41523          _dispatchEvent(self, "release", "onRelease");
41524
41525          _dispatchEvent(self, "click", "onClick");
41526
41527          isClicking = false;
41528          return;
41529        }
41530
41531        i = triggers.length;
41532
41533        while (--i > -1) {
41534          _setStyle(triggers[i], "cursor", vars.cursor || (vars.cursor !== false ? _defaultCursor : null));
41535        }
41536
41537        _dragCount--;
41538
41539        if (e) {
41540          touches = e.changedTouches;
41541
41542          if (touches) {
41543            e = touches[0];
41544
41545            if (e !== touch && e.identifier !== touchID) {
41546              i = touches.length;
41547
41548              while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {}
41549
41550              if (i < 0 && !force) {
41551                return;
41552              }
41553            }
41554          }
41555
41556          self.pointerEvent = originalEvent;
41557          self.pointerX = e.pageX;
41558          self.pointerY = e.pageY;
41559        }
41560
41561        if (isContextMenuRelease && originalEvent) {
41562          _preventDefault(originalEvent);
41563
41564          isPreventingDefault = true;
41565
41566          _dispatchEvent(self, "release", "onRelease");
41567        } else if (originalEvent && !wasDragging) {
41568          isPreventingDefault = false;
41569
41570          if (interrupted && (vars.snap || vars.bounds)) {
41571            animate(vars.inertia || vars.throwProps);
41572          }
41573
41574          _dispatchEvent(self, "release", "onRelease");
41575
41576          if ((!_isAndroid || originalEvent.type !== "touchmove") && originalEvent.type.indexOf("cancel") === -1) {
41577            _dispatchEvent(self, "click", "onClick");
41578
41579            if (_getTime() - clickTime < 300) {
41580              _dispatchEvent(self, "doubleclick", "onDoubleClick");
41581            }
41582
41583            eventTarget = originalEvent.target || target;
41584            clickTime = _getTime();
41585
41586            syntheticClick = function syntheticClick() {
41587              if (clickTime !== clickDispatch && self.enabled() && !self.isPressed && !originalEvent.defaultPrevented) {
41588                if (eventTarget.click) {
41589                  eventTarget.click();
41590                } else if (ownerDoc.createEvent) {
41591                  syntheticEvent = ownerDoc.createEvent("MouseEvents");
41592                  syntheticEvent.initMouseEvent("click", true, true, _win$1, 1, self.pointerEvent.screenX, self.pointerEvent.screenY, self.pointerX, self.pointerY, false, false, false, false, 0, null);
41593                  eventTarget.dispatchEvent(syntheticEvent);
41594                }
41595              }
41596            };
41597
41598            if (!_isAndroid && !originalEvent.defaultPrevented) {
41599              gsap.delayedCall(0.05, syntheticClick);
41600            }
41601          }
41602        } else {
41603          animate(vars.inertia || vars.throwProps);
41604
41605          if (!self.allowEventDefault && originalEvent && (vars.dragClickables !== false || !isClickable.call(self, originalEvent.target)) && wasDragging && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling === touchDragAxis) && originalEvent.cancelable !== false) {
41606            isPreventingDefault = true;
41607
41608            _preventDefault(originalEvent);
41609          } else {
41610            isPreventingDefault = false;
41611          }
41612
41613          _dispatchEvent(self, "release", "onRelease");
41614        }
41615
41616        isTweening() && placeholderDelayedCall.duration(self.tween.duration());
41617        wasDragging && _dispatchEvent(self, "dragend", "onDragEnd");
41618        return true;
41619      },
41620          updateScroll = function updateScroll(e) {
41621        if (e && self.isDragging && !scrollProxy) {
41622          var parent = e.target || target.parentNode,
41623              deltaX = parent.scrollLeft - parent._gsScrollX,
41624              deltaY = parent.scrollTop - parent._gsScrollY;
41625
41626          if (deltaX || deltaY) {
41627            if (matrix) {
41628              startPointerX -= deltaX * matrix.a + deltaY * matrix.c;
41629              startPointerY -= deltaY * matrix.d + deltaX * matrix.b;
41630            } else {
41631              startPointerX -= deltaX;
41632              startPointerY -= deltaY;
41633            }
41634
41635            parent._gsScrollX += deltaX;
41636            parent._gsScrollY += deltaY;
41637            setPointerPosition(self.pointerX, self.pointerY);
41638          }
41639        }
41640      },
41641          onClick = function onClick(e) {
41642        var time = _getTime(),
41643            recentlyClicked = time - clickTime < 100,
41644            recentlyDragged = time - dragEndTime < 50,
41645            alreadyDispatched = recentlyClicked && clickDispatch === clickTime,
41646            defaultPrevented = self.pointerEvent && self.pointerEvent.defaultPrevented,
41647            alreadyDispatchedTrusted = recentlyClicked && trustedClickDispatch === clickTime,
41648            trusted = e.isTrusted || e.isTrusted == null && recentlyClicked && alreadyDispatched;
41649
41650        if ((alreadyDispatched || recentlyDragged && self.vars.suppressClickOnDrag !== false) && e.stopImmediatePropagation) {
41651          e.stopImmediatePropagation();
41652        }
41653
41654        if (recentlyClicked && !(self.pointerEvent && self.pointerEvent.defaultPrevented) && (!alreadyDispatched || trusted && !alreadyDispatchedTrusted)) {
41655          if (trusted && alreadyDispatched) {
41656            trustedClickDispatch = clickTime;
41657          }
41658
41659          clickDispatch = clickTime;
41660          return;
41661        }
41662
41663        if (self.isPressed || recentlyDragged || recentlyClicked) {
41664          if (!trusted || !e.detail || !recentlyClicked || defaultPrevented) {
41665            _preventDefault(e);
41666          }
41667        }
41668
41669        if (!recentlyClicked && !recentlyDragged && !dragged) {
41670          e && e.target && (self.pointerEvent = e);
41671
41672          _dispatchEvent(self, "click", "onClick");
41673        }
41674      },
41675          localizePoint = function localizePoint(p) {
41676        return matrix ? {
41677          x: p.x * matrix.a + p.y * matrix.c + matrix.e,
41678          y: p.x * matrix.b + p.y * matrix.d + matrix.f
41679        } : {
41680          x: p.x,
41681          y: p.y
41682        };
41683      };
41684
41685      old = Draggable.get(target);
41686      old && old.kill();
41687
41688      _this2.startDrag = function (event, align) {
41689        var r1, r2, p1, p2;
41690        onPress(event || self.pointerEvent, true);
41691
41692        if (align && !self.hitTest(event || self.pointerEvent)) {
41693          r1 = _parseRect(event || self.pointerEvent);
41694          r2 = _parseRect(target);
41695          p1 = localizePoint({
41696            x: r1.left + r1.width / 2,
41697            y: r1.top + r1.height / 2
41698          });
41699          p2 = localizePoint({
41700            x: r2.left + r2.width / 2,
41701            y: r2.top + r2.height / 2
41702          });
41703          startPointerX -= p1.x - p2.x;
41704          startPointerY -= p1.y - p2.y;
41705        }
41706
41707        if (!self.isDragging) {
41708          self.isDragging = dragged = true;
41709
41710          _dispatchEvent(self, "dragstart", "onDragStart");
41711        }
41712      };
41713
41714      _this2.drag = onMove;
41715
41716      _this2.endDrag = function (e) {
41717        return onRelease(e || self.pointerEvent, true);
41718      };
41719
41720      _this2.timeSinceDrag = function () {
41721        return self.isDragging ? 0 : (_getTime() - dragEndTime) / 1000;
41722      };
41723
41724      _this2.timeSinceClick = function () {
41725        return (_getTime() - clickTime) / 1000;
41726      };
41727
41728      _this2.hitTest = function (target, threshold) {
41729        return Draggable.hitTest(self.target, target, threshold);
41730      };
41731
41732      _this2.getDirection = function (from, diagonalThreshold) {
41733        var mode = from === "velocity" && InertiaPlugin ? from : _isObject(from) && !rotationMode ? "element" : "start",
41734            xChange,
41735            yChange,
41736            ratio,
41737            direction,
41738            r1,
41739            r2;
41740
41741        if (mode === "element") {
41742          r1 = _parseRect(self.target);
41743          r2 = _parseRect(from);
41744        }
41745
41746        xChange = mode === "start" ? self.x - startElementX : mode === "velocity" ? InertiaPlugin.getVelocity(target, xProp) : r1.left + r1.width / 2 - (r2.left + r2.width / 2);
41747
41748        if (rotationMode) {
41749          return xChange < 0 ? "counter-clockwise" : "clockwise";
41750        } else {
41751          diagonalThreshold = diagonalThreshold || 2;
41752          yChange = mode === "start" ? self.y - startElementY : mode === "velocity" ? InertiaPlugin.getVelocity(target, yProp) : r1.top + r1.height / 2 - (r2.top + r2.height / 2);
41753          ratio = Math.abs(xChange / yChange);
41754          direction = ratio < 1 / diagonalThreshold ? "" : xChange < 0 ? "left" : "right";
41755
41756          if (ratio < diagonalThreshold) {
41757            if (direction !== "") {
41758              direction += "-";
41759            }
41760
41761            direction += yChange < 0 ? "up" : "down";
41762          }
41763        }
41764
41765        return direction;
41766      };
41767
41768      _this2.applyBounds = function (newBounds, sticky) {
41769        var x, y, forceZeroVelocity, e, parent, isRoot;
41770
41771        if (newBounds && vars.bounds !== newBounds) {
41772          vars.bounds = newBounds;
41773          return self.update(true, sticky);
41774        }
41775
41776        syncXY(true);
41777        calculateBounds();
41778
41779        if (hasBounds && !isTweening()) {
41780          x = self.x;
41781          y = self.y;
41782
41783          if (x > maxX) {
41784            x = maxX;
41785          } else if (x < minX) {
41786            x = minX;
41787          }
41788
41789          if (y > maxY) {
41790            y = maxY;
41791          } else if (y < minY) {
41792            y = minY;
41793          }
41794
41795          if (self.x !== x || self.y !== y) {
41796            forceZeroVelocity = true;
41797            self.x = self.endX = x;
41798
41799            if (rotationMode) {
41800              self.endRotation = x;
41801            } else {
41802              self.y = self.endY = y;
41803            }
41804
41805            dirty = true;
41806            render(true);
41807
41808            if (self.autoScroll && !self.isDragging) {
41809              _recordMaxScrolls(target.parentNode);
41810
41811              e = target;
41812              _windowProxy.scrollTop = _win$1.pageYOffset != null ? _win$1.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop;
41813              _windowProxy.scrollLeft = _win$1.pageXOffset != null ? _win$1.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft;
41814
41815              while (e && !isRoot) {
41816                isRoot = _isRoot(e.parentNode);
41817                parent = isRoot ? _windowProxy : e.parentNode;
41818
41819                if (allowY && parent.scrollTop > parent._gsMaxScrollY) {
41820                  parent.scrollTop = parent._gsMaxScrollY;
41821                }
41822
41823                if (allowX && parent.scrollLeft > parent._gsMaxScrollX) {
41824                  parent.scrollLeft = parent._gsMaxScrollX;
41825                }
41826
41827                e = parent;
41828              }
41829            }
41830          }
41831
41832          if (self.isThrowing && (forceZeroVelocity || self.endX > maxX || self.endX < minX || self.endY > maxY || self.endY < minY)) {
41833            animate(vars.inertia || vars.throwProps, forceZeroVelocity);
41834          }
41835        }
41836
41837        return self;
41838      };
41839
41840      _this2.update = function (applyBounds, sticky, ignoreExternalChanges) {
41841        if (sticky && self.isPressed) {
41842          
vendor: 3,070 bytes, lines 41842-41943
41842var m = getGlobalMatrix(target),
41843              p = innerMatrix.apply({
41844            x: self.x - startElementX,
41845            y: self.y - startElementY
41846          }),
41847              m2 = getGlobalMatrix(target.parentNode, true);
41848          m2.apply({
41849            x: m.e - p.x,
41850            y: m.f - p.y
41851          }, p);
41852          self.x -= p.x - m2.e;
41853          self.y -= p.y - m2.f;
41854          render(true);
41855          recordStartPositions();
41856        }
41857
41858        var x = self.x,
41859            y = self.y;
41860        updateMatrix(!sticky);
41861
41862        if (applyBounds) {
41863          self.applyBounds();
41864        } else {
41865          dirty && ignoreExternalChanges && render(true);
41866          syncXY(true);
41867        }
41868
41869        if (sticky) {
41870          setPointerPosition(self.pointerX, self.pointerY);
41871          dirty && render(true);
41872        }
41873
41874        if (self.isPressed && !sticky && (allowX && Math.abs(x - self.x) > 0.01 || allowY && Math.abs(y - self.y) > 0.01 && !rotationMode)) {
41875          recordStartPositions();
41876        }
41877
41878        if (self.autoScroll) {
41879          _recordMaxScrolls(target.parentNode, self.isDragging);
41880
41881          checkAutoScrollBounds = self.isDragging;
41882          render(true);
41883
41884          _removeScrollListener(target, updateScroll);
41885
41886          _addScrollListener(target, updateScroll);
41887        }
41888
41889        return self;
41890      };
41891
41892      _this2.enable = function (type) {
41893        var setVars = {
41894          lazy: true
41895        },
41896            id,
41897            i,
41898            trigger;
41899
41900        if (vars.cursor !== false) {
41901          setVars.cursor = vars.cursor || _defaultCursor;
41902        }
41903
41904        if (gsap.utils.checkPrefix("touchCallout")) {
41905          setVars.touchCallout = "none";
41906        }
41907
41908        if (type !== "soft") {
41909          _setTouchActionForAllDescendants(triggers, allowX === allowY ? "none" : vars.allowNativeTouchScrolling && target.scrollHeight === target.clientHeight === (target.scrollWidth === target.clientHeight) || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x");
41910
41911          i = triggers.length;
41912
41913          while (--i > -1) {
41914            trigger = triggers[i];
41915            _supportsPointer || _addListener(trigger, "mousedown", onPress);
41916
41917            _addListener(trigger, "touchstart", onPress);
41918
41919            _addListener(trigger, "click", onClick, true);
41920
41921            gsap.set(trigger, setVars);
41922
41923            if (trigger.getBBox && trigger.ownerSVGElement && allowX !== allowY) {
41924              gsap.set(trigger.ownerSVGElement, {
41925                touchAction: vars.allowNativeTouchScrolling || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x"
41926              });
41927            }
41928
41929            vars.allowContextMenu || _addListener(trigger, "contextmenu", onContextMenu);
41930          }
41931
41932          _setSelectable(triggers, false);
41933        }
41934
41935        _addScrollListener(target, updateScroll);
41936
41937        enabled = true;
41938
41939        if (InertiaPlugin && type !== "soft") {
41940          InertiaPlugin.track(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left");
41941        }
41942
41943        target._gsDragID = id =
vendor: 5,466 bytes, lines 41943-42149
41943 "d" + _lookupCount++;
41944        _lookup[id] = self;
41945
41946        if (scrollProxy) {
41947          scrollProxy.enable();
41948          scrollProxy.element._gsDragID = id;
41949        }
41950
41951        (vars.bounds || rotationMode) && recordStartPositions();
41952        vars.bounds && self.applyBounds();
41953        return self;
41954      };
41955
41956      _this2.disable = function (type) {
41957        var dragging = self.isDragging,
41958            i = triggers.length,
41959            trigger;
41960
41961        while (--i > -1) {
41962          _setStyle(triggers[i], "cursor", null);
41963        }
41964
41965        if (type !== "soft") {
41966          _setTouchActionForAllDescendants(triggers, null);
41967
41968          i = triggers.length;
41969
41970          while (--i > -1) {
41971            trigger = triggers[i];
41972
41973            _setStyle(trigger, "touchCallout", null);
41974
41975            _removeListener(trigger, "mousedown", onPress);
41976
41977            _removeListener(trigger, "touchstart", onPress);
41978
41979            _removeListener(trigger, "click", onClick, true);
41980
41981            _removeListener(trigger, "contextmenu", onContextMenu);
41982          }
41983
41984          _setSelectable(triggers, true);
41985
41986          if (touchEventTarget) {
41987            _removeListener(touchEventTarget, "touchcancel", onRelease);
41988
41989            _removeListener(touchEventTarget, "touchend", onRelease);
41990
41991            _removeListener(touchEventTarget, "touchmove", onMove);
41992          }
41993
41994          _removeListener(ownerDoc, "mouseup", onRelease);
41995
41996          _removeListener(ownerDoc, "mousemove", onMove);
41997        }
41998
41999        _removeScrollListener(target, updateScroll);
42000
42001        enabled = false;
42002
42003        if (InertiaPlugin && type !== "soft") {
42004          InertiaPlugin.untrack(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left");
42005          self.tween && self.tween.kill();
42006        }
42007
42008        scrollProxy && scrollProxy.disable();
42009
42010        _removeFromRenderQueue(render);
42011
42012        self.isDragging = self.isPressed = isClicking = false;
42013        dragging && _dispatchEvent(self, "dragend", "onDragEnd");
42014        return self;
42015      };
42016
42017      _this2.enabled = function (value, type) {
42018        return arguments.length ? value ? self.enable(type) : self.disable(type) : enabled;
42019      };
42020
42021      _this2.kill = function () {
42022        self.isThrowing = false;
42023        self.tween && self.tween.kill();
42024        self.disable();
42025        gsap.set(triggers, {
42026          clearProps: "userSelect"
42027        });
42028        delete _lookup[target._gsDragID];
42029        return self;
42030      };
42031
42032      _this2.revert = function () {
42033        this.kill();
42034        this.styles && this.styles.revert();
42035      };
42036
42037      if (~type.indexOf("scroll")) {
42038        scrollProxy = _this2.scrollProxy = new ScrollProxy(target, _extend({
42039          onKill: function onKill() {
42040            self.isPressed && onRelease(null);
42041          }
42042        }, vars));
42043        target.style.overflowY = allowY && !_isTouchDevice ? "auto" : "hidden";
42044        target.style.overflowX = allowX && !_isTouchDevice ? "auto" : "hidden";
42045        target = scrollProxy.content;
42046      }
42047
42048      if (rotationMode) {
42049        killProps.rotation = 1;
42050      } else {
42051        if (allowX) {
42052          killProps[xProp] = 1;
42053        }
42054
42055        if (allowY) {
42056          killProps[yProp] = 1;
42057        }
42058      }
42059
42060      gsCache.force3D = "force3D" in vars ? vars.force3D : true;
42061
42062      _context(_assertThisInitialized(_this2));
42063
42064      _this2.enable();
42065
42066      return _this2;
42067    }
42068
42069    Draggable.register = function register(core) {
42070      gsap = core;
42071
42072      _initCore();
42073    };
42074
42075    Draggable.create = function create(targets, vars) {
42076      _coreInitted || _initCore(true);
42077      return _toArray(targets).map(function (target) {
42078        return new Draggable(target, vars);
42079      });
42080    };
42081
42082    Draggable.get = function get(target) {
42083      return _lookup[(_toArray(target)[0] || {})._gsDragID];
42084    };
42085
42086    Draggable.timeSinceDrag = function timeSinceDrag() {
42087      return (_getTime() - _lastDragTime) / 1000;
42088    };
42089
42090    Draggable.hitTest = function hitTest(obj1, obj2, threshold) {
42091      if (obj1 === obj2) {
42092        return false;
42093      }
42094
42095      var r1 = _parseRect(obj1),
42096          r2 = _parseRect(obj2),
42097          top = r1.top,
42098          left = r1.left,
42099          right = r1.right,
42100          bottom = r1.bottom,
42101          width = r1.width,
42102          height = r1.height,
42103          isOutside = r2.left > right || r2.right < left || r2.top > bottom || r2.bottom < top,
42104          overlap,
42105          area,
42106          isRatio;
42107
42108      if (isOutside || !threshold) {
42109        return !isOutside;
42110      }
42111
42112      isRatio = (threshold + "").indexOf("%") !== -1;
42113      threshold = parseFloat(threshold) || 0;
42114      overlap = {
42115        left: Math.max(left, r2.left),
42116        top: Math.max(top, r2.top)
42117      };
42118      overlap.width = Math.min(right, r2.right) - overlap.left;
42119      overlap.height = Math.min(bottom, r2.bottom) - overlap.top;
42120
42121      if (overlap.width < 0 || overlap.height < 0) {
42122        return false;
42123      }
42124
42125      if (isRatio) {
42126        threshold *= 0.01;
42127        area = overlap.width * overlap.height;
42128        return area >= width * height * threshold || area >= r2.width * r2.height * threshold;
42129      }
42130
42131      return overlap.width > threshold && overlap.height > threshold;
42132    };
42133
42134    return Draggable;
42135  }(EventDispatcher);
42136
42137  _setDefaults(Draggable.prototype, {
42138    pointerX: 0,
42139    pointerY: 0,
42140    startX: 0,
42141    startY: 0,
42142    deltaX: 0,
42143    deltaY: 0,
42144    isDragging: false,
42145    isPressed: false
42146  });
42147
42148  Draggable.zIndex = 1000;
42149  Draggable.version = "3.1
vendor: 15,817 bytes, lines 42149-42692
421492.5";
42150  _getGSAP() && gsap.registerPlugin(Draggable);
42151
42152  exports.Draggable = Draggable;
42153  exports.default = Draggable;
42154
42155  if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;}
42156
42157})));
42158/* ========================================================================
42159 * Bootstrap: collapse.js v3.1.1
42160 * http://getbootstrap.com/javascript/#collapse
42161 * ========================================================================
42162 * Copyright 2011-2014 Twitter, Inc.
42163 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42164 * ======================================================================== */
42165
42166
42167+function ($) {
42168	'use strict';
42169
42170	// COLLAPSE PUBLIC CLASS DEFINITION
42171	// ================================
42172
42173	var Collapse = function (element, options) {
42174		this.$element      = $(element)
42175		this.options       = $.extend({}, Collapse.DEFAULTS, options)
42176		this.transitioning = null
42177
42178		if (this.options.parent) this.$parent = $(this.options.parent)
42179		if (this.options.toggle) this.toggle()
42180	}
42181
42182	Collapse.DEFAULTS = {
42183		toggle: true
42184	}
42185
42186	Collapse.prototype.dimension = function () {
42187		var hasWidth = this.$element.hasClass('width')
42188		return hasWidth ? 'width' : 'height'
42189	}
42190
42191	Collapse.prototype.show = function () {
42192		if (this.transitioning || this.$element.hasClass('in')) return
42193
42194		var startEvent = $.Event('show.bs.collapse')
42195		this.$element.trigger(startEvent)
42196		if (startEvent.isDefaultPrevented()) return
42197
42198		var actives = this.$parent && this.$parent.find('> .panel > .in')
42199
42200		if (actives && actives.length) {
42201			var hasData = actives.data('bs.collapse')
42202			if (hasData && hasData.transitioning) return
42203			//START UNCODE EDIT
42204			var parentNoToggle = this.$parent.data('no-toggle')
42205			if (!parentNoToggle) {
42206				actives.collapse('hide')
42207			}
42208			//END UNCODE EDIT
42209			hasData || actives.data('bs.collapse', null)
42210		}
42211
42212		var dimension = this.dimension()
42213
42214		this.$element
42215			.removeClass('collapse')
42216			.addClass('collapsing')[dimension](0)
42217
42218		this.transitioning = 1
42219
42220		var complete = function (e) {
42221			if (e && e.target != this.$element[0]) return
42222			this.$element
42223				.removeClass('collapsing')
42224				.addClass('collapse in')[dimension]('auto')
42225			this.transitioning = 0
42226			this.$element.trigger('shown.bs.collapse')
42227		}
42228
42229		if (!$.support.transition) return complete.call(this)
42230
42231		var scrollSize = $.camelCase(['scroll', dimension].join('-'))
42232
42233		this.$element
42234			.one($.support.transition.end, $.proxy(complete, this))
42235			.emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
42236	}
42237
42238	Collapse.prototype.hide = function () {
42239		if (this.transitioning || !this.$element.hasClass('in')) return
42240
42241		var startEvent = $.Event('hide.bs.collapse')
42242		this.$element.trigger(startEvent)
42243		if (startEvent.isDefaultPrevented()) return
42244
42245		var dimension = this.dimension()
42246
42247		this.$element[dimension](this.$element[dimension]())[0].offsetHeight
42248
42249		this.$element
42250			.addClass('collapsing')
42251			.removeClass('collapse')
42252			.removeClass('in')
42253
42254		this.transitioning = 1
42255
42256		var complete = function (e) {
42257			if (e && e.target != this.$element[0]) return
42258			this.transitioning = 0
42259			this.$element
42260				.trigger('hidden.bs.collapse')
42261				.removeClass('collapsing')
42262				.addClass('collapse')
42263		}
42264
42265		if (!$.support.transition) return complete.call(this)
42266
42267		this.$element
42268			[dimension](0)
42269			.one($.support.transition.end, $.proxy(complete, this))
42270			.emulateTransitionEnd(350)
42271	}
42272
42273	Collapse.prototype.toggle = function () {
42274		this[this.$element.hasClass('in') ? 'hide' : 'show']()
42275	}
42276
42277
42278	// COLLAPSE PLUGIN DEFINITION
42279	// ==========================
42280
42281	var old = $.fn.collapse
42282
42283	$.fn.collapse = function (option) {
42284		return this.each(function () {
42285			var $this   = $(this)
42286			var data    = $this.data('bs.collapse')
42287			var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
42288
42289			if (!data && options.toggle && option == 'show') option = !option
42290			if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
42291			if (typeof option == 'string') data[option]()
42292		})
42293	}
42294
42295	$.fn.collapse.Constructor = Collapse
42296
42297
42298	// COLLAPSE NO CONFLICT
42299	// ====================
42300
42301	$.fn.collapse.noConflict = function () {
42302		$.fn.collapse = old
42303		return this
42304	}
42305
42306
42307	// COLLAPSE DATA-API
42308	// =================
42309
42310	$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
42311		var $this   = $(this), href
42312		var target  = $this.attr('data-target')
42313				|| e.preventDefault()
42314				|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
42315		//Edited by Uncode to replace ID in panel [START]
42316		var _target = href.replace(/^#/, "");
42317		if ( $('[data-id="' + _target + '"]').length ) {
42318			var $target = $('[data-id="' + _target + '"]')
42319		} else {
42320			var $target = $(target)
42321		}
42322		//Edited by Uncode to replace ID in panel [END]
42323		var data    = $target.data('bs.collapse')
42324		var option  = data ? 'toggle' : $this.data()
42325		var parent  = $this.attr('data-parent')
42326		var $parent = parent && $(parent)
42327
42328		if (!data || !data.transitioning) {
42329			if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
42330			$this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
42331		}
42332
42333		$target.collapse(option)
42334	})
42335
42336}(jQuery);
42337
42338/* ========================================================================
42339 * Bootstrap: tab.js v3.1.1
42340 * http://getbootstrap.com/javascript/#tabs
42341 * ========================================================================
42342 * Copyright 2011-2014 Twitter, Inc.
42343 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42344 * ======================================================================== */
42345
42346
42347+function ($) {
42348  'use strict';
42349
42350  // TAB CLASS DEFINITION
42351  // ====================
42352
42353  var Tab = function (element) {
42354    this.element = $(element)
42355  }
42356
42357  Tab.prototype.show = function () {
42358    var $this    = this.element
42359    var $ul      = $this.closest('ul:not(.dropdown-menu)')
42360    var selector = $this.data('target')
42361
42362    if (!selector) {
42363      selector = $this.attr('href')
42364      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
42365    }
42366
42367    if ($this.parent('li').hasClass('active')) return
42368
42369    var previous = $ul.find('.active:last a')[0]
42370    var e        = $.Event('show.bs.tab', {
42371      relatedTarget: previous
42372    })
42373
42374    $this.trigger(e)
42375
42376    if (e.isDefaultPrevented()) return
42377
42378    //Edited by Uncode to replace ID in panel [START]
42379    var _target = selector.replace(/^#/, "");
42380    if ( $('[data-id="' + _target + '"]').length )
42381      var $target = $('[data-id="' + _target + '"]')
42382    else
42383      var $target = $(selector)
42384    //Edited by Uncode to replace ID in panel [END]
42385
42386    this.activate($this.parent('li'), $ul)
42387    this.activate($target, $target.parent(), function () {
42388      $this.trigger({
42389        type: 'shown.bs.tab',
42390        relatedTarget: previous
42391      })
42392    })
42393  }
42394
42395  Tab.prototype.activate = function (element, container, callback) {
42396    var $active    = container.find('> .active').add(container.find('> .active > .active'))
42397    var transition = callback
42398      && $.support.transition
42399      && $active.hasClass('fade')
42400
42401    function next() {
42402      $active
42403        .removeClass('active')
42404        .find('> .dropdown-menu > .active')
42405        .removeClass('active')
42406
42407      $active
42408        .find('.tab-excerpt').slideUp();
42409
42410      element.addClass('active')
42411      $('.tab-excerpt', element).slideDown();
42412
42413      //if (transition) {
42414        element[0].offsetWidth // reflow for transition
42415        element.add($active).addClass('in')
42416      /*} else {
42417        element.removeClass('fade')
42418      }*/
42419
42420      if (element.parent('.dropdown-menu')) {
42421        element.closest('li.dropdown').addClass('active')
42422      }
42423
42424      if ( ! element.is('li') ) {
42425        element.closest('.tab-content').find('> .active').not(element).removeClass('active');
42426      }
42427
42428      callback && callback()
42429    }
42430
42431    transition ?
42432      $active
42433        .one($.support.transition.end, next)
42434        .emulateTransitionEnd(150) :
42435      next()
42436
42437    $active.removeClass('in')
42438  }
42439
42440
42441  // TAB PLUGIN DEFINITION
42442  // =====================
42443
42444  var old = $.fn.tab
42445
42446  $.fn.tab = function ( option ) {
42447    return this.each(function () {
42448      var $this = $(this)
42449      var data  = $this.data('bs.tab')
42450
42451      if (!data) $this.data('bs.tab', (data = new Tab(this)))
42452      if (typeof option == 'string') data[option]()
42453    })
42454  }
42455
42456  $.fn.tab.Constructor = Tab
42457
42458
42459  // TAB NO CONFLICT
42460  // ===============
42461
42462  $.fn.tab.noConflict = function () {
42463    $.fn.tab = old
42464    return this
42465  }
42466
42467
42468  // TAB DATA-API
42469  // ============
42470
42471  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
42472    e.preventDefault()
42473    $(this).tab('show')
42474  })
42475
42476}(jQuery);
42477
42478/* ========================================================================
42479 * Bootstrap: tooltip.js v3.1.1
42480 * http://getbootstrap.com/javascript/#tooltip
42481 * Inspired by the original jQuery.tipsy by Jason Frame
42482 * ========================================================================
42483 * Copyright 2011-2014 Twitter, Inc.
42484 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42485 * ======================================================================== */
42486
42487
42488+function ($) {
42489  'use strict';
42490
42491  // TOOLTIP PUBLIC CLASS DEFINITION
42492  // ===============================
42493
42494  var Tooltip = function (element, options) {
42495    this.type       =
42496    this.options    =
42497    this.enabled    =
42498    this.timeout    =
42499    this.hoverState =
42500    this.$element   = null
42501
42502    this.init('tooltip', element, options)
42503  }
42504
42505  Tooltip.DEFAULTS = {
42506    animation: true,
42507    placement: 'top',
42508    selector: false,
42509    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
42510    trigger: 'hover focus',
42511    title: '',
42512    delay: 0,
42513    html: false,
42514    container: false,
42515    viewport: {
42516      selector: 'body',
42517      padding: 0
42518    }
42519  }
42520
42521  Tooltip.prototype.init = function (type, element, options) {
42522    this.enabled   = true
42523    this.type      = type
42524    this.$element  = $(element)
42525    this.options   = this.getOptions(options)
42526    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
42527
42528    var triggers = this.options.trigger.split(' ')
42529
42530    for (var i = triggers.length; i--;) {
42531      var trigger = triggers[i]
42532
42533      if (trigger == 'click') {
42534        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
42535      } else if (trigger != 'manual') {
42536        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
42537        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
42538
42539        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
42540        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
42541      }
42542    }
42543
42544    this.options.selector ?
42545      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
42546      this.fixTitle()
42547  }
42548
42549  Tooltip.prototype.getDefaults = function () {
42550    return Tooltip.DEFAULTS
42551  }
42552
42553  Tooltip.prototype.getOptions = function (options) {
42554    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
42555
42556    if (options.delay && typeof options.delay == 'number') {
42557      options.delay = {
42558        show: options.delay,
42559        hide: options.delay
42560      }
42561    }
42562
42563    return options
42564  }
42565
42566  Tooltip.prototype.getDelegateOptions = function () {
42567    var options  = {}
42568    var defaults = this.getDefaults()
42569
42570    this._options && $.each(this._options, function (key, value) {
42571      if (defaults[key] != value) options[key] = value
42572    })
42573
42574    return options
42575  }
42576
42577  Tooltip.prototype.enter = function (obj) {
42578    var self = obj instanceof this.constructor ?
42579      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
42580
42581    clearTimeout(self.timeout)
42582
42583    self.hoverState = 'in'
42584
42585    if (!self.options.delay || !self.options.delay.show) return self.show()
42586
42587    self.timeout = setTimeout(function () {
42588      if (self.hoverState == 'in') self.show()
42589    }, self.options.delay.show)
42590  }
42591
42592  Tooltip.prototype.leave = function (obj) {
42593    var self = obj instanceof this.constructor ?
42594      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
42595
42596    clearTimeout(self.timeout)
42597
42598    self.hoverState = 'out'
42599
42600    if (!self.options.delay || !self.options.delay.hide) return self.hide()
42601
42602    self.timeout = setTimeout(function () {
42603      if (self.hoverState == 'out') self.hide()
42604    }, self.options.delay.hide)
42605  }
42606
42607  Tooltip.prototype.show = function () {
42608    var e = $.Event('show.bs.' + this.type)
42609
42610    if (this.hasContent() && this.enabled) {
42611      this.$element.trigger(e)
42612
42613      if (e.isDefaultPrevented()) return
42614      var that = this;
42615
42616      var $tip = this.tip()
42617
42618      this.setContent()
42619
42620      if (this.options.animation) $tip.addClass('fade')
42621
42622      var placement = typeof this.options.placement == 'function' ?
42623        this.options.placement.call(this, $tip[0], this.$element[0]) :
42624        this.options.placement
42625
42626      var autoToken = /\s?auto?\s?/i
42627      var autoPlace = autoToken.test(placement)
42628      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
42629
42630      $tip
42631        .detach()
42632        .css({ top: 0, left: 0, display: 'block' })
42633        .addClass(placement)
42634
42635      this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)
42636
42637      var pos          = this.getPosition()
42638      var actualWidth  = $tip[0].offsetWidth
42639      var actualHeight = $tip[0].offsetHeight
42640
42641      if (autoPlace) {
42642        var orgPlacement = placement
42643        var $parent      = this.$element.parent()
42644        var parentDim    = this.getPosition($parent)
42645
42646        placement = placement == 'bottom' && pos.top   + pos.height       + actualHeight - parentDim.scroll > parentDim.height ? 'top'    :
42647                    placement == 'top'    && pos.top   - parentDim.scroll - actualHeight < 0                                   ? 'bottom' :
42648                    placement == 'right'  && pos.right + actualWidth      > parentDim.width                                    ? 'left'   :
42649                    placement == 'left'   && pos.left  - actualWidth      < parentDim.left                                     ? 'right'  :
42650                    placement
42651
42652        $tip
42653          .removeClass(orgPlacement)
42654          .addClass(placement)
42655      }
42656
42657      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
42658
42659      this.applyPlacement(calculatedOffset, placement)
42660      this.hoverState = null
42661
42662      var complete = function() {
42663        that.$element.trigger('shown.bs.' + that.type)
42664      }
42665
42666      $.support.transition && this.$tip.hasClass('fade') ?
42667        $tip
42668          .one($.support.transition.end, complete)
42669          .emulateTransitionEnd(150) :
42670        complete()
42671    }
42672  }
42673
42674  Tooltip.prototype.applyPlacement = function (offset, placement) {
42675    var $tip   = this.tip()
42676    var width  = $tip[0].offsetWidth
42677    var height = $tip[0].offsetHeight
42678
42679    // manually read margins because getBoundingClientRect includes difference
42680    var marginTop = parseInt($tip.css('margin-top'), 10)
42681    var marginLeft = parseInt($tip.css('margin-left'), 10)
42682
42683    // we must check for NaN for ie 8/9
42684    if (isNaN(marginTop))  marginTop  = 0
42685    if (isNaN(marginLeft)) marginLeft = 0
42686
42687    offset.top  = offset.top  + marginTop
42688    offset.left = offset.left + marginLeft
42689
42690    // $.fn.offset doesn't round pixel values
42691    // so we use setOffset directly with our own function B-0
42692    $.offset.setOffset($tip[0], $.ext
42692end({
42693      using: function (props) {
42694        $tip.css({
42695          top: Math.round(props.top),
42696          left: Math.round(props.left)
42697        })
42698      }
42699    }, offset), 0)
42700
42701    $tip.addClass('in')
42702
42703    // check to see if placing tip in new offset caused the tip to resize itself
42704    var actualWidth  = $tip[0].offsetWidth
42705    var actualHeight = $tip[0].offsetHeight
42706
42707    if (placement == 'top' && actualHeight != height) {
42708      offset.top = offset.top + height - actualHeight
42709    }
42710
42711    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
42712
42713    if (delta.left) offset.left += delta.left
42714    else offset.top += delta.top
42715
42716    var arrowDelta          = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
42717    var arrowPosition       = delta.left ? 'left'        : 'top'
42718    var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
42719
42720    $tip.offset(offset)
42721    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
42722  }
42723
42724  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
42725    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
42726  }
42727
42728  Tooltip.prototype.setContent = function () {
42729    var $tip  = this.tip()
42730    var title = this.getTitle()
42731
42732    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
42733    $tip.removeClass('fade in top bottom left right')
42734  }
42735
42736  Tooltip.prototype.hide = function () {
42737    var that = this
42738    var $tip = this.tip()
42739    var e    = $.Event('hide.bs.' + this.type)
42740
42741    function complete() {
42742      if (that.hoverState != 'in') $tip.detach()
42743      that.$element.trigger('hidden.bs.' + that.type)
42744    }
42745
42746    this.$element.trigger(e)
42747
42748    if (e.isDefaultPrevented()) return
42749
42750    $tip.removeClass('in')
42751
42752    $.support.transition && this.$tip.hasClass('fade') ?
42753      $tip
42754        .one($.support.transition.end, complete)
42755        .emulateTransitionEnd(150) :
42756      complete()
42757
42758    this.hoverState = null
42759
42760    return this
42761  }
42762
42763  Tooltip.prototype.fixTitle = function () {
42764    var $e = this.$element
42765    if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
42766      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
42767    }
42768  }
42769
42770  Tooltip.prototype.hasContent = function () {
42771    return this.getTitle()
42772  }
42773
42774  Tooltip.prototype.getPosition = function ($element) {
42775    $element   = $element || this.$element
42776    var el     = $element[0]
42777    var isBody = el.tagName == 'BODY'
42778    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
42779      scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
42780      width:  isBody ? $(window).width()  : $element.outerWidth(),
42781      height: isBody ? $(window).height() : $element.outerHeight()
42782    }, isBody ? {top: 0, left: 0} : $element.offset())
42783  }
42784
42785  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
42786    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
42787           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
42788           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
42789        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
42790
42791  }
42792
42793  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
42794    var delta = { top: 0, left: 0 }
42795    if (!this.$viewport) return delta
42796
42797    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
42798    var viewportDimensions = this.getPosition(this.$viewport)
42799
42800    if (/right|left/.test(placement)) {
42801      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
42802      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
42803      if (topEdgeOffset < viewportDimensions.top) { // top overflow
42804        delta.top = viewportDimensions.top - topEdgeOffset
42805      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
42806        delta.top = viewportDimensions.top + viewportDimensions.height - bottom
42806EdgeOffset
42807      }
42808    } else {
42809      var leftEdgeOffset  = pos.left - viewportPadding
42810      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
42811      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
42812        delta.left = viewportDimensions.left - leftEdgeOffset
42813      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
42814        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
42815      }
42816    }
42817
42818    return delta
42819  }
42820
42821  Tooltip.prototype.getTitle = function () {
42822    var title
42823    var $e = this.$element
42824    var o  = this.options
42825
42826    title = $e.attr('data-original-title')
42827      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
42828
42829    return title
42830  }
42831
42832  Tooltip.prototype.tip = function () {
42833    return this.$tip = this.$tip || $(this.options.template)
42834  }
42835
42836  Tooltip.prototype.arrow = function () {
42837    return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
42838  }
42839
42840  Tooltip.prototype.validate = function () {
42841    if (!this.$element[0].parentNode) {
42842      this.hide()
42843      this.$element = null
42844      this.options  = null
42845    }
42846  }
42847
42848  Tooltip.prototype.enable = function () {
42849    this.enabled = true
42850  }
42851
42852  Tooltip.prototype.disable = function () {
42853    this.enabled = false
42854  }
42855
42856  Tooltip.prototype.toggleEnabled = function () {
42857    this.enabled = !this.enabled
42858  }
42859
42860  Tooltip.prototype.toggle = function (e) {
42861    var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
42862    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
42863  }
42864
42865  Tooltip.prototype.destroy = function () {
42866    clearTimeout(this.timeout)
42867    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
42868  }
42869
42870
42871  // TOOLTIP PLUGIN DEFINITION
42872  // =========================
42873
42874  var old = $.fn.tooltip
42875
42876  $.fn.tooltip = function (option) {
42877    return this.each(function () {
42878      var $this   = $(this)
42879      var data    = $this.data('bs.tooltip')
42880      var options = typeof option == 'object' && option
42881
42882      if (!data && option == 'destroy') return
42883      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
42884      if (typeof option == 'string') data[option]()
42885    })
42886  }
42887
42888  $.fn.tooltip.Constructor = Tooltip
42889
42890
42891  // TOOLTIP NO CONFLICT
42892  // ===================
42893
42894  $.fn.tooltip.noConflict = function () {
42895    $.fn.tooltip = old
42896    return this
42897  }
42898
42899}(jQuery);
42900
42901/* ========================================================================
42902 * Bootstrap: transition.js v3.1.1
42903 * http://getbootstrap.com/javascript/#transitions
42904 * ========================================================================
42905 * Copyright 2011-2014 Twitter, Inc.
42906 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42907 * ======================================================================== */
42908
42909
42910+function ($) {
42911  'use strict';
42912
42913  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
42914  // ============================================================
42915
42916  function transitionEnd() {
42917    var el = document.createElement('bootstrap')
42918
42919    var transEndEventNames = {
42920      WebkitTransition : 'webkitTransitionEnd',
42921      MozTransition    : 'transitionend',
42922      OTransition      : 'oTransitionEnd otransitionend',
42923      transition       : 'transitionend'
42924    }
42925
42926    for (var name in transEndEventNames) {
42927      if (el.style[name] !== undefined) {
42928        return { end: transEndEventNames[name] }
42929      }
42930    }
42931
42932    return false // explicit for ie8 (  ._.)
42933  }
42934
42935  // http://blog.alexmaccaw.com/css-transitions
42936  $.fn.emulateTransitionEnd = function (duration) {
42937    var called = false, $el = this
42938    $(this).one($.support.transition.end, function () { called = true })
42939    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
42940    setTimeout(callback, duration)
42941    return this
42942  }
42943
42944  $(function () {
42945    $.support.transition = transitionEnd()
42946  })
42947
42948}(jQuery);
42949
42950
42951// ------------------------------------------
42952// Rellax.js
42953// Buttery smooth parallax library
42954// Copyright (c) 2016 Moe Amaya (@moeamaya)
42955// MIT license
42956//
42957// Thanks to Paraxify.js and Jaime Cabllero
42958// for parallax concepts
42959// ------------------------------------------
42960
42961(function (root, factory) {
42962	if (typeof define === 'function' && define.amd) {
42963		// AMD. Register as an anonymous module.
42964		define([], factory);
42965	} else if (typeof module === 'object' && module.exports) {
42966		// Node. Does not work with strict CommonJS, but
42967		// only CommonJS-like environments that support module.exports,
42968		// like Node.
42969		module.exports = factory();
42970	} else {
42971		// Browser globals (root is window)
42972		root.Rellax = factory();
42973	}
42974}(typeof window !== "undefined" ? window : global, function () {
42975	var Rellax = function(el, options){
42976		"use strict";
42977
42978		var self = Object.create(Rellax.prototype);
42979
42980		var posY = 0;
42981		var screenY = 0;
42982		var posX = 0;
42983		var screenX = 0;
42984		var blocks = [];
42985		var pause = true;
42986
42987		// check what requestAnimationFrame to use, and if
42988		// it's not supported, use the onscroll event
42989		var loop = window.requestAnimationFrame ||
42990			window.webkitRequestAnimationFrame ||
42991			window.mozRequestAnimationFrame ||
42992			window.msRequestAnimationFrame ||
42993			window.oRequestAnimationFrame ||
42994			function(callback){ return setTimeout(callback, 1000 / 60); };
42995
42996		// store the id for later use
42997		var loopId = null;
42998
42999		// Test via a getter in the options object to see if the passive property is accessed
43000		var supportsPassive = false;
vendor: 10,724 bytes, lines 43001-43302
43001		try {
43002			var opts = Object.defineProperty({}, 'passive', {
43003				get: function() {
43004					supportsPassive = true;
43005				}
43006			});
43007			window.addEventListener("testPassive", null, opts);
43008			window.removeEventListener("testPassive", null, opts);
43009		} catch (e) {}
43010
43011		// check what cancelAnimation method to use
43012		var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout;
43013
43014		// check which transform property to use
43015		var transformProp = window.transformProp || (function(){
43016				var testEl = document.createElement('div');
43017				if (testEl.style.transform === null) {
43018					var vendors = ['Webkit', 'Moz', 'ms'];
43019					for (var vendor in vendors) {
43020						if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) {
43021							return vendors[vendor] + 'Transform';
43022						}
43023					}
43024				}
43025				return 'transform';
43026			})();
43027
43028		// Default Settings
43029		self.options = {
43030			speed: -2,
43031			verticalSpeed: null,
43032			horizontalSpeed: null,
43033			breakpoints: [576, 768, 1201],
43034			center: false,
43035			wrapper: null,
43036			relativeToWrapper: false,
43037			round: true,
43038			vertical: true,
43039			horizontal: false,
43040			verticalScrollAxis: "y",
43041			horizontalScrollAxis: "x",
43042			callback: function() {},
43043		};
43044
43045		// User defined options (might have more in the future)
43046		if (options){
43047			Object.keys(options).forEach(function(key){
43048				self.options[key] = options[key];
43049			});
43050		}
43051
43052		function validateCustomBreakpoints () {
43053			if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) {
43054				var isAscending = true;
43055				var isNumerical = true;
43056				var lastVal;
43057				self.options.breakpoints.forEach(function (i) {
43058					if (typeof i !== 'number') isNumerical = false;
43059					if (lastVal !== null) {
43060						if (i < lastVal) isAscending = false;
43061					}
43062					lastVal = i;
43063				});
43064				if (isAscending && isNumerical) return;
43065			}
43066			// revert defaults if set incorrectly
43067			self.options.breakpoints = [576, 768, 1201];
43068			console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted");
43069		}
43070
43071		if (options && options.breakpoints) {
43072			validateCustomBreakpoints();
43073		}
43074
43075		// By default, rellax class
43076		if (!el) {
43077			el = '.rellax';
43078		}
43079
43080		// check if el is a className or a node
43081		var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el];
43082
43083		// Now query selector
43084		if (elements.length > 0) {
43085			self.elems = elements;
43086		}
43087
43088		// The elements don't exist
43089		else {
43090			console.warn("Rellax: The elements you're trying to select don't exist.");
43091			return;
43092		}
43093
43094		// Has a wrapper and it exists
43095		if (self.options.wrapper) {
43096			if (!self.options.wrapper.nodeType) {
43097				var wrapper = document.querySelector(self.options.wrapper);
43098
43099				if (wrapper) {
43100					self.options.wrapper = wrapper;
43101				} else {
43102					console.warn("Rellax: The wrapper you're trying to use doesn't exist.");
43103					return;
43104				}
43105			}
43106		}
43107
43108		// set a placeholder for the current breakpoint
43109		var currentBreakpoint;
43110
43111		// helper to determine current breakpoint
43112		var getCurrentBreakpoint = function (w) {
43113			var bp = self.options.breakpoints;
43114			if (w < bp[0]) return 'xs';
43115			if (w >= bp[0] && w < bp[1]) return 'sm';
43116			if (w >= bp[1] && w < bp[2]) return 'md';
43117			return 'lg';
43118		};
43119
43120		// Get and cache initial position of all elements
43121		var cacheBlocks = function() {
43122			for (var i = 0; i < self.elems.length; i++){
43123				var block = createBlock(self.elems[i]);
43124				blocks.push(block);
43125			}
43126		};
43127
43128
43129		// Let's kick this script off
43130		// Build array for cached element values
43131		var init = function() {
43132			for (var i = 0; i < blocks.length; i++){
43133				self.elems[i].style.cssText = blocks[i].style;
43134			}
43135
43136			blocks = [];
43137
43138			screenY = window.innerHeight;
43139			screenX = window.innerWidth;
43140			currentBreakpoint = getCurrentBreakpoint(screenX);
43141
43142			setPosition();
43143
43144			cacheBlocks();
43145
43146			animate();
43147
43148			// If paused, unpause and set listener for window resizing events
43149			if (pause) {
43150				window.addEventListener('resize', init);
43151				pause = false;
43152				// Start the loop
43153				update();
43154			}
43155		};
43156
43157		// We want to cache the parallax blocks'
43158		// values: base, top, height, speed
43159		// el: is dom object, return: el cache values
43160		var createBlock = function(el) {
43161			var dataPercentage = el.getAttribute( 'data-rellax-percentage' );
43162			var dataSpeed = el.getAttribute( 'data-rellax-speed' );
43163			var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' );
43164			var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' );
43165			var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' );
43166			var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' );
43167			var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed');
43168			var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed');
43169			var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis');
43170			var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis');
43171			var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0;
43172			var dataMin = el.getAttribute( 'data-rellax-min' );
43173			var dataMax = el.getAttribute( 'data-rellax-max' );
43174			var dataMinX = el.getAttribute('data-rellax-min-x');
43175			var dataMaxX = el.getAttribute('data-rellax-max-x');
43176			var dataMinY = el.getAttribute('data-rellax-min-y');
43177			var dataMaxY = el.getAttribute('data-rellax-max-y');
43178			var mapBreakpoints;
43179			var breakpoints = true;
43180
43181			if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) {
43182				breakpoints = false;
43183			} else {
43184				mapBreakpoints = {
43185					'xs': dataXsSpeed,
43186					'sm': dataMobileSpeed,
43187					'md': dataTabletSpeed,
43188					'lg': dataDesktopSpeed
43189				};
43190			}
43191
43192			// initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser)
43193			// ensures elements are positioned based on HTML layout.
43194			//
43195			// If the element has the percentage attribute, the posY and posX needs to be
43196			// the current scroll position's value, so that the elements are still positioned based on HTML layout
43197			var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
43198			// If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll.
43199			if (self.options.relativeToWrapper) {
43200				var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
43201				wrapperPosY = scrollPosY - self.options.wrapper.offsetTop;
43202			}
43203			var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0;
43204			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;
43205
43206			var blockTop = posY + el.getBoundingClientRect().top;
43207			var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight;
43208
43209			var blockLeft = posX + el.getBoundingClientRect().left;
43210			var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth;
43211
43212			// apparently parallax equation everyone uses
43213			var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY);
43214			var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX);
43215			if(self.options.center){ percentageX = 0.5; percentageY = 0.5; }
43216
43217			// Optional individual block speed as data attr, otherwise global speed
43218			var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed);
43219			var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed;
43220			var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed;
43221
43222			// Optional individual block movement axis direction as data attr, otherwise global movement direction
43223			var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis;
43224			var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis;
43225
43226			var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed);
43227
43228			// ~~Store non-translate3d transforms~~
43229			// Store inline styles and extract transforms
43230			var style = el.style.cssText;
43231			var transform = '';
43232
43233			// Check if there's an inline styled transform
43234			var searchResult = /transform\s*:/i.exec(style);
43235			if (searchResult) {
43236				// Get the index of the transform
43237				var index = searchResult.index;
43238
43239				// Trim the style to the transform point and get the following semi-colon index
43240				var trimmedStyle = style.slice(index);
43241				var delimiter = trimmedStyle.indexOf(';');
43242
43243				// Remove "transform" string and save the attribute
43244				if (delimiter) {
43245					transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,'');
43246				} else {
43247					transform = " " + trimmedStyle.slice(11).replace(/\s/g,'');
43248				}
43249			}
43250
43251			return {
43252				baseX: bases.x,
43253				baseY: bases.y,
43254				top: blockTop,
43255				left: blockLeft,
43256				height: blockHeight,
43257				width: blockWidth,
43258				speed: speed,
43259				verticalSpeed: verticalSpeed,
43260				horizontalSpeed: horizontalSpeed,
43261				verticalScrollAxis: verticalScrollAxis,
43262				horizontalScrollAxis: horizontalScrollAxis,
43263				style: style,
43264				transform: transform,
43265				zindex: dataZindex,
43266				min: dataMin,
43267				max: dataMax,
43268				minX: dataMinX,
43269				maxX: dataMaxX,
43270				minY: dataMinY,
43271				maxY: dataMaxY
43272			};
43273		};
43274
43275		// set scroll position (posY, posX)
43276		// side effect method is not ideal, but okay for now
43277		// returns true if the scroll changed, false if nothing happened
43278		var setPosition = function() {
43279			var oldY = posY;
43280			var oldX = posX;
43281
43282			posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset;
43283			posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset;
43284			// If option relativeToWrapper is true, use relative wrapper value instead.
43285			if (self.options.relativeToWrapper) {
43286				var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset;
43287				posY = scrollPosY - self.options.wrapper.offsetTop;
43288			}
43289
43290
43291			if (oldY != posY && self.options.vertical) {
43292				// scroll changed, return true
43293				return true;
43294			}
43295
43296			if (oldX != posX && self.options.horizontal) {
43297				// scroll changed, return true
43298				return true;
43299			}
43300
43301			// scroll did not change
43302			return false;
43303		};
43304
43305		// Ahh a pure function, gets new transform value
43306		// based on scrollPosition and speed
43307		// Allow for decimal pixel values
43308		var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) {
43309			var result = {};
43310			var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX)));
43311			var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY)));
43312
43313			result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100;
43314			result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100;
43315
43316			return result;
43317		};
43318
43319		// Remove event listeners and loop again
43320		var deferredUpdate = function() {
43321			window.removeEventListener('resize', deferredUpdate);
43322			window.removeEventListener('orientationchange', deferredUpdate);
43323			(self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate);
43324			(self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate);
43325
43326			// loop again
43327			loopId = loop(update);
43328		};
43329
43330		// Loop
43331		var update = function() {
43332			if (setPosition() && pause === false) {
43333				animate();
43334
43335				// loop again
43336				loopId = loop(update);
43337			} else {
43338				loopId = null;
43339
43340				// Don't animate until we get a position updating event
43341				window.addEventListener('resize', deferredUpdate);
43342				window.addEventListener('orientationchange', deferredUpdate);
43343				(self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false);
43344				(self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false);
43345			}
43346		};
43347
43348		// Transform3d on parallax element
43349		var animate = function() {
43350			var positions;
43351			for (var i = 0; i < self.elems.length; i++){
43352				// Determine relevant movement directions
43353				var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase();
43354				var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase();
43355				var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0;
43356				var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0;
43357				var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0;
43358				var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0;
43359
43360				var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY));
43361				var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX));
43362
43363				// Subtracting initialize value, so element stays in same spot as HTML
43364				positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed);
43365				var positionY = positions.y - blocks[i].baseY;
43366				var positionX = positions.x - blocks[i].baseX;
43367
43368				// The next two "if" blocks go like this:
43369				// Check if a limit is defined (first "min", then "max");
43370				// Check if we need to change the Y or the X
43371				// (Currently working only if just one of the axes is enabled)
43372				// Then, check if the new position is inside the allowed limit
43373				// If so, use new position. If not, set position to limit.
43374
43375				// Check if a min limit is defined
43376				if (blocks[i].min !== null) {
43377					if (self.options.vertical && !self.options.horizontal) {
43378						positionY = positionY <= blocks[i].min ? blocks[i].min : positionY;
43379					}
43380					if (self.options.horizontal && !self.options.vertical) {
43381						positionX = positionX <= blocks[i].min ? blocks[i].min : positionX;
43382					}
43383				}
43384
43385				// Check if directional min limits are defined
43386				if (blocks[i].minY != null) {
43387						positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY;
43388				}
43389				if (blocks[i].minX != null) {
43390						positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX;
43391				}
43392
43393				// Check if a max limit is defined
43394				if (blocks[i].max !== null) {
43395					if (self.options.vertical && !self.options.horizontal) {
43396						positionY = positionY >= blocks[i].max ? blocks[i].max : positionY;
43397					}
43398					if (self.options.horizontal && !self.options.vertical) {
43399						positionX = positionX >= blocks[i].max ? blocks[i].max : positionX;
43400					}
43401				}
43402
43403				// Check if directional max limits are defined
43404				if (blocks[i].maxY != null) {
43405						positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY;
43406				}
43407				if (blocks[i].maxX != null) {
43408						positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX;
43409				}
43410
43411				var zindex = blocks[i].zindex;
43412
43413				// Move that element
43414				// (Set the new translation and append initial inline transforms.)
43415				var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform;
43416				self.elems[i].style[transformProp] = translate;
43417			}
43418			self.options.callback(positions);
43419		};
43420
43421		self.destroy = function() {
43422			for (var i = 0; i < self.elems.length; i++){
43423				self.elems[i].style.cssText = blocks[i].style;
43424			}
43425
43426			// Remove resize event listener if not pause, and pause
43427			if (!pause) {
43428				window.removeEventListener('resize', init);
43429				pause = true;
43430			}
43431
43432			// Clear the animation loop to prevent possible memory leak
43433			clearLoop(loopId);
43434			loopId = null;
43435		};
43436
43437		// Init
43438		init();
43439
43440		// Allow to recalculate the initial values whenever we want
43441		self.refresh = init;
43442
43443		return self;
43444	};
43445	return Rellax;
43446}));
43447
43448/*
43449 * OKVideo by OKFocus v2.3.2
43450 * http://okfoc.us
43451 *
43452 * Copyright 2014, OKFocus
43453 * Licensed under the MIT license.
43454 *
43455 */
43456var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array();
43457// youtube player ready
43458function onYouTubeIframeAPIReady() {
43459	YTplayers = new Array();
43460	jQuery('.uncode-video-container.video').each(function() {
43461		var playerY;
43462		if (jQuery(this).attr('data-provider') == 'youtube') {
43463			var id = jQuery(this).attr('data-id'),
43464				start = jQuery(this).attr('data-start'),
43465				end = jQuery(this).attr('data-end');
43466			start = typeof start && start !== null ? start : 0;
43467			end = typeof end && end !== null ? end : 0;
43468			options = jQuery(window).data('okoptions-' + id);
43469			if ( typeof options === 'undefined' ) {
43470				return true;
43471			}
43472			options.time = jQuery(this).attr('data-t');
43473			playerY = new YT.Player('okplayer-' + id, {
43474				videoId: options.video ? options.video.id : null,
43475				playerVars: {
43476					'autohide': 1,
43477					'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay,
43478					'disablekb': 1,
43479					'cc_load_policy': options.captions,
43480					'controls': 0,
43481					'enablejsapi': 1,
43482					'fs': 0,
43483					'modestbranding': 1,
43484					'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname),
43485					'iv_load_policy': options.annotations,
43486					'loop': options.loop,
43487					'showinfo': 0,
43488					'rel': 0,
43489					'wmode': 'opaque',
43490					'hd': options.hd,
43491					'mute': 1,
43492					'start': start,
43493					'end': end
43494				},
43495				events: {
43496					'onReady': OKEvents.yt.ready,
43497					'onStateChange': OKEvents.yt.onStateChange,
43498					'onError': OKEvents.yt.error
43499				}
43500			});
43501			YTplayers[id] = playerY;
43502			playerY.videoId = id;
43503		}
43504
43505	});
43506}
43507// vimeo player ready
43508function vimeoPlayerReady(id) {
43509	options = jQuery(window).data('okoptions-' + id);
43510	if ( typeof options === 'undefined' ) {
43511		return true;
43512	}
43513	var jIframe = options.jobject,
43514		iframe = jIframe[0];
43515
43516	jIframe.attr('src', jIframe.data('src'));
43517	var playerV = new Vimeo.Player(iframe);
43518	// hide player until Vimeo hides controls...
43519	playerV.on('loaded', function(e) {
43520		OKEvents.v.onReady(iframe);
43521		var carouselContainer = jQuery(iframe).closest('.owl-carousel');
43522		if (carouselContainer.length) {
43523			UNCODE.owlPlayVideo(carouselContainer);
43524		}
43525		// "Do not try to add listeners or call functions before receiving this event."
43526		if (OKEvents.utils.isMobile()) {
43527			// mobile devices cannot listen for play event
43528			OKEvents.v.onPlay(playerV);
43529		} else {
43530			playerV.on('play', function(){
43531				OKEvents.v.onPlay(playerV);
43532				jQuery(window).trigger('okevents.v.play', [playerV]);
43533			});
43534			playerV.on('pause', function(){
43535				OKEvents.v.onPause;
43536				jQuery(window).trigger('okevents.v.pause', [playerV]);
43537			});
43538			playerV.on('ended', function(){
43539				OKEvents.v.onFinish
43540				jQuery(window).trigger('okevents.v.ended', [playerV]);
43541			});
43542		}
43543		if (options.time != null) {
43544			var optsTimeStr = (options.time).replace('t=', ''),
43545				timeV = '';
43546
43547			if ( /[a-zA-Z]/g.test(optsTimeStr) ) {
43548				var timeArr = optsTimeStr.split(/([^\d.-])/);
43549				for ( var i = 0; i < timeArr.length; i++ ) {
43550					if ( timeArr[i] === 'h' ) {
43551						timeV += parseFloat(timeArr[i-1]) * 3600;
43552					} else if ( timeArr[i] === 'm' ) {
43553						timeV += parseFloat(timeArr[i-1]) * 60;
43554					} else if ( timeArr[i] === 's' ) {
43555						timeV += parseFloat(timeArr[i-1]);
43556					}
43557				}
43558			} else {
43559				timeV = optsTimeStr;
43560			}
43561
43562			playerV.setCurrentTime(timeV);
43563		}
43564
43565		playerV.setVolume(0);
43566		playerV.play();
43567		jQuery(iframe).css({
43568			visibility: 'visible',
43569			opacity: 1
43570		});
43571		jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43572		jQuery(iframe).closest('#page-header').addClass('video-started');
43573		jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43574
43575		jQuery(window).trigger('okevents.v.loaded', [playerV]);
43576	});
43577}
43578OKEvents = {
43579	yt: {
43580		ready: function(event) {
43581			var id = event.target.videoId,
43582				$video = jQuery('#okplayer-' + id),
43583				options = jQuery(window).data('okoptions-' + id);
43584			if ( typeof options === 'undefined' ) {
43585				return true;
43586			}
43587			youtubePlayers[id] = event.target;
43588			event.target.setVolume(options.volume);
43589			if (options.autoplay === 1) {
43590				if (options.playlist.list) {
43591					player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality);
43592				} else {
43593					var inCarousel = $video.closest('.owl-item');
43594					if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) {
43595						if (options.time != null) {
43596							event.target.seekTo(parseInt(options.time));
43597						}
43598						event.target.playVideo();
43599					} else {
43600						event.target.pauseVideo();
43601					}
43602				}
43603			}
43604			OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target);
43605
43606			$video.closest('[data-provider]').on('uncode-resume', function(){
43607				if (options.time != null) {
43608					event.target.seekTo(parseInt(options.time)).playVideo();
43609				} else {
43610					event.target.seekTo(0).playVideo();
43611				}
43612			});
43613
43614			$video.closest('[data-provider]').on('uncode-pause', function(){
43615				if (options.time != null) {
43616					event.target.seekTo(parseInt(options.time)).pauseVideo();
43617				} else {
43618					event.target.seekTo(0).pauseVideo();
43619				}
43620			});
43621			jQuery(window).trigger('okevents.y.loaded', [event]);
43622		},
43623		onStateChange: function(event) {
43624			var id = event.target.videoId,
43625				$video = jQuery('#okplayer-' + id),
43626				options = jQuery(window).data('okoptions-' + id);
43627			if ( typeof options === 'undefined' || typeof event.target.setVolume === 'undefined' ) {
43628				return true;
43629			}
43630			youtubePlayers[id] = event.target;
43631			event.target.setVolume(options.volume);
43632			var $fluid = $video.closest('.fluid-object'),
43633				$tmb = $video.closest('.tmb'),
43634				setTime;
43635			switch (event.data) {
43636				case -1:
43637					OKEvents.utils.isFunction(options.unstarted) && options.unstarted();
43638					break;
43639				case 0:
43640					OKEvents.utils.isFunction(options.onFinished) && options.onFinished();
43641					options.loop && event.target.playVideo();
43642					break;
43643				case 1:
43644					OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
43645					setTimeout(function() {
43646						UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)');
43647						jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43648						jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started');
43649						jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43650					}, 300);
43651				break;
43652				case 2:
43653					OKEvents.utils.isFunction(options.onPause) && options.onPause();
43654					break;
43655				case 3:
43656					OKEvents.utils.isFunction(options.buffering) && options.buffering();
43657					break;
43658				case 5:
43659					OKEvents.utils.isFunction(options.cued) && options.cued();
43660					break;
43661				default:
43662					throw "OKVideo: received invalid data from YT player.";
43663			}
43664
43665			jQuery(window).trigger('okevents.y.change', [event]);
43666		},
43667		error: function(event) {
43668			throw event;
43669		}
43670	},
43671	v: {
43672		onReady: function(target) {
43673			if ( typeof options === 'undefined' ) {
43674				return true;
43675			}
43676			OKEvents.utils.isFunction(options.onReady) && options.onReady(target);
43677		},
43678		onPlay: function(player) {
43679			if ( typeof options === 'undefined' ) {
43680				return true;
43681			}
43682			if (!OKEvents.utils.isMobile()) player.setVolume(options.volume);
43683			OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
43684			jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43685			jQuery(player.element).closest('#page-header').addClass('video-started');
43686			jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43687		},
43688		onPause: function() {
43689			if ( typeof options === 'undefined' ) {
43690				return true;
43691			}
43692			OKEvents.utils.isFunction(options.onPause) && options.onPause();
43693		},
43694		onFinish: function() {
43695			if ( typeof options === 'undefined' ) {
43696				return true;
43697			}
43698			OKEvents.utils.isFunction(options.onFinish) && options.onFinish();
43699		}
43700	},
43701	utils: {
43702		isFunction: function(func) {
43703			if (typeof func === 'function') {
43704				return true;
43705			} else {
43706				return false;
43707			}
43708		},
43709		isMobile: function() {
43710			if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
43711				return true;
43712			} else {
43713				return false;
43714			}
43715		}
43716	}
43717};
43718/**
43719 * vivus - JavaScript library to make drawing animation on SVG
43720 * @version v0.4.4
43721 * @link https://github.com/maxwellito/vivus
43722 * @license MIT
43723 */
43724
43725'use strict';
43726
43727(function () {
43728
43729  'use strict';
43730
43731/**
43732 * Pathformer
43733 * Beta version
43734 *
43735 * Take any SVG version 1.1 and transform
43736 * child elements to 'path' elements
43737 *
43738 * This code is purely forked from
43739 * https://github.com/Waest/SVGPathConverter
43740 */
43741
43742/**
43743 * Class constructor
43744 *
43745 * @param {DOM|String} element Dom element of the SVG or id of it
43746 */
43747function Pathformer(element) {
43748  // Test params
43749  if (typeof element === 'undefined') {
43750	throw new Error('Pathformer [constructor]: "element" parameter is required');
43751  }
43752
43753  // Set the element
43754  if (element.constructor === String) {
43755	element = document.getElementById(element);
43756	if (!element) {
43757	  throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID');
43758	}
43759  }
43760  if (element instanceof window.SVGElement ||
43761	  element instanceof window.SVGGElement ||
43762	  /^svg$/i.test(element.nodeName)) {
43763	this.el = element;
43764  } else {
43765	throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement');
43766  }
43767
43768  // Start
43769  this.scan(element);
43770}
43771
43772/**
43773 * List of tags which can be transformed
43774 * to path elements
43775 *
43776 * @type {Array}
43777 */
43778Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect'];
43779
43780/**
43781 * List of attribute names which contain
43782 * data. This array list them to check if
43783 * they contain bad values, like percentage.
43784 *
43785 * @type {Array}
43786 */
43787Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 43787-44585
43787y1', 'y2'];
43788
43789/**
43790 * Finds the elements compatible for transform
43791 * and apply the liked method
43792 *
43793 * @param  {object} options Object from the constructor
43794 */
43795Pathformer.prototype.scan = function (svg) {
43796  var fn, element, pathData, pathDom,
43797	  elements = svg.querySelectorAll(this.TYPES.join(','));
43798
43799  for (var i = 0; i < elements.length; i++) {
43800	element = elements[i];
43801	fn = this[element.tagName.toLowerCase() + 'ToPath'];
43802	pathData = fn(this.parseAttr(element.attributes));
43803	pathDom = this.pathMaker(element, pathData);
43804	element.parentNode.replaceChild(pathDom, element);
43805  }
43806};
43807
43808
43809/**
43810 * Read `line` element to extract and transform
43811 * data, to make it ready for a `path` object.
43812 *
43813 * @param  {DOMelement} element Line element to transform
43814 * @return {object}			 Data for a `path` element
43815 */
43816Pathformer.prototype.lineToPath = function (element) {
43817  var newElement = {},
43818	  x1 = element.x1 || 0,
43819	  y1 = element.y1 || 0,
43820	  x2 = element.x2 || 0,
43821	  y2 = element.y2 || 0;
43822
43823  newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2;
43824  return newElement;
43825};
43826
43827/**
43828 * Read `rect` element to extract and transform
43829 * data, to make it ready for a `path` object.
43830 * The radius-border is not taken in charge yet.
43831 * (your help is more than welcomed)
43832 *
43833 * @param  {DOMelement} element Rect element to transform
43834 * @return {object}             Data for a `path` element
43835 */
43836Pathformer.prototype.rectToPath = function (element) {
43837  var newElement = {},
43838      x      = parseFloat(element.x)      || 0,
43839      y      = parseFloat(element.y)      || 0,
43840      width  = parseFloat(element.width)  || 0,
43841      height = parseFloat(element.height) || 0;
43842
43843  if (element.rx || element.ry) {
43844    var rx = parseInt(element.rx, 10) || -1,
43845        ry = parseInt(element.ry, 10) || -1;
43846    rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2);
43847    ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2);
43848
43849    newElement.d = 'M ' + (x + rx) + ',' + y + ' ' +
43850                   'L ' + (x + width - rx) + ',' + y + ' ' +
43851                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' +
43852                   'L ' + (x + width) + ',' + (y + height - ry) + ' ' +
43853                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' +
43854                   'L ' + (x + rx) + ',' + (y + height) + ' ' +
43855                   'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' +
43856                   'L ' + x + ',' + (y + ry) + ' ' +
43857                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y;
43858  }
43859  else {
43860    newElement.d = 'M' + x + ' ' + y + ' ' +
43861                   'L' + (x + width) + ' ' + y + ' ' +
43862                   'L' + (x + width) + ' ' + (y + height) + ' ' +
43863                   'L' + x + ' ' + (y + height) + ' Z';
43864  }
43865  return newElement;
43866};
43867
43868/**
43869 * Read `polyline` element to extract and transform
43870 * data, to make it ready for a `path` object.
43871 *
43872 * @param  {DOMelement} element Polyline element to transform
43873 * @return {object}             Data for a `path` element
43874 */
43875Pathformer.prototype.polylineToPath = function (element) {
43876  var newElement = {},
43877      points = element.points.trim().split(' '),
43878      i, path;
43879
43880  // Reformatting if points are defined without commas
43881  if (element.points.indexOf(',') === -1) {
43882    var formattedPoints = [];
43883    for (i = 0; i < points.length; i+=2) {
43884      formattedPoints.push(points[i] + ',' + points[i+1]);
43885    }
43886    points = formattedPoints;
43887  }
43888
43889  // Generate the path.d value
43890  path = 'M' + points[0];
43891  for(i = 1; i < points.length; i++) {
43892    if (points[i].indexOf(',') !== -1) {
43893      path += 'L' + points[i];
43894    }
43895  }
43896  newElement.d = path;
43897  return newElement;
43898};
43899
43900/**
43901 * Read `polygon` element to extract and transform
43902 * data, to make it ready for a `path` object.
43903 * This method rely on polylineToPath, because the
43904 * logic is similar. The path created is just closed,
43905 * so it needs an 'Z' at the end.
43906 *
43907 * @param  {DOMelement} element Polygon element to transform
43908 * @return {object}             Data for a `path` element
43909 */
43910Pathformer.prototype.polygonToPath = function (element) {
43911  var newElement = Pathformer.prototype.polylineToPath(element);
43912
43913  newElement.d += 'Z';
43914  return newElement;
43915};
43916
43917/**
43918 * Read `ellipse` element to extract and transform
43919 * data, to make it ready for a `path` object.
43920 *
43921 * @param  {DOMelement} element ellipse element to transform
43922 * @return {object}             Data for a `path` element
43923 */
43924Pathformer.prototype.ellipseToPath = function (element) {
43925  var newElement = {},
43926      rx = parseFloat(element.rx) || 0,
43927      ry = parseFloat(element.ry) || 0,
43928      cx = parseFloat(element.cx) || 0,
43929      cy = parseFloat(element.cy) || 0,
43930      startX = cx - rx,
43931      startY = cy,
43932      endX = parseFloat(cx) + parseFloat(rx),
43933      endY = cy;
43934
43935  newElement.d = 'M' + startX + ',' + startY +
43936                 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY +
43937                 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY;
43938  return newElement;
43939};
43940
43941/**
43942 * Read `circle` element to extract and transform
43943 * data, to make it ready for a `path` object.
43944 *
43945 * @param  {DOMelement} element Circle element to transform
43946 * @return {object}             Data for a `path` element
43947 */
43948Pathformer.prototype.circleToPath = function (element) {
43949  var newElement = {},
43950      r  = parseFloat(element.r)  || 0,
43951      cx = parseFloat(element.cx) || 0,
43952      cy = parseFloat(element.cy) || 0,
43953      startX = cx - r,
43954      startY = cy,
43955      endX = parseFloat(cx) + parseFloat(r),
43956      endY = cy;
43957
43958  newElement.d =  'M' + startX + ',' + startY +
43959                  'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY +
43960                  'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY;
43961  return newElement;
43962};
43963
43964/**
43965 * Create `path` elements form original element
43966 * and prepared objects
43967 *
43968 * @param  {DOMelement} element  Original element to transform
43969 * @param  {object} pathData     Path data (from `toPath` methods)
43970 * @return {DOMelement}          Path element
43971 */
43972Pathformer.prototype.pathMaker = function (element, pathData) {
43973  var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path');
43974  for(i = 0; i < element.attributes.length; i++) {
43975    attr = element.attributes[i];
43976    if (this.ATTR_WATCH.indexOf(attr.name) === -1) {
43977      pathTag.setAttribute(attr.name, attr.value);
43978    }
43979  }
43980  for(i in pathData) {
43981    pathTag.setAttribute(i, pathData[i]);
43982  }
43983  return pathTag;
43984};
43985
43986/**
43987 * Parse attributes of a DOM element to
43988 * get an object of attribute => value
43989 *
43990 * @param  {NamedNodeMap} attributes Attributes object from DOM element to parse
43991 * @return {object}                  Object of attributes
43992 */
43993Pathformer.prototype.parseAttr = function (element) {
43994  var attr, output = {};
43995  for (var i = 0; i < element.length; i++) {
43996    attr = element[i];
43997    // Check if no data attribute contains '%', or the transformation is impossible
43998    if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) {
43999      throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.');
44000    }
44001    output[attr.name] = attr.value;
44002  }
44003  return output;
44004};
44005
44006  'use strict';
44007
44008var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt;
44009
44010/**
44011 * Vivus
44012 * Beta version
44013 *
44014 * Take any SVG and make the animation
44015 * to give give the impression of live drawing
44016 *
44017 * This in more than just inspired from codrops
44018 * At that point, it's a pure fork.
44019 */
44020
44021/**
44022 * Class constructor
44023 * option structure
44024 *   type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed)
44025 *   duration: <int> (in frames)
44026 *   start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport)
44027 *   delay: <int> (delay between the drawing of first and last path)
44028 *   dashGap <integer> whitespace extra margin between dashes
44029 *   pathTimingFunction <function> timing animation function for each path element of the SVG
44030 *   animTimingFunction <function> timing animation function for the complete SVG
44031 *   forceRender <boolean> force the browser to re-render all updated path items
44032 *   selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original
44033 *
44034 * The attribute 'type' is by default on 'delayed'.
44035 *  - 'delayed'
44036 *    all paths are draw at the same time but with a
44037 *    little delay between them before start
44038 *  - 'sync'
44039 *    all path are start and finish at the same time
44040 *  - 'oneByOne'
44041 *    only one path is draw at the time
44042 *    the end of the first one will trigger the draw
44043 *    of the next one
44044 *
44045 * All these values can be overwritten individually
44046 * for each path item in the SVG
44047 * The value of frames will always take the advantage of
44048 * the duration value.
44049 * If you fail somewhere, an error will be thrown.
44050 * Good luck.
44051 *
44052 * @constructor
44053 * @this {Vivus}
44054 * @param {DOM|String}   element  Dom element of the SVG or id of it
44055 * @param {Object}       options  Options about the animation
44056 * @param {Function}     callback Callback for the end of the animation
44057 */
44058function Vivus (element, options, callback) {
44059
44060  setupEnv();
44061
44062  // Setup
44063  this.isReady = false;
44064  this.setElement(element, options);
44065  this.setOptions(options);
44066  this.setCallback(callback);
44067
44068  if (this.isReady) {
44069    this.init();
44070  }
44071}
44072
44073/**
44074 * Timing functions
44075 **************************************
44076 *
44077 * Default functions to help developers.
44078 * It always take a number as parameter (between 0 to 1) then
44079 * return a number (between 0 and 1)
44080 */
44081Vivus.LINEAR          = function (x) {return x;};
44082Vivus.EASE            = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;};
44083Vivus.EASE_OUT        = function (x) {return 1 - Math.pow(1-x, 3);};
44084Vivus.EASE_IN         = function (x) {return Math.pow(x, 3);};
44085Vivus.EASE_OUT_BOUNCE = function (x) {
44086  var base = -Math.cos(x * (0.5 * Math.PI)) + 1,
44087    rate = Math.pow(base,1.5),
44088    rateR = Math.pow(1 - x, 2),
44089    progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1;
44090  return (1- rateR) + (progress * rateR);
44091};
44092
44093
44094/**
44095 * Setters
44096 **************************************
44097 */
44098
44099/**
44100 * Check and set the element in the instance
44101 * The method will not return anything, but will throw an
44102 * error if the parameter is invalid
44103 *
44104 * @param {DOM|String}   element  SVG Dom element or id of it
44105 */
44106Vivus.prototype.setElement = function (element, options) {
44107  var onLoad, self;
44108
44109  // Basic check
44110  if (typeof element === 'undefined') {
44111    throw new Error('Vivus [constructor]: "element" parameter is required');
44112  }
44113
44114  // Set the element
44115  if (element.constructor === String) {
44116    element = document.getElementById(element);
44117    if (!element) {
44118      throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');
44119    }
44120  }
44121  this.parentEl = element;
44122
44123  // Load the SVG with XMLHttpRequest and extract the SVG
44124  if (options && options.file) {
44125    var self = this;
44126    onLoad = function (e) {
44127      var domSandbox = document.createElement('div');
44128      domSandbox.innerHTML = this.responseText;
44129
44130      var svgTag = domSandbox.querySelector('svg');
44131      if (!svgTag) {
44132        throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file);
44133      }
44134
44135      self.el = svgTag
44136      self.el.setAttribute('width', '100%');
44137      self.el.setAttribute('height', '100%');
44138      self.parentEl.appendChild(self.el)
44139      self.isReady = true;
44140      self.init();
44141      self = null;
44142    }
44143
44144    var oReq = new window.XMLHttpRequest();
44145    oReq.addEventListener('load', onLoad);
44146    oReq.open('GET', options.file);
44147    oReq.send();
44148    return;
44149  }
44150
44151  switch (element.constructor) {
44152  case window.SVGSVGElement:
44153  case window.SVGElement:
44154  case window.SVGGElement:
44155    this.el = element;
44156    this.isReady = true;
44157    break;
44158
44159  case window.HTMLObjectElement:
44160    self = this;
44161    onLoad = function (e) {
44162      if (self.isReady) {
44163        return;
44164      }
44165      self.el = element.contentDocument && element.contentDocument.querySelector('svg');
44166      if (!self.el && e) {
44167        throw new Error('Vivus [constructor]: object loaded does not contain any SVG');
44168      }
44169      else if (self.el) {
44170        if (element.getAttribute('built-by-vivus')) {
44171          self.parentEl.insertBefore(self.el, element);
44172          self.parentEl.removeChild(element);
44173          self.el.setAttribute('width', '100%');
44174          self.el.setAttribute('height', '100%');
44175        }
44176        self.isReady = true;
44177        self.init();
44178        self = null;
44179      }
44180    };
44181
44182    if (!onLoad()) {
44183      element.addEventListener('load', onLoad);
44184    }
44185    break;
44186
44187  default:
44188    throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)');
44189  }
44190};
44191
44192/**
44193 * Set up user option to the instance
44194 * The method will not return anything, but will throw an
44195 * error if the parameter is invalid
44196 *
44197 * @param  {object} options Object from the constructor
44198 */
44199Vivus.prototype.setOptions = function (options) {
44200  var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync'];
44201  var allowedStarts =  ['inViewport', 'manual', 'autostart'];
44202
44203  // Basic check
44204  if (options !== undefined && options.constructor !== Object) {
44205    throw new Error('Vivus [constructor]: "options" parameter must be an object');
44206  }
44207  else {
44208    options = options || {};
44209  }
44210
44211  // Set the animation type
44212  if (options.type && allowedTypes.indexOf(options.type) === -1) {
44213    throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`');
44214  }
44215  else {
44216    this.type = options.type || allowedTypes[0];
44217  }
44218
44219  // Set the start type
44220  if (options.start && allowedStarts.indexOf(options.start) === -1) {
44221    throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option');
44222  }
44223  else {
44224    this.start = options.start || allowedStarts[0];
44225  }
44226
44227  this.isIE         = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 );
44228  this.duration     = parsePositiveInt(options.duration, 120);
44229  this.delay        = parsePositiveInt(options.delay, null);
44230  //Uncode addition
44231  this.delayStart   = parsePositiveInt(options.delayStart, null);
44232  //#END
44233  this.dashGap      = parsePositiveInt(options.dashGap, 1);
44234  this.forceRender  = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE;
44235  this.reverseStack = !!options.reverseStack;
44236  this.selfDestroy  = !!options.selfDestroy;
44237  this.onReady      = options.onReady;
44238  this.map          = [];
44239  this.frameLength  = this.currentFrame = this.delayUnit = this.speed = this.handle = null;
44240
44241  this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false;
44242
44243  this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR;
44244  this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR;
44245
44246  if (this.delay >= this.duration) {
44247    throw new Error('Vivus [constructor]: delay must be shorter than duration');
44248  }
44249};
44250
44251/**
44252 * Set up callback to the instance
44253 * The method will not return enything, but will throw an
44254 * error if the parameter is invalid
44255 *
44256 * @param  {Function} callback Callback for the animation end
44257 */
44258Vivus.prototype.setCallback = function (callback) {
44259  // Basic check
44260  if (!!callback && callback.constructor !== Function) {
44261    throw new Error('Vivus [constructor]: "callback" parameter must be a function');
44262  }
44263  this.callback = callback || function () {};
44264};
44265
44266
44267/**
44268 * Core
44269 **************************************
44270 */
44271
44272/**
44273 * Map the svg, path by path.
44274 * The method return nothing, it just fill the
44275 * `map` array. Each item in this array represent
44276 * a path element from the SVG, with informations for
44277 * the animation.
44278 *
44279 * ```
44280 * [
44281 *   {
44282 *     el: <DOMobj> the path element
44283 *     length: <number> length of the path line
44284 *     startAt: <number> time start of the path animation (in frames)
44285 *     duration: <number> path animation duration (in frames)
44286 *   },
44287 *   ...
44288 * ]
44289 * ```
44290 *
44291 */
44292Vivus.prototype.mapping = function () {
44293  var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint;
44294  timePoint = totalLength = lengthMeter = 0;
44295  paths = this.el.querySelectorAll('path');
44296
44297  for (i = 0; i < paths.length; i++) {
44298    path = paths[i];
44299    if (this.isInvisible(path)) {
44300      continue;
44301    }
44302    pathObj = {
44303      el: path,
44304      length: Math.ceil(path.getTotalLength())
44305    };
44306    // Test if the path length is correct
44307    if (isNaN(pathObj.length)) {
44308      if (window.console && console.warn) {
44309        console.warn('Vivus [mapping]: cannot retrieve a path element length', path);
44310      }
44311      continue;
44312    }
44313    this.map.push(pathObj);
44314    path.style.strokeDasharray  = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2);
44315    path.style.strokeDashoffset = pathObj.length + this.dashGap;
44316    pathObj.length += this.dashGap;
44317    totalLength += pathObj.length;
44318
44319    this.renderPath(i);
44320  }
44321
44322  totalLength = totalLength === 0 ? 1 : totalLength;
44323  this.delay = this.delay === null ? this.duration / 3 : this.delay;
44324  this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1);
44325
44326  // Reverse stack if asked
44327  if (this.reverseStack) {
44328    this.map.reverse();
44329  }
44330
44331  for (i = 0; i < this.map.length; i++) {
44332    pathObj = this.map[i];
44333
44334    switch (this.type) {
44335    case 'delayed':
44336      pathObj.startAt = this.delayUnit * i;
44337      pathObj.duration = this.duration - this.delay;
44338      break;
44339
44340    case 'oneByOne':
44341      pathObj.startAt = lengthMeter / totalLength * this.duration;
44342      pathObj.duration = pathObj.length / totalLength * this.duration;
44343      break;
44344
44345    case 'sync':
44346    case 'async':
44347    case 'nsync':
44348      pathObj.startAt = 0;
44349      pathObj.duration = this.duration;
44350      break;
44351
44352    case 'scenario-sync':
44353      path = pathObj.el;
44354      pAttrs = this.parseAttr(path);
44355      pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0);
44356      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
44357      timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration;
44358      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
44359      break;
44360
44361    case 'scenario':
44362      path = pathObj.el;
44363      pAttrs = this.parseAttr(path);
44364      pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0;
44365      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
44366      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
44367      break;
44368    }
44369    lengthMeter += pathObj.length;
44370    this.frameLength = this.frameLength || this.duration;
44371  }
44372};
44373
44374/**
44375 * Interval method to draw the SVG from current
44376 * position of the animation. It update the value of
44377 * `currentFrame` and re-trace the SVG.
44378 *
44379 * It use this.handle to store the requestAnimationFrame
44380 * and clear it one the animation is stopped. So this
44381 * attribute can be used to know if the animation is
44382 * playing.
44383 *
44384 * Once the animation at the end, this method will
44385 * trigger the Vivus callback.
44386 *
44387 */
44388Vivus.prototype.drawer = function () {
44389  var self = this;
44390  this.currentFrame += this.speed;
44391
44392  if (this.currentFrame <= 0) {
44393    this.stop();
44394    this.reset();
44395  } else if (this.currentFrame >= this.frameLength) {
44396    this.stop();
44397    this.currentFrame = this.frameLength;
44398    this.trace();
44399    if (this.selfDestroy) {
44400      this.destroy();
44401    }
44402  } else {
44403    this.trace();
44404    this.handle = requestAnimFrame(function () {
44405      self.drawer();
44406    });
44407    return;
44408  }
44409
44410  this.callback(this);
44411  if (this.instanceCallback) {
44412    this.instanceCallback(this);
44413    this.instanceCallback = null;
44414  }
44415};
44416
44417/**
44418 * Draw the SVG at the current instant from the
44419 * `currentFrame` value. Here is where most of the magic is.
44420 * The trick is to use the `strokeDashoffset` style property.
44421 *
44422 * For optimisation reasons, a new property called `progress`
44423 * is added in each item of `map`. This one contain the current
44424 * progress of the path element. Only if the new value is different
44425 * the new value will be applied to the DOM element. This
44426 * method save a lot of resources to re-render the SVG. And could
44427 * be improved if the animation couldn't be played forward.
44428 *
44429 */
44430Vivus.prototype.trace = function () {
44431  var i, progress, path, currentFrame;
44432  currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength;
44433  for (i = 0; i < this.map.length; i++) {
44434    path = this.map[i];
44435    progress = (currentFrame - path.startAt) / path.duration;
44436    progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress)));
44437    if (path.progress !== progress) {
44438      path.progress = progress;
44439      path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress));
44440      this.renderPath(i);
44441    }
44442  }
44443};
44444
44445/**
44446 * Method forcing the browser to re-render a path element
44447 * from it's index in the map. Depending on the `forceRender`
44448 * value.
44449 * The trick is to replace the path element by it's clone.
44450 * This practice is not recommended because it's asking more
44451 * ressources, too much DOM manupulation..
44452 * but it's the only way to let the magic happen on IE.
44453 * By default, this fallback is only applied on IE.
44454 *
44455 * @param  {Number} index Path index
44456 */
44457Vivus.prototype.renderPath = function (index) {
44458  if (this.forceRender && this.map && this.map[index]) {
44459    var pathObj = this.map[index],
44460        newPath = pathObj.el.cloneNode(true);
44461    pathObj.el.parentNode.replaceChild(newPath, pathObj.el);
44462    pathObj.el = newPath;
44463  }
44464};
44465
44466/**
44467 * When the SVG object is loaded and ready,
44468 * this method will continue the initialisation.
44469 *
44470 * This this mainly due to the case of passing an
44471 * object tag in the constructor. It will wait
44472 * the end of the loading to initialise.
44473 *
44474 */
44475Vivus.prototype.init = function () {
44476  // Set object variables
44477  this.frameLength = 0;
44478  this.currentFrame = 0;
44479  this.map = [];
44480
44481  // Start
44482  new Pathformer(this.el);
44483  this.mapping();
44484  this.starter();
44485
44486  if (this.onReady) {
44487    this.onReady(this);
44488  }
44489};
44490
44491/**
44492 * Trigger to start of the animation.
44493 * Depending on the `start` value, a different script
44494 * will be applied.
44495 *
44496 * If the `start` value is not valid, an error will be thrown.
44497 * Even if technically, this is impossible.
44498 *
44499 */
44500Vivus.prototype.starter = function () {
44501  switch (this.start) {
44502  case 'manual':
44503    return;
44504
44505  case 'autostart':
44506    this.play();
44507    break;
44508
44509  case 'inViewport':
44510    var self = this,
44511    listener = function () {
44512      if (self.isInViewport(self.parentEl, 1)) {
44513        self.play();
44514        window.removeEventListener('scroll', listener);
44515        //Uncode addition
44516        window.removeEventListener('fp-slide-changed', listener);
44517        window.removeEventListener('fp-slide-scroll', listener);
44518        //#END
44519      }
44520    };
44521    window.addEventListener('scroll', listener);
44522    //Uncode addition
44523    window.addEventListener('fp-slide-changed', listener);
44524    window.addEventListener('fp-slide-scroll', listener);
44525    //#END
44526    listener();
44527    break;
44528  }
44529};
44530
44531
44532/**
44533 * Controls
44534 **************************************
44535 */
44536
44537/**
44538 * Get the current status of the animation between
44539 * three different states: 'start', 'progress', 'end'.
44540 * @return {string} Instance status
44541 */
44542Vivus.prototype.getStatus = function () {
44543  return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress';
44544};
44545
44546/**
44547 * Reset the instance to the initial state : undraw
44548 * Be careful, it just reset the animation, if you're
44549 * playing the animation, this won't stop it. But just
44550 * make it start from start.
44551 *
44552 */
44553Vivus.prototype.reset = function () {
44554  return this.setFrameProgress(0);
44555};
44556
44557/**
44558 * Set the instance to the final state : drawn
44559 * Be careful, it just set the animation, if you're
44560 * playing the animation on rewind, this won't stop it.
44561 * But just make it start from the end.
44562 *
44563 */
44564Vivus.prototype.finish = function () {
44565  return this.setFrameProgress(1);
44566};
44567
44568/**
44569 * Set the level of progress of the drawing.
44570 *
44571 * @param {number} progress Level of progress to set
44572 */
44573Vivus.prototype.setFrameProgress = function (progress) {
44574  progress = Math.min(1, Math.max(0, progress));
44575  this.currentFrame = Math.round(this.frameLength * progress);
44576  this.trace();
44577  return this;
44578};
44579
44580/**
44581 * Play the animation at the desired speed.
44582 * Speed must be a valid number (no zero).
44583 * By default, the speed value is 1.
44584 * But a negative value is accepted to go forward.
44585 *
44586 * And works with float too.
44587 * But don't forget we are in JavaScript, se be nice
44588 * with him and give him a 1/2^x value.
44589 *
44590 * @param  {number} speed Animation speed [optional]
44591 */
44592Vivus.prototype.play = function (speed, callback) {
44593  this.instanceCallback = null;
44594
44595  if (speed && typeof speed === 'function') {
44596    this.instanceCallback = speed; // first parameter is actually the callback function
44597    speed = null;
44598  }
44599  else if (speed && typeof speed !== 'number') {
44600    throw new Error('Vivus [play]: invalid speed');
44601  }
44602  // if the first parameter wasn't the callback, check if the seconds was
44603  if (callback && typeof(callback) === 'function' && !this.instanceCallback) {
44604    this.instanceCallback = callback;
44605  }
44606
44607
44608  this.speed = speed || 1;
44609  //Uncode addition
44610  if (!this.handle) {
44611    var $this = this,
44612    delay = (this.delayStart != null) ? this.delayStart : 0;
44613    setTimeout(function() {
44614      $this.drawer();
44615    }, delay);
44616  }
44617  //#END
44618  return this;
44619};
44620
44621/**
44622 * Stop the current animation, if on progress.
44623 * Should not trigger any error.
44624 *
44625 */
44626Vivus.prototype.stop = function () {
44627  if (this.handle) {
44628    cancelAnimFrame(this.handle);
44629    this.handle = null;
44630  }
44631  return this;
44632};
44633
44634/**
44635 * Destroy the instance.
44636 * Remove all bad styling attributes on all
44637 * path tags
44638 *
44639 */
44640Vivus.prototype.destroy = function () {
44641  this.stop();
44642  var i, path;
44643  for (i = 0; i < this.map.length; i++) {
44644    path = this.map[i];
44645    path.el.style.strokeDashoffset = null;
44646    path.el.style.strokeDasharray = null;
44647    this.renderPath(i);
44648  }
44649};
44650
44651
44652/**
44653 * Utils methods
44654 * include methods from Codrops
44655 **************************************
44656 */
44657
44658/**
44659 * Method to best guess if a path should added into
44660 * the animation or not.
44661 *
44662 * 1. Use the `data-vivus-ignore` attribute if set
44663 * 2. Check if the instance must ignore invisible paths
44664 * 3. Check if the path is visible
44665 *
44666 * For now the visibility checking is unstable.
44667 * It will be used for a beta phase.
44668 *
44669 * Other improvments are planned. Like detecting
44670 * is the path got a stroke or a valid opacity.
44671 */
44672Vivus.prototype.isInvisible = function (el) {
44673  var rect,
44674    ignoreAttr = el.getAttribute('data-ignore');
44675
44676  if (ignoreAttr !== null) {
44677    return ignoreAttr !== 'false';
44678  }
44679
44680  if (this.ignoreInvisible) {
44681    rect = el.getBoundingClientRect();
44682    return !rect.width && !rect.height;
44683  }
44684  else {
44685    return false;
44686  }
44687};
44688
44689/**
44690 * Parse attributes of a DOM element to
44691 * get an object of {attributeName => attributeValue}
44692 *
44693 * @param  {object} element DOM element to parse
44694 * @return {object}         Object of attributes
44695 */
44696Vivus.prototype.parseAttr = function (element) {
44697  var attr, output = {};
44698  if (element && element.attributes) {
44699    for (var i = 0; i < element.attributes.length; i++) {
44700      attr = element.attributes[i];
44701      output[attr.name] = attr.value;
44702    }
44703  }
44704  return output;
44705};
44706
44707/**
44708 * Reply if an element is in the page viewport
44709 *
44710 * @param  {object} el Element to observe
44711 * @param  {number} h  Percentage of height
44712 * @return {boolean}
44713 */
44714Vivus.prototype.isInViewport = function (el, h) {
44715  var scrolled   = this.scrollY(),
44716    viewed       = scrolled + this.getViewportH(),
44717    elBCR        = el.getBoundingClientRect(),
44718    elHeight     = elBCR.height,
44719    elTop        = scrolled + elBCR.top,
44720    elBottom     = elTop + elHeight;
44721
44722  // if 0, the element is considered in the viewport as soon as it enters.
44723  // if 1, the element is considered in the viewport only when it's fully inside
44724  // value in percentage (1 >= h >= 0)
44725  h = h || 0;
44726
44727  return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled;
44728};
44729
44730
44731/**
44732 * Get the viewport height in pixels
44733 *
44734 * @return {integer} Viewport height
44735 */
44736Vivus.prototype.getViewportH = function () {
44737  var client = this.docElem.clientHeight,
44738    inner = window.innerHeight;
44739
44740  if (client < inner) {
44741    return inner;
44742  }
44743  else {
44744    return client;
44745  }
44746};
44747
44748/**
44749 * Get the page Y offset
44750 *
44751 * @return {integer} Page Y offset
44752 */
44753Vivus.prototype.scrollY = function () {
44754  return window.pageYOffset || this.docElem.scrollTop;
44755};
44756
44757setupEnv = function () {
44758
44759  if (Vivus.prototype.docElem) {
44760    return;
44761  }
44762
44763  /**
44764   * Alias for document element
44765   *
44766   * @type {DOMelement}
44767   */
44768  Vivus.prototype.docElem = window.document.documentElement;
44769
44770  /**
44771   * Alias for `requestAnimationFrame` or
44772   * `setTimeout` function for deprecated browsers.
44773   *
44774   */
44775  requestAnimFrame = (function () {
44776    return (
44777      window.requestAnimationFrame       ||
44778      window.webkitRequestAnimationFrame ||
44779      window.mozRequestAnimationFrame    ||
44780      window.oRequestAnimationFrame      ||
44781      window.msRequestAnimationFrame     ||
44782      function(/* function */ callback){
44783        return window.setTimeout(callback, 1000 / 60);
44784      }
44785    );
44786  })();
44787
44788  /**
44789   * Alias for `cancelAnimationFrame` or
44790   * `cancelTimeout` function for deprecated browsers.
44791   *
44792   */
44793  cancelAnimFrame = (function () {
44794    return (
44795      window.cancelAnimationFrame       ||
44796      window.webkitCancelAnimationFrame ||
44797      window.mozCancelAnimationFrame    ||
44798      window.oCancelAnimationFrame      ||
44799      window.msCancelAnimationFrame     ||
44800      function(id){
44801        return window.clearTimeout(id);
44802      }
44803    );
44804  })();
44805};
44806
44807/**
44808 * Parse string to integer.
44809 * If the number is not positive or null
44810 * the method will return the default value
44811 * or 0 if undefined
44812 *
44813 * @param {string} value String to parse
44814 * @param {*}
44814 defaultValue Value to return if the result parsed is invalid
44815 * @return {number}
44816 *
44817 */
44818parsePositiveInt = function (value, defaultValue) {
44819  var output = parseInt(value, 10);
44820  return (output >= 0) ? output : defaultValue;
44821};
44822
44823
44824  if (typeof define === 'function' && define.amd) {
44825    // AMD. Register as an anonymous module.
44826    define([], function() {
44827      return Vivus;
44828    });
44829  } else if (typeof exports === 'object') {
44830    // Node. Does not work with strict CommonJS, but
44831    // only CommonJS-like environments that support module.exports,
44832    // like Node.
44833    module.exports = Vivus;
44834  } else {
44835    // Browser globals
44836    window.Vivus = Vivus;
44837  }
44838
44839}());
44840
44841//Noise.js
44842!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)}
44842var 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.