PageSourceSearch

https://movementstrategy.org/wp-content/themes/uncode/library/js/plugins.js?ver=37075504

js movementstrategy.org collected 2026-09-24 10:25:25 UTC 1,485,435 bytes, 44,889 lines download raw bytes

vendor: 4,970 bytes, lines 1-161
1/* ----------------------------------------------------------
2 * Plugins
3 * ---------------------------------------------------------- */
4
5(function (global, factory) {
6  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
7  typeof define === 'function' && define.amd ? define(['exports'], factory) :
8  (global = global || self, factory(global.window = global.window || {}));
9}(this, (function (exports) { 'use strict';
10
11  function _inheritsLoose(subClass, superClass) {
12    subClass.prototype = Object.create(superClass.prototype);
13    subClass.prototype.constructor = subClass;
14    subClass.__proto__ = superClass;
15  }
16
17  function _assertThisInitialized(self) {
18    if (self === void 0) {
19      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
20    }
21
22    return self;
23  }
24
25  /*!
26   * GSAP 3.12.5
27   * https://gsap.com
28   *
29   * @license Copyright 2008-2024, GreenSock. All rights reserved.
30   * Subject to the terms at https://gsap.com/standard-license or for
31   * Club GSAP members, the agreement issued with that membership.
32   * @author: Jack Doyle, [email protected]
33  */
34  var _config = {
35    autoSleep: 120,
36    force3D: "auto",
37    nullTargetWarn: 1,
38    units: {
39      lineHeight: ""
40    }
41  },
42      _defaults = {
43    duration: .5,
44    overwrite: false,
45    delay: 0
46  },
47      _suppressOverwrites,
48      _reverting,
49      _context,
50      _bigNum = 1e8,
51      _tinyNum = 1 / _bigNum,
52      _2PI = Math.PI * 2,
53      _HALF_PI = _2PI / 4,
54      _gsID = 0,
55      _sqrt = Math.sqrt,
56      _cos = Math.cos,
57      _sin = Math.sin,
58      _isString = function _isString(value) {
59    return typeof value === "string";
60  },
61      _isFunction = function _isFunction(value) {
62    return typeof value === "function";
63  },
64      _isNumber = function _isNumber(value) {
65    return typeof value === "number";
66  },
67      _isUndefined = function _isUndefined(value) {
68    return typeof value === "undefined";
69  },
70      _isObject = function _isObject(value) {
71    return typeof value === "object";
72  },
73      _isNotFalse = function _isNotFalse(value) {
74    return value !== false;
75  },
76      _windowExists = function _windowExists() {
77    return typeof window !== "undefined";
78  },
79      _isFuncOrString = function _isFuncOrString(value) {
80    return _isFunction(value) || _isString(value);
81  },
82      _isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView || function () {},
83      _isArray = Array.isArray,
84      _strictNumExp = /(?:-?\.?\d|\.)+/gi,
85      _numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g,
86      _numWithUnitExp = /[-+=.]*\d+[.e-]*\d*[a-z%]*/g,
87      _complexStringNumExp = /[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi,
88      _relExp = /[+-]=-?[.\d]+/,
89      _delimitedValueExp = /[^,'"\[\]\s]+/gi,
90      _unitExp = /^[+\-=e\s\d]*\d+[.\d]*([a-z]*|%)\s*$/i,
91      _globalTimeline,
92      _win,
93      _coreInitted,
94      _doc,
95      _globals = {},
96      _installScope = {},
97      _coreReady,
98      _install = function _install(scope) {
99    return (_installScope = _merge(scope, _globals)) && gsap;
100  },
101      _missingPlugin = function _missingPlugin(property, value) {
102    return console.warn("Invalid property", property, "set to", value, "Missing plugin? gsap.registerPlugin()");
103  },
104      _warn = function _warn(message, suppress) {
105    return !suppress && console.warn(message);
106  },
107      _addGlobal = function _addGlobal(name, obj) {
108    return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals;
109  },
110      _emptyFunc = function _emptyFunc() {
111    return 0;
112  },
113      _startAtRevertConfig = {
114    suppressEvents: true,
115    isStart: true,
116    kill: false
117  },
118      _revertConfigNoKill = {
119    suppressEvents: true,
120    kill: false
121  },
122      _revertConfig = {
123    suppressEvents: true
124  },
125      _reservedProps = {},
126      _lazyTweens = [],
127      _lazyLookup = {},
128      _lastRenderedFrame,
129      _plugins = {},
130      _effects = {},
131      _nextGCFrame = 30,
132      _harnessPlugins = [],
133      _callbackNames = "",
134      _harness = function _harness(targets) {
135    var target = targets[0],
136        harnessPlugin,
137        i;
138    _isObject(target) || _isFunction(target) || (targets = [targets]);
139
140    if (!(harnessPlugin = (target._gsap || {}).harness)) {
141      i = _harnessPlugins.length;
142
143      while (i-- && !_harnessPlugins[i].targetTest(target)) {}
144
145      harnessPlugin = _harnessPlugins[i];
146    }
147
148    i = targets.length;
149
150    while (i--) {
151      targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1);
152    }
153
154    return targets;
155  },
156      _getCache = function _getCache(target) {
157    return target._gsap || _harness(toArray(target))[0]._gsap;
158  },
159      _getProperty = function _getProperty(target, property, v) {
160    return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v;
161  },
vendor: 6,338 bytes, lines 162-371
162      _forEachName = function _forEachName(names, func) {
163    return (names = names.split(",")).forEach(func) || names;
164  },
165      _round = function _round(value) {
166    return Math.round(value * 100000) / 100000 || 0;
167  },
168      _roundPrecise = function _roundPrecise(value) {
169    return Math.round(value * 10000000) / 10000000 || 0;
170  },
171      _parseRelative = function _parseRelative(start, value) {
172    var operator = value.charAt(0),
173        end = parseFloat(value.substr(2));
174    start = parseFloat(start);
175    return operator === "+" ? start + end : operator === "-" ? start - end : operator === "*" ? start * end : start / end;
176  },
177      _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) {
178    var l = toFind.length,
179        i = 0;
180
181    for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {}
182
183    return i < l;
184  },
185      _lazyRender = function _lazyRender() {
186    var l = _lazyTweens.length,
187        a = _lazyTweens.slice(0),
188        i,
189        tween;
190
191    _lazyLookup = {};
192    _lazyTweens.length = 0;
193
194    for (i = 0; i < l; i++) {
195      tween = a[i];
196      tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0);
197    }
198  },
199      _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) {
200    _lazyTweens.length && !_reverting && _lazyRender();
201    animation.render(time, suppressEvents, force || _reverting && time < 0 && (animation._initted || animation._startAt));
202    _lazyTweens.length && !_reverting && _lazyRender();
203  },
204      _numericIfPossible = function _numericIfPossible(value) {
205    var n = parseFloat(value);
206    return (n || n === 0) && (value + "").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value;
207  },
208      _passThrough = function _passThrough(p) {
209    return p;
210  },
211      _setDefaults = function _setDefaults(obj, defaults) {
212    for (var p in defaults) {
213      p in obj || (obj[p] = defaults[p]);
214    }
215
216    return obj;
217  },
218      _setKeyframeDefaults = function _setKeyframeDefaults(excludeDuration) {
219    return function (obj, defaults) {
220      for (var p in defaults) {
221        p in obj || p === "duration" && excludeDuration || p === "ease" || (obj[p] = defaults[p]);
222      }
223    };
224  },
225      _merge = function _merge(base, toMerge) {
226    for (var p in toMerge) {
227      base[p] = toMerge[p];
228    }
229
230    return base;
231  },
232      _mergeDeep = function _mergeDeep(base, toMerge) {
233    for (var p in toMerge) {
234      p !== "__proto__" && p !== "constructor" && p !== "prototype" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]);
235    }
236
237    return base;
238  },
239      _copyExcluding = function _copyExcluding(obj, excluding) {
240    var copy = {},
241        p;
242
243    for (p in obj) {
244      p in excluding || (copy[p] = obj[p]);
245    }
246
247    return copy;
248  },
249      _inheritDefaults = function _inheritDefaults(vars) {
250    var parent = vars.parent || _globalTimeline,
251        func = vars.keyframes ? _setKeyframeDefaults(_isArray(vars.keyframes)) : _setDefaults;
252
253    if (_isNotFalse(vars.inherit)) {
254      while (parent) {
255        func(vars, parent.vars.defaults);
256        parent = parent.parent || parent._dp;
257      }
258    }
259
260    return vars;
261  },
262      _arraysMatch = function _arraysMatch(a1, a2) {
263    var i = a1.length,
264        match = i === a2.length;
265
266    while (match && i-- && a1[i] === a2[i]) {}
267
268    return i < 0;
269  },
270      _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) {
271    if (firstProp === void 0) {
272      firstProp = "_first";
273    }
274
275    if (lastProp === void 0) {
276      lastProp = "_last";
277    }
278
279    var prev = parent[lastProp],
280        t;
281
282    if (sortBy) {
283      t = child[sortBy];
284
285      while (prev && prev[sortBy] > t) {
286        prev = prev._prev;
287      }
288    }
289
290    if (prev) {
291      child._next = prev._next;
292      prev._next = child;
293    } else {
294      child._next = parent[firstProp];
295      parent[firstProp] = child;
296    }
297
298    if (child._next) {
299      child._next._prev = child;
300    } else {
301      parent[lastProp] = child;
302    }
303
304    child._prev = prev;
305    child.parent = child._dp = parent;
306    return child;
307  },
308      _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) {
309    if (firstProp === void 0) {
310      firstProp = "_first";
311    }
312
313    if (lastProp === void 0) {
314      lastProp = "_last";
315    }
316
317    var prev = child._prev,
318        next = child._next;
319
320    if (prev) {
321      prev._next = next;
322    } else if (parent[firstProp] === child) {
323      parent[firstProp] = next;
324    }
325
326    if (next) {
327      next._prev = prev;
328    } else if (parent[lastProp] === child) {
329      parent[lastProp] = prev;
330    }
331
332    child._next = child._prev = child.parent = null;
333  },
334      _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) {
335    child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove && child.parent.remove(child);
336    child._act = 0;
337  },
338      _uncache = function _uncache(animation, child) {
339    if (animation && (!child || child._end > animation._dur || child._start < 0)) {
340      var a = animation;
341
342      while (a) {
343        a._dirty = 1;
344        a = a.parent;
345      }
346    }
347
348    return animation;
349  },
350      _recacheAncestors = function _recacheAncestors(animation) {
351    var parent = animation.parent;
352
353    while (parent && parent.parent) {
354      parent._dirty = 1;
355      parent.totalDuration();
356      parent = parent.parent;
357    }
358
359    return animation;
360  },
361      _rewindStartAt = function _rewindStartAt(tween, totalTime, suppressEvents, force) {
362    return tween._startAt && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween.vars.immediateRender && !tween.vars.autoRevert || tween._startAt.render(totalTime, true, force));
363  },
364      _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) {
365    return !animation || animation._ts && _hasNoPausedAncestors(animation.parent);
366  },
367      _elapsedCycleDuration = function _elapsedCycleDuration(animation) {
368    return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0;
369  },
370      _animationCycle = function _animationCycle(tTime, cycleDuration) {
371    var whole = Math.floor(tTime /= cycleDuration
vendor: 17,487 bytes, lines 371-839
371);
372    return tTime && whole === tTime ? whole - 1 : whole;
373  },
374      _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) {
375    return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur);
376  },
377      _setEnd = function _setEnd(animation) {
378    return animation._end = _roundPrecise(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0));
379  },
380      _alignPlayhead = function _alignPlayhead(animation, totalTime) {
381    var parent = animation._dp;
382
383    if (parent && parent.smoothChildTiming && animation._ts) {
384      animation._start = _roundPrecise(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts));
385
386      _setEnd(animation);
387
388      parent._dirty || _uncache(parent, animation);
389    }
390
391    return animation;
392  },
393      _postAddChecks = function _postAddChecks(timeline, child) {
394    var t;
395
396    if (child._time || !child._dur && child._initted || child._start < timeline._time && (child._dur || !child.add)) {
397      t = _parentToChildTotalTime(timeline.rawTime(), child);
398
399      if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) {
400        child.render(t, true);
401      }
402    }
403
404    if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) {
405      if (timeline._dur < timeline.duration()) {
406        t = timeline;
407
408        while (t._dp) {
409          t.rawTime() >= 0 && t.totalTime(t._tTime);
410          t = t._dp;
411        }
412      }
413
414      timeline._zTime = -_tinyNum;
415    }
416  },
417      _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) {
418    child.parent && _removeFromParent(child);
419    child._start = _roundPrecise((_isNumber(position) ? position : position || timeline !== _globalTimeline ? _parsePosition(timeline, position, child) : timeline._time) + child._delay);
420    child._end = _roundPrecise(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0));
421
422    _addLinkedListItem(timeline, child, "_first", "_last", timeline._sort ? "_start" : 0);
423
424    _isFromOrFromStart(child) || (timeline._recent = child);
425    skipChecks || _postAddChecks(timeline, child);
426    timeline._ts < 0 && _alignPlayhead(timeline, timeline._tTime);
427    return timeline;
428  },
429      _scrollTrigger = function _scrollTrigger(animation, trigger) {
430    return (_globals.ScrollTrigger || _missingPlugin("scrollTrigger", trigger)) && _globals.ScrollTrigger.create(trigger, animation);
431  },
432      _attemptInitTween = function _attemptInitTween(tween, time, force, suppressEvents, tTime) {
433    _initTween(tween, time, tTime);
434
435    if (!tween._initted) {
436      return 1;
437    }
438
439    if (!force && tween._pt && !_reverting && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) {
440      _lazyTweens.push(tween);
441
442      tween._lazy = [tTime, suppressEvents];
443      return 1;
444    }
445  },
446      _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) {
447    var parent = _ref.parent;
448    return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent));
449  },
450      _isFromOrFromStart = function _isFromOrFromStart(_ref2) {
451    var data = _ref2.data;
452    return data === "isFromStart" || data === "isStart";
453  },
454      _renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) {
455    var prevRatio = tween.ratio,
456        ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) && !(!tween._initted && _isFromOrFromStart(tween)) || (tween._ts < 0 || tween._dp._ts < 0) && !_isFromOrFromStart(tween)) ? 0 : 1,
457        repeatDelay = tween._rDelay,
458        tTime = 0,
459        pt,
460        iteration,
461        prevIteration;
462
463    if (repeatDelay && tween._repeat) {
464      tTime = _clamp(0, tween._tDur, totalTime);
465      iteration = _animationCycle(tTime, repeatDelay);
466      tween._yoyo && iteration & 1 && (ratio = 1 - ratio);
467
468      if (iteration !== _animationCycle(tween._tTime, repeatDelay)) {
469        prevRatio = 1 - ratio;
470        tween.vars.repeatRefresh && tween._initted && tween.invalidate();
471      }
472    }
473
474    if (ratio !== prevRatio || _reverting || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) {
475      if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents, tTime)) {
476        return;
477      }
478
479      prevIteration = tween._zTime;
480      tween._zTime = totalTime || (suppressEvents ? _tinyNum : 0);
481      suppressEvents || (suppressEvents = totalTime && !prevIteration);
482      tween.ratio = ratio;
483      tween._from && (ratio = 1 - ratio);
484      tween._time = 0;
485      tween._tTime = tTime;
486      pt = tween._pt;
487
488      while (pt) {
489        pt.r(ratio, pt.d);
490        pt = pt._next;
491      }
492
493      totalTime < 0 && _rewindStartAt(tween, totalTime, suppressEvents, true);
494      tween._onUpdate && !suppressEvents && _callback(tween, "onUpdate");
495      tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, "onRepeat");
496
497      if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) {
498        ratio && _removeFromParent(tween, 1);
499
500        if (!suppressEvents && !_reverting) {
501          _callback(tween, ratio ? "onComplete" : "onReverseComplete", true);
502
503          tween._prom && tween._prom();
504        }
505      }
506    } else if (!tween._zTime) {
507      tween._zTime = totalTime;
508    }
509  },
510      _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) {
511    var child;
512
513    if (time > prevTime) {
514      child = animation._first;
515
516      while (child && child._start <= time) {
517        if (child.data === "isPause" && child._start > prevTime) {
518          return child;
519        }
520
521        child = child._next;
522      }
523    } else {
524      child = animation._last;
525
526      while (child && child._start >= time) {
527        if (child.data === "isPause" && child._start < prevTime) {
528          return child;
529        }
530
531        child = child._prev;
532      }
533    }
534  },
535      _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) {
536    var repeat = animation._repeat,
537        dur = _roundPrecise(duration) || 0,
538        totalProgress = animation._tTime / animation._tDur;
539    totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur);
540    animation._dur = dur;
541    animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _roundPrecise(dur * (repeat + 1) + animation._rDelay * repeat);
542    totalProgress > 0 && !leavePlayhead && _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress);
543    animation.parent && _setEnd(animation);
544    skipUncache || _uncache(animation.parent, animation);
545    return animation;
546  },
547      _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) {
548    return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur);
549  },
550      _zeroPosition = {
551    _start: 0,
552    endTime: _emptyFunc,
553    totalDuration: _emptyFunc
554  },
555      _parsePosition = function _parsePosition(animation, position, percentAnimation) {
556    var labels = animation.labels,
557        recent = animation._recent || _zeroPosition,
558        clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur,
559        i,
560        offset,
561        isPercent;
562
563    if (_isString(position) && (isNaN(position) || position in labels)) {
564      offset = position.charAt(0);
565      isPercent = position.substr(-1) === "%";
566      i = position.indexOf("=");
567
568      if (offset === "<" || offset === ">") {
569        i >= 0 && (position = position.replace(/=/, ""));
570        return (offset === "<" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0) * (isPercent ? (i < 0 ? recent : percentAnimation).totalDuration() / 100 : 1);
571      }
572
573      if (i < 0) {
574        position in labels || (labels[position] = clippedDuration);
575        return labels[position];
576      }
577
578      offset = parseFloat(position.charAt(i - 1) + position.substr(i + 1));
579
580      if (isPercent && percentAnimation) {
581        offset = offset / 100 * (_isArray(percentAnimation) ? percentAnimation[0] : percentAnimation).totalDuration();
582      }
583
584      return i > 1 ? _parsePosition(animation, position.substr(0, i - 1), percentAnimation) + offset : clippedDuration + offset;
585    }
586
587    return position == null ? clippedDuration : +position;
588  },
589      _createTweenType = function _createTweenType(type, params, timeline) {
590    var isLegacy = _isNumber(params[1]),
591        varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1),
592        vars = params[varsIndex],
593        irVars,
594        parent;
595
596    isLegacy && (vars.duration = params[1]);
597    vars.parent = timeline;
598
599    if (type) {
600      irVars = vars;
601      parent = timeline;
602
603      while (parent && !("immediateRender" in irVars)) {
604        irVars = parent.vars.defaults || {};
605        parent = _isNotFalse(parent.vars.inherit) && parent.parent;
606      }
607
608      vars.immediateRender = _isNotFalse(irVars.immediateRender);
609      type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1];
610    }
611
612    return new Tween(params[0], vars, params[varsIndex + 1]);
613  },
614      _conditionalReturn = function _conditionalReturn(value, func) {
615    return value || value === 0 ? func(value) : func;
616  },
617      _clamp = function _clamp(min, max, value) {
618    return value < min ? min : value > max ? max : value;
619  },
620      getUnit = function getUnit(value, v) {
621    return !_isString(value) || !(v = _unitExp.exec(value)) ? "" : v[1];
622  },
623      clamp = function clamp(min, max, value) {
624    return _conditionalReturn(value, function (v) {
625      return _clamp(min, max, v);
626    });
627  },
628      _slice = [].slice,
629      _isArrayLike = function _isArrayLike(value, nonEmpty) {
630    return value && _isObject(value) && "length" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win;
631  },
632      _flatten = function _flatten(ar, leaveStrings, accumulator) {
633    if (accumulator === void 0) {
634      accumulator = [];
635    }
636
637    return ar.forEach(function (value) {
638      var _accumulator;
639
640      return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value);
641    }) || accumulator;
642  },
643      toArray = function toArray(value, scope, leaveStrings) {
644    return _context && !scope && _context.selector ? _context.selector(value) : _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call((scope || _doc).querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : [];
645  },
646      selector = function selector(value) {
647    value = toArray(value)[0] || _warn("Invalid scope") || {};
648    return function (v) {
649      var el = value.current || value.nativeElement || value;
650      return toArray(v, el.querySelectorAll ? el : el === value ? _warn("Invalid scope") || _doc.createElement("div") : value);
651    };
652  },
653      shuffle = function shuffle(a) {
654    return a.sort(function () {
655      return .5 - Math.random();
656    });
657  },
658      distribute = function distribute(v) {
659    if (_isFunction(v)) {
660      return v;
661    }
662
663    var vars = _isObject(v) ? v : {
664      each: v
665    },
666        ease = _parseEase(vars.ease),
667        from = vars.from || 0,
668        base = parseFloat(vars.base) || 0,
669        cache = {},
670        isDecimal = from > 0 && from < 1,
671        ratios = isNaN(from) || isDecimal,
672        axis = vars.axis,
673        ratioX = from,
674        ratioY = from;
675
676    if (_isString(from)) {
677      ratioX = ratioY = {
678        center: .5,
679        edges: .5,
680        end: 1
681      }[from] || 0;
682    } else if (!isDecimal && ratios) {
683      ratioX = from[0];
684      ratioY = from[1];
685    }
686
687    return function (i, target, a) {
688      var l = (a || vars).length,
689          distances = cache[l],
690          originX,
691          originY,
692          x,
693          y,
694          d,
695          j,
696          max,
697          min,
698          wrapAt;
699
700      if (!distances) {
701        wrapAt = vars.grid === "auto" ? 0 : (vars.grid || [1, _bigNum])[1];
702
703        if (!wrapAt) {
704          max = -_bigNum;
705
706          while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {}
707
708          wrapAt < l && wrapAt--;
709        }
710
711        distances = cache[l] = [];
712        originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt;
713        originY = wrapAt === _bigNum ? 0 : ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0;
714        max = 0;
715        min = _bigNum;
716
717        for (j = 0; j < l; j++) {
718          x = j % wrapAt - originX;
719          y = originY - (j / wrapAt | 0);
720          distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === "y" ? y : x);
721          d > max && (max = d);
722          d < min && (min = d);
723        }
724
725        from === "random" && shuffle(distances);
726        distances.max = max - min;
727        distances.min = min;
728        distances.v = l = (parseFloat(vars.amount) || parseFloat(vars.each) * (wrapAt > l ? l - 1 : !axis ? Math.max(wrapAt, l / wrapAt) : axis === "y" ? l / wrapAt : wrapAt) || 0) * (from === "edges" ? -1 : 1);
729        distances.b = l < 0 ? base - l : base;
730        distances.u = getUnit(vars.amount || vars.each) || 0;
731        ease = ease && l < 0 ? _invertEase(ease) : ease;
732      }
733
734      l = (distances[i] - distances.min) / distances.max || 0;
735      return _roundPrecise(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u;
736    };
737  },
738      _roundModifier = function _roundModifier(v) {
739    var p = Math.pow(10, ((v + "").split(".")[1] || "").length);
740    return function (raw) {
741      var n = _roundPrecise(Math.round(parseFloat(raw) / v) * v * p);
742
743      return (n - n % 1) / p + (_isNumber(raw) ? 0 : getUnit(raw));
744    };
745  },
746      snap = function snap(snapTo, value) {
747    var isArray = _isArray(snapTo),
748        radius,
749        is2D;
750
751    if (!isArray && _isObject(snapTo)) {
752      radius = isArray = snapTo.radius || _bigNum;
753
754      if (snapTo.values) {
755        snapTo = toArray(snapTo.values);
756
757        if (is2D = !_isNumber(snapTo[0])) {
758          radius *= radius;
759        }
760      } else {
761        snapTo = _roundModifier(snapTo.increment);
762      }
763    }
764
765    return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) {
766      is2D = snapTo(raw);
767      return Math.abs(is2D - raw) <= radius ? is2D : raw;
768    } : function (raw) {
769      var x = parseFloat(is2D ? raw.x : raw),
770          y = parseFloat(is2D ? raw.y : 0),
771          min = _bigNum,
772          closest = 0,
773          i = snapTo.length,
774          dx,
775          dy;
776
777      while (i--) {
778        if (is2D) {
779          dx = snapTo[i].x - x;
780          dy = snapTo[i].y - y;
781          dx = dx * dx + dy * dy;
782        } else {
783          dx = Math.abs(snapTo[i] - x);
784        }
785
786        if (dx < min) {
787          min = dx;
788          closest = i;
789        }
790      }
791
792      closest = !radius || min <= radius ? snapTo[closest] : raw;
793      return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw);
794    });
795  },
796      random = function random(min, max, roundingIncrement, returnFunction) {
797    return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () {
798      return _isArray(min) ? min[~~(Math.random() * min.length)] : (roundingIncrement = roundingIncrement || 1e-5) && (returnFunction = roundingIncrement < 1 ? Math.pow(10, (roundingIncrement + "").length - 2) : 1) && Math.floor(Math.round((min - roundingIncrement / 2 + Math.random() * (max - min + roundingIncrement * .99)) / roundingIncrement) * roundingIncrement * returnFunction) / returnFunction;
799    });
800  },
801      pipe = function pipe() {
802    for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) {
803      functions[_key] = arguments[_key];
804    }
805
806    return function (value) {
807      return functions.reduce(function (v, f) {
808        return f(v);
809      }, value);
810    };
811  },
812      unitize = function unitize(func, unit) {
813    return function (value) {
814      return func(parseFloat(value)) + (unit || getUnit(value));
815    };
816  },
817      normalize = function normalize(min, max, value) {
818    return mapRange(min, max, 0, 1, value);
819  },
820      _wrapArray = function _wrapArray(a, wrapper, value) {
821    return _conditionalReturn(value, function (index) {
822      return a[~~wrapper(index)];
823    });
824  },
825      wrap = function wrap(min, max, value) {
826    var range = max - min;
827    return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) {
828      return (range + (value - min) % range) % range + min;
829    });
830  },
831      wrapYoyo = function wrapYoyo(min, max, value) {
832    var range = max - min,
833        total = range * 2;
834    return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) {
835      value = (total + (value - min) % total) % total || 0;
836      return min + (value > range ? total - value : value);
837    });
838  },
839      _replaceRandom = function _replaceRandom(
vendor: 531 bytes, lines 839-855
839value) {
840    var prev = 0,
841        s = "",
842        i,
843        nums,
844        end,
845        isArray;
846
847    while (~(i = value.indexOf("random(", prev))) {
848      end = value.indexOf(")", i);
849      isArray = value.charAt(i + 7) === "[";
850      nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp);
851      s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5);
852      prev = end + 1;
853    }
854
855    return s + value.substr(prev, value.length - prev
vendor: 14,290 bytes, lines 855-1371
855);
856  },
857      mapRange = function mapRange(inMin, inMax, outMin, outMax, value) {
858    var inRange = inMax - inMin,
859        outRange = outMax - outMin;
860    return _conditionalReturn(value, function (value) {
861      return outMin + ((value - inMin) / inRange * outRange || 0);
862    });
863  },
864      interpolate = function interpolate(start, end, progress, mutate) {
865    var func = isNaN(start + end) ? 0 : function (p) {
866      return (1 - p) * start + p * end;
867    };
868
869    if (!func) {
870      var isString = _isString(start),
871          master = {},
872          p,
873          i,
874          interpolators,
875          l,
876          il;
877
878      progress === true && (mutate = 1) && (progress = null);
879
880      if (isString) {
881        start = {
882          p: start
883        };
884        end = {
885          p: end
886        };
887      } else if (_isArray(start) && !_isArray(end)) {
888        interpolators = [];
889        l = start.length;
890        il = l - 2;
891
892        for (i = 1; i < l; i++) {
893          interpolators.push(interpolate(start[i - 1], start[i]));
894        }
895
896        l--;
897
898        func = function func(p) {
899          p *= l;
900          var i = Math.min(il, ~~p);
901          return interpolators[i](p - i);
902        };
903
904        progress = end;
905      } else if (!mutate) {
906        start = _merge(_isArray(start) ? [] : {}, start);
907      }
908
909      if (!interpolators) {
910        for (p in end) {
911          _addPropTween.call(master, start, p, "get", end[p]);
912        }
913
914        func = function func(p) {
915          return _renderPropTweens(p, master) || (isString ? start.p : start);
916        };
917      }
918    }
919
920    return _conditionalReturn(progress, func);
921  },
922      _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) {
923    var labels = timeline.labels,
924        min = _bigNum,
925        p,
926        distance,
927        label;
928
929    for (p in labels) {
930      distance = labels[p] - fromTime;
931
932      if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) {
933        label = p;
934        min = distance;
935      }
936    }
937
938    return label;
939  },
940      _callback = function _callback(animation, type, executeLazyFirst) {
941    var v = animation.vars,
942        callback = v[type],
943        prevContext = _context,
944        context = animation._ctx,
945        params,
946        scope,
947        result;
948
949    if (!callback) {
950      return;
951    }
952
953    params = v[type + "Params"];
954    scope = v.callbackScope || animation;
955    executeLazyFirst && _lazyTweens.length && _lazyRender();
956    context && (_context = context);
957    result = params ? callback.apply(scope, params) : callback.call(scope);
958    _context = prevContext;
959    return result;
960  },
961      _interrupt = function _interrupt(animation) {
962    _removeFromParent(animation);
963
964    animation.scrollTrigger && animation.scrollTrigger.kill(!!_reverting);
965    animation.progress() < 1 && _callback(animation, "onInterrupt");
966    return animation;
967  },
968      _quickTween,
969      _registerPluginQueue = [],
970      _createPlugin = function _createPlugin(config) {
971    if (!config) return;
972    config = !config.name && config["default"] || config;
973
974    if (_windowExists() || config.headless) {
975      var name = config.name,
976          isFunc = _isFunction(config),
977          Plugin = name && !isFunc && config.init ? function () {
978        this._props = [];
979      } : config,
980          instanceDefaults = {
981        init: _emptyFunc,
982        render: _renderPropTweens,
983        add: _addPropTween,
984        kill: _killPropTweensOf,
985        modifier: _addPluginModifier,
986        rawVars: 0
987      },
988          statics = {
989        targetTest: 0,
990        get: 0,
991        getSetter: _getSetter,
992        aliases: {},
993        register: 0
994      };
995
996      _wake();
997
998      if (config !== Plugin) {
999        if (_plugins[name]) {
1000          return;
1001        }
1002
1003        _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics));
1004
1005        _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics)));
1006
1007        _plugins[Plugin.prop = name] = Plugin;
1008
1009        if (config.targetTest) {
1010          _harnessPlugins.push(Plugin);
1011
1012          _reservedProps[name] = 1;
1013        }
1014
1015        name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin";
1016      }
1017
1018      _addGlobal(name, Plugin);
1019
1020      config.register && config.register(gsap, Plugin, PropTween);
1021    } else {
1022      _registerPluginQueue.push(config);
1023    }
1024  },
1025      _255 = 255,
1026      _colorLookup = {
1027    aqua: [0, _255, _255],
1028    lime: [0, _255, 0],
1029    silver: [192, 192, 192],
1030    black: [0, 0, 0],
1031    maroon: [128, 0, 0],
1032    teal: [0, 128, 128],
1033    blue: [0, 0, _255],
1034    navy: [0, 0, 128],
1035    white: [_255, _255, _255],
1036    olive: [128, 128, 0],
1037    yellow: [_255, _255, 0],
1038    orange: [_255, 165, 0],
1039    gray: [128, 128, 128],
1040    purple: [128, 0, 128],
1041    green: [0, 128, 0],
1042    red: [_255, 0, 0],
1043    pink: [_255, 192, 203],
1044    cyan: [0, _255, _255],
1045    transparent: [_255, _255, _255, 0]
1046  },
1047      _hue = function _hue(h, m1, m2) {
1048    h += h < 0 ? 1 : h > 1 ? -1 : 0;
1049    return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < .5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * _255 + .5 | 0;
1050  },
1051      splitColor = function splitColor(v, toHSL, forceAlpha) {
1052    var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0,
1053        r,
1054        g,
1055        b,
1056        h,
1057        s,
1058        l,
1059        max,
1060        min,
1061        d,
1062        wasHSL;
1063
1064    if (!a) {
1065      if (v.substr(-1) === ",") {
1066        v = v.substr(0, v.length - 1);
1067      }
1068
1069      if (_colorLookup[v]) {
1070        a = _colorLookup[v];
1071      } else if (v.charAt(0) === "#") {
1072        if (v.length < 6) {
1073          r = v.charAt(1);
1074          g = v.charAt(2);
1075          b = v.charAt(3);
1076          v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : "");
1077        }
1078
1079        if (v.length === 9) {
1080          a = parseInt(v.substr(1, 6), 16);
1081          return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255];
1082        }
1083
1084        v = parseInt(v.substr(1), 16);
1085        a = [v >> 16, v >> 8 & _255, v & _255];
1086      } else if (v.substr(0, 3) === "hsl") {
1087        a = wasHSL = v.match(_strictNumExp);
1088
1089        if (!toHSL) {
1090          h = +a[0] % 360 / 360;
1091          s = +a[1] / 100;
1092          l = +a[2] / 100;
1093          g = l <= .5 ? l * (s + 1) : l + s - l * s;
1094          r = l * 2 - g;
1095          a.length > 3 && (a[3] *= 1);
1096          a[0] = _hue(h + 1 / 3, r, g);
1097          a[1] = _hue(h, r, g);
1098          a[2] = _hue(h - 1 / 3, r, g);
1099        } else if (~v.indexOf("=")) {
1100          a = v.match(_numExp);
1101          forceAlpha && a.length < 4 && (a[3] = 1);
1102          return a;
1103        }
1104      } else {
1105        a = v.match(_strictNumExp) || _colorLookup.transparent;
1106      }
1107
1108      a = a.map(Number);
1109    }
1110
1111    if (toHSL && !wasHSL) {
1112      r = a[0] / _255;
1113      g = a[1] / _255;
1114      b = a[2] / _255;
1115      max = Math.max(r, g, b);
1116      min = Math.min(r, g, b);
1117      l = (max + min) / 2;
1118
1119      if (max === min) {
1120        h = s = 0;
1121      } else {
1122        d = max - min;
1123        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1124        h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
1125        h *= 60;
1126      }
1127
1128      a[0] = ~~(h + .5);
1129      a[1] = ~~(s * 100 + .5);
1130      a[2] = ~~(l * 100 + .5);
1131    }
1132
1133    forceAlpha && a.length < 4 && (a[3] = 1);
1134    return a;
1135  },
1136      _colorOrderData = function _colorOrderData(v) {
1137    var values = [],
1138        c = [],
1139        i = -1;
1140    v.split(_colorExp).forEach(function (v) {
1141      var a = v.match(_numWithUnitExp) || [];
1142      values.push.apply(values, a);
1143      c.push(i += a.length + 1);
1144    });
1145    values.c = c;
1146    return values;
1147  },
1148      _formatColors = function _formatColors(s, toHSL, orderMatchData) {
1149    var result = "",
1150        colors = (s + result).match(_colorExp),
1151        type = toHSL ? "hsla(" : "rgba(",
1152        i = 0,
1153        c,
1154        shell,
1155        d,
1156        l;
1157
1158    if (!colors) {
1159      return s;
1160    }
1161
1162    colors = colors.map(function (color) {
1163      return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")";
1164    });
1165
1166    if (orderMatchData) {
1167      d = _colorOrderData(s);
1168      c = orderMatchData.c;
1169
1170      if (c.join(result) !== d.c.join(result)) {
1171        shell = s.replace(_colorExp, "1").split(_numWithUnitExp);
1172        l = shell.length - 1;
1173
1174        for (; i < l; i++) {
1175          result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift());
1176        }
1177      }
1178    }
1179
1180    if (!shell) {
1181      shell = s.split(_colorExp);
1182      l = shell.length - 1;
1183
1184      for (; i < l; i++) {
1185        result += shell[i] + colors[i];
1186      }
1187    }
1188
1189    return result + shell[l];
1190  },
1191      _colorExp = function () {
1192    var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b",
1193        p;
1194
1195    for (p in _colorLookup) {
1196      s += "|" + p + "\\b";
1197    }
1198
1199    return new RegExp(s + ")", "gi");
1200  }(),
1201      _hslExp = /hsl[a]?\(/,
1202      _colorStringFilter = function _colorStringFilter(a) {
1203    var combined = a.join(" "),
1204        toHSL;
1205    _colorExp.lastIndex = 0;
1206
1207    if (_colorExp.test(combined)) {
1208      toHSL = _hslExp.test(combined);
1209      a[1] = _formatColors(a[1], toHSL);
1210      a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1]));
1211      return true;
1212    }
1213  },
1214      _tickerActive,
1215      _ticker = function () {
1216    var _getTime = Date.now,
1217        _lagThreshold = 500,
1218        _adjustedLag = 33,
1219        _startTime = _getTime(),
1220        _lastUpdate = _startTime,
1221        _gap = 1000 / 240,
1222        _nextTime = _gap,
1223        _listeners = [],
1224        _id,
1225        _req,
1226        _raf,
1227        _self,
1228        _delta,
1229        _i,
1230        _tick = function _tick(v) {
1231      var elapsed = _getTime() - _lastUpdate,
1232          manual = v === true,
1233          overlap,
1234          dispatch,
1235          time,
1236          frame;
1237
1238      (elapsed > _lagThreshold || elapsed < 0) && (_startTime += elapsed - _adjustedLag);
1239      _lastUpdate += elapsed;
1240      time = _lastUpdate - _startTime;
1241      overlap = time - _nextTime;
1242
1243      if (overlap > 0 || manual) {
1244        frame = ++_self.frame;
1245        _delta = time - _self.time * 1000;
1246        _self.time = time = time / 1000;
1247        _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap);
1248        dispatch = 1;
1249      }
1250
1251      manual || (_id = _req(_tick));
1252
1253      if (dispatch) {
1254        for (_i = 0; _i < _listeners.length; _i++) {
1255          _listeners[_i](time, _delta, frame, v);
1256        }
1257      }
1258    };
1259
1260    _self = {
1261      time: 0,
1262      frame: 0,
1263      tick: function tick() {
1264        _tick(true);
1265      },
1266      deltaRatio: function deltaRatio(fps) {
1267        return _delta / (1000 / (fps || 60));
1268      },
1269      wake: function wake() {
1270        if (_coreReady) {
1271          if (!_coreInitted && _windowExists()) {
1272            _win = _coreInitted = window;
1273            _doc = _win.document || {};
1274            _globals.gsap = gsap;
1275            (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version);
1276
1277            _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {});
1278
1279            _registerPluginQueue.forEach(_createPlugin);
1280          }
1281
1282          _raf = typeof requestAnimationFrame !== "undefined" && requestAnimationFrame;
1283          _id && _self.sleep();
1284
1285          _req = _raf || function (f) {
1286            return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0);
1287          };
1288
1289          _tickerActive = 1;
1290
1291          _tick(2);
1292        }
1293      },
1294      sleep: function sleep() {
1295        (_raf ? cancelAnimationFrame : clearTimeout)(_id);
1296        _tickerActive = 0;
1297        _req = _emptyFunc;
1298      },
1299      lagSmoothing: function lagSmoothing(threshold, adjustedLag) {
1300        _lagThreshold = threshold || Infinity;
1301        _adjustedLag = Math.min(adjustedLag || 33, _lagThreshold);
1302      },
1303      fps: function fps(_fps) {
1304        _gap = 1000 / (_fps || 240);
1305        _nextTime = _self.time * 1000 + _gap;
1306      },
1307      add: function add(callback, once, prioritize) {
1308        var func = once ? function (t, d, f, v) {
1309          callback(t, d, f, v);
1310
1311          _self.remove(func);
1312        } : callback;
1313
1314        _self.remove(callback);
1315
1316        _listeners[prioritize ? "unshift" : "push"](func);
1317
1318        _wake();
1319
1320        return func;
1321      },
1322      remove: function remove(callback, i) {
1323        ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--;
1324      },
1325      _listeners: _listeners
1326    };
1327    return _self;
1328  }(),
1329      _wake = function _wake() {
1330    return !_tickerActive && _ticker.wake();
1331  },
1332      _easeMap = {},
1333      _customEaseExp = /^[\d.\-M][\d.\-,\s]/,
1334      _quotesExp = /["']/g,
1335      _parseObjectInString = function _parseObjectInString(value) {
1336    var obj = {},
1337        split = value.substr(1, value.length - 3).split(":"),
1338        key = split[0],
1339        i = 1,
1340        l = split.length,
1341        index,
1342        val,
1343        parsedVal;
1344
1345    for (; i < l; i++) {
1346      val = split[i];
1347      index = i !== l - 1 ? val.lastIndexOf(",") : val.length;
1348      parsedVal = val.substr(0, index);
1349      obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal;
1350      key = val.substr(index + 1).trim();
1351    }
1352
1353    return obj;
1354  },
1355      _valueInParentheses = function _valueInParentheses(value) {
1356    var open = value.indexOf("(") + 1,
1357        close = value.indexOf(")"),
1358        nested = value.indexOf("(", open);
1359    return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close);
1360  },
1361      _configEaseFromString = function _configEaseFromString(name) {
1362    var split = (name + "").split("("),
1363        ease = _easeMap[split[0]];
1364    return ease && split.length > 1 && ease.config ? ease.config.apply(null, ~name.indexOf("{") ? [_parseObjectInString(split[1])] : _valueInParentheses(name).split(",").map(_numericIfPossible)) : _easeMap._CE && _customEaseExp.test(name) ? _easeMap._CE("", name) : ease;
1365  },
1366      _invertEase = function _invertEase(ease) {
1367    return function (p) {
1368      return 1 - ease(1 - p);
1369    };
1370  },
1371      _p
1371ropagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) {
1372    var child = timeline._first,
1373        ease;
1374
1375    while (child) {
1376      if (child instanceof Timeline) {
1377        _propagateYoyoEase(child, isYoyo);
1378      } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) {
1379        if (child.timeline) {
1380          _propagateYoyoEase(child.timeline, isYoyo);
1381        } else {
1382          ease = child._ease;
1383          child._ease = child._yEase;
1384          child._yEase = ease;
1385          child._yoyo = isYoyo;
1386        }
1387      }
1388
1389      child = child._next;
1390    }
vendor: 3,445 bytes, lines 1390-1501
1390
1391  },
1392      _parseEase = function _parseEase(ease, defaultEase) {
1393    return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase;
1394  },
1395      _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) {
1396    if (easeOut === void 0) {
1397      easeOut = function easeOut(p) {
1398        return 1 - easeIn(1 - p);
1399      };
1400    }
1401
1402    if (easeInOut === void 0) {
1403      easeInOut = function easeInOut(p) {
1404        return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2;
1405      };
1406    }
1407
1408    var ease = {
1409      easeIn: easeIn,
1410      easeOut: easeOut,
1411      easeInOut: easeInOut
1412    },
1413        lowercaseName;
1414
1415    _forEachName(names, function (name) {
1416      _easeMap[name] = _globals[name] = ease;
1417      _easeMap[lowercaseName = name.toLowerCase()] = easeOut;
1418
1419      for (var p in ease) {
1420        _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p];
1421      }
1422    });
1423
1424    return ease;
1425  },
1426      _easeInOutFromOut = function _easeInOutFromOut(easeOut) {
1427    return function (p) {
1428      return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2;
1429    };
1430  },
1431      _configElastic = function _configElastic(type, amplitude, period) {
1432    var p1 = amplitude >= 1 ? amplitude : 1,
1433        p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1),
1434        p3 = p2 / _2PI * (Math.asin(1 / p1) || 0),
1435        easeOut = function easeOut(p) {
1436      return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1;
1437    },
1438        ease = type === "out" ? easeOut : type === "in" ? function (p) {
1439      return 1 - easeOut(1 - p);
1440    } : _easeInOutFromOut(easeOut);
1441
1442    p2 = _2PI / p2;
1443
1444    ease.config = function (amplitude, period) {
1445      return _configElastic(type, amplitude, period);
1446    };
1447
1448    return ease;
1449  },
1450      _configBack = function _configBack(type, overshoot) {
1451    if (overshoot === void 0) {
1452      overshoot = 1.70158;
1453    }
1454
1455    var easeOut = function easeOut(p) {
1456      return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0;
1457    },
1458        ease = type === "out" ? easeOut : type === "in" ? function (p) {
1459      return 1 - easeOut(1 - p);
1460    } : _easeInOutFromOut(easeOut);
1461
1462    ease.config = function (overshoot) {
1463      return _configBack(type, overshoot);
1464    };
1465
1466    return ease;
1467  };
1468
1469  _forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) {
1470    var power = i < 5 ? i + 1 : i;
1471
1472    _insertEase(name + ",Power" + (power - 1), i ? function (p) {
1473      return Math.pow(p, power);
1474    } : function (p) {
1475      return p;
1476    }, function (p) {
1477      return 1 - Math.pow(1 - p, power);
1478    }, function (p) {
1479      return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2;
1480    });
1481  });
1482
1483  _easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn;
1484
1485  _insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic());
1486
1487  (function (n, c) {
1488    var n1 = 1 / c,
1489        n2 = 2 * n1,
1490        n3 = 2.5 * n1,
1491        easeOut = function easeOut(p) {
1492      return p < n1 ? n * p * p : p < n2 ? n * Math.pow(p - 1.5 / c, 2) + .75 : p < n3 ? n * (p -= 2.25 / c) * p + .9375 : n * Math.pow(p - 2.625 / c, 2) + .984375;
1493    };
1494
1495    _insertEase("Bounce", function (p) {
1496      return 1 - easeOut(1 - p);
1497    }, easeOut);
1498  })(7.5625, 2.75);
1499
1500  _insertEase("Expo", function (p) {
1501    return 
vendor: 18,509 bytes, lines 1501-2076
1501p ? Math.pow(2, 10 * (p - 1)) : 0;
1502  });
1503
1504  _insertEase("Circ", function (p) {
1505    return -(_sqrt(1 - p * p) - 1);
1506  });
1507
1508  _insertEase("Sine", function (p) {
1509    return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1;
1510  });
1511
1512  _insertEase("Back", _configBack("in"), _configBack("out"), _configBack());
1513
1514  _easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = {
1515    config: function config(steps, immediateStart) {
1516      if (steps === void 0) {
1517        steps = 1;
1518      }
1519
1520      var p1 = 1 / steps,
1521          p2 = steps + (immediateStart ? 0 : 1),
1522          p3 = immediateStart ? 1 : 0,
1523          max = 1 - _tinyNum;
1524      return function (p) {
1525        return ((p2 * _clamp(0, max, p) | 0) + p3) * p1;
1526      };
1527    }
1528  };
1529  _defaults.ease = _easeMap["quad.out"];
1530
1531  _forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) {
1532    return _callbackNames += name + "," + name + "Params,";
1533  });
1534
1535  var GSCache = function GSCache(target, harness) {
1536    this.id = _gsID++;
1537    target._gsap = this;
1538    this.target = target;
1539    this.harness = harness;
1540    this.get = harness ? harness.get : _getProperty;
1541    this.set = harness ? harness.getSetter : _getSetter;
1542  };
1543  var Animation = function () {
1544    function Animation(vars) {
1545      this.vars = vars;
1546      this._delay = +vars.delay || 0;
1547
1548      if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) {
1549        this._rDelay = vars.repeatDelay || 0;
1550        this._yoyo = !!vars.yoyo || !!vars.yoyoEase;
1551      }
1552
1553      this._ts = 1;
1554
1555      _setDuration(this, +vars.duration, 1, 1);
1556
1557      this.data = vars.data;
1558
1559      if (_context) {
1560        this._ctx = _context;
1561
1562        _context.data.push(this);
1563      }
1564
1565      _tickerActive || _ticker.wake();
1566    }
1567
1568    var _proto = Animation.prototype;
1569
1570    _proto.delay = function delay(value) {
1571      if (value || value === 0) {
1572        this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay);
1573        this._delay = value;
1574        return this;
1575      }
1576
1577      return this._delay;
1578    };
1579
1580    _proto.duration = function duration(value) {
1581      return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur;
1582    };
1583
1584    _proto.totalDuration = function totalDuration(value) {
1585      if (!arguments.length) {
1586        return this._tDur;
1587      }
1588
1589      this._dirty = 0;
1590      return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1));
1591    };
1592
1593    _proto.totalTime = function totalTime(_totalTime, suppressEvents) {
1594      _wake();
1595
1596      if (!arguments.length) {
1597        return this._tTime;
1598      }
1599
1600      var parent = this._dp;
1601
1602      if (parent && parent.smoothChildTiming && this._ts) {
1603        _alignPlayhead(this, _totalTime);
1604
1605        !parent._dp || parent.parent || _postAddChecks(parent, this);
1606
1607        while (parent && parent.parent) {
1608          if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) {
1609            parent.totalTime(parent._tTime, true);
1610          }
1611
1612          parent = parent.parent;
1613        }
1614
1615        if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) {
1616          _addToTimeline(this._dp, this, this._start - this._delay);
1617        }
1618      }
1619
1620      if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) {
1621        this._ts || (this._pTime = _totalTime);
1622
1623        _lazySafeRender(this, _totalTime, suppressEvents);
1624      }
1625
1626      return this;
1627    };
1628
1629    _proto.time = function time(value, suppressEvents) {
1630      return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % (this._dur + this._rDelay) || (value ? this._dur : 0), suppressEvents) : this._time;
1631    };
1632
1633    _proto.totalProgress = function totalProgress(value, suppressEvents) {
1634      return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.rawTime() > 0 ? 1 : 0;
1635    };
1636
1637    _proto.progress = function progress(value, suppressEvents) {
1638      return arguments.length ? this.totalTime(this.duration() * (this._yoyo && !(this.iteration() & 1) ? 1 - value : value) + _elapsedCycleDuration(this), suppressEvents) : this.duration() ? Math.min(1, this._time / this._dur) : this.rawTime() > 0 ? 1 : 0;
1639    };
1640
1641    _proto.iteration = function iteration(value, suppressEvents) {
1642      var cycleDuration = this.duration() + this._rDelay;
1643
1644      return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1;
1645    };
1646
1647    _proto.timeScale = function timeScale(value, suppressEvents) {
1648      if (!arguments.length) {
1649        return this._rts === -_tinyNum ? 0 : this._rts;
1650      }
1651
1652      if (this._rts === value) {
1653        return this;
1654      }
1655
1656      var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime;
1657      this._rts = +value || 0;
1658      this._ts = this._ps || value === -_tinyNum ? 0 : this._rts;
1659      this.totalTime(_clamp(-Math.abs(this._delay), this._tDur, tTime), suppressEvents !== false);
1660
1661      _setEnd(this);
1662
1663      return _recacheAncestors(this);
1664    };
1665
1666    _proto.paused = function paused(value) {
1667      if (!arguments.length) {
1668        return this._ps;
1669      }
1670
1671      if (this._ps !== value) {
1672        this._ps = value;
1673
1674        if (value) {
1675          this._pTime = this._tTime || Math.max(-this._delay, this.rawTime());
1676          this._ts = this._act = 0;
1677        } else {
1678          _wake();
1679
1680          this._ts = this._rts;
1681          this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && Math.abs(this._zTime) !== _tinyNum && (this._tTime -= _tinyNum));
1682        }
1683      }
1684
1685      return this;
1686    };
1687
1688    _proto.startTime = function startTime(value) {
1689      if (arguments.length) {
1690        this._start = value;
1691        var parent = this.parent || this._dp;
1692        parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay);
1693        return this;
1694      }
1695
1696      return this._start;
1697    };
1698
1699    _proto.endTime = function endTime(includeRepeats) {
1700      return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1);
1701    };
1702
1703    _proto.rawTime = function rawTime(wrapRepeats) {
1704      var parent = this.parent || this._dp;
1705      return !parent ? this._tTime : wrapRepeats && (!this._ts || this._repeat && this._time && this.totalProgress() < 1) ? this._tTime % (this._dur + this._rDelay) : !this._ts ? this._tTime : _parentToChildTotalTime(parent.rawTime(wrapRepeats), this);
1706    };
1707
1708    _proto.revert = function revert(config) {
1709      if (config === void 0) {
1710        config = _revertConfig;
1711      }
1712
1713      var prevIsReverting = _reverting;
1714      _reverting = config;
1715
1716      if (this._initted || this._startAt) {
1717        this.timeline && this.timeline.revert(config);
1718        this.totalTime(-0.01, config.suppressEvents);
1719      }
1720
1721      this.data !== "nested" && config.kill !== false && this.kill();
1722      _reverting = prevIsReverting;
1723      return this;
1724    };
1725
1726    _proto.globalTime = function globalTime(rawTime) {
1727      var animation = this,
1728          time = arguments.length ? rawTime : animation.rawTime();
1729
1730      while (animation) {
1731        time = animation._start + time / (Math.abs(animation._ts) || 1);
1732        animation = animation._dp;
1733      }
1734
1735      return !this.parent && this._sat ? this._sat.globalTime(rawTime) : time;
1736    };
1737
1738    _proto.repeat = function repeat(value) {
1739      if (arguments.length) {
1740        this._repeat = value === Infinity ? -2 : value;
1741        return _onUpdateTotalDuration(this);
1742      }
1743
1744      return this._repeat === -2 ? Infinity : this._repeat;
1745    };
1746
1747    _proto.repeatDelay = function repeatDelay(value) {
1748      if (arguments.length) {
1749        var time = this._time;
1750        this._rDelay = value;
1751
1752        _onUpdateTotalDuration(this);
1753
1754        return time ? this.time(time) : this;
1755      }
1756
1757      return this._rDelay;
1758    };
1759
1760    _proto.yoyo = function yoyo(value) {
1761      if (arguments.length) {
1762        this._yoyo = value;
1763        return this;
1764      }
1765
1766      return this._yoyo;
1767    };
1768
1769    _proto.seek = function seek(position, suppressEvents) {
1770      return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents));
1771    };
1772
1773    _proto.restart = function restart(includeDelay, suppressEvents) {
1774      return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents));
1775    };
1776
1777    _proto.play = function play(from, suppressEvents) {
1778      from != null && this.seek(from, suppressEvents);
1779      return this.reversed(false).paused(false);
1780    };
1781
1782    _proto.reverse = function reverse(from, suppressEvents) {
1783      from != null && this.seek(from || this.totalDuration(), suppressEvents);
1784      return this.reversed(true).paused(false);
1785    };
1786
1787    _proto.pause = function pause(atTime, suppressEvents) {
1788      atTime != null && this.seek(atTime, suppressEvents);
1789      return this.paused(true);
1790    };
1791
1792    _proto.resume = function resume() {
1793      return this.paused(false);
1794    };
1795
1796    _proto.reversed = function reversed(value) {
1797      if (arguments.length) {
1798        !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0));
1799        return this;
1800      }
1801
1802      return this._rts < 0;
1803    };
1804
1805    _proto.invalidate = function invalidate() {
1806      this._initted = this._act = 0;
1807      this._zTime = -_tinyNum;
1808      return this;
1809    };
1810
1811    _proto.isActive = function isActive() {
1812      var parent = this.parent || this._dp,
1813          start = this._start,
1814          rawTime;
1815      return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum);
1816    };
1817
1818    _proto.eventCallback = function eventCallback(type, callback, params) {
1819      var vars = this.vars;
1820
1821      if (arguments.length > 1) {
1822        if (!callback) {
1823          delete vars[type];
1824        } else {
1825          vars[type] = callback;
1826          params && (vars[type + "Params"] = params);
1827          type === "onUpdate" && (this._onUpdate = callback);
1828        }
1829
1830        return this;
1831      }
1832
1833      return vars[type];
1834    };
1835
1836    _proto.then = function then(onFulfilled) {
1837      var self = this;
1838      return new Promise(function (resolve) {
1839        var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough,
1840            _resolve = function _resolve() {
1841          var _then = self.then;
1842          self.then = null;
1843          _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then);
1844          resolve(f);
1845          self.then = _then;
1846        };
1847
1848        if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) {
1849          _resolve();
1850        } else {
1851          self._prom = _resolve;
1852        }
1853      });
1854    };
1855
1856    _proto.kill = function kill() {
1857      _interrupt(this);
1858    };
1859
1860    return Animation;
1861  }();
1862
1863  _setDefaults(Animation.prototype, {
1864    _time: 0,
1865    _start: 0,
1866    _end: 0,
1867    _tTime: 0,
1868    _tDur: 0,
1869    _dirty: 0,
1870    _repeat: 0,
1871    _yoyo: false,
1872    parent: null,
1873    _initted: false,
1874    _rDelay: 0,
1875    _ts: 1,
1876    _dp: 0,
1877    ratio: 0,
1878    _zTime: -_tinyNum,
1879    _prom: 0,
1880    _ps: false,
1881    _rts: 1
1882  });
1883
1884  var Timeline = function (_Animation) {
1885    _inheritsLoose(Timeline, _Animation);
1886
1887    function Timeline(vars, position) {
1888      var _this;
1889
1890      if (vars === void 0) {
1891        vars = {};
1892      }
1893
1894      _this = _Animation.call(this, vars) || this;
1895      _this.labels = {};
1896      _this.smoothChildTiming = !!vars.smoothChildTiming;
1897      _this.autoRemoveChildren = !!vars.autoRemoveChildren;
1898      _this._sort = _isNotFalse(vars.sortChildren);
1899      _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position);
1900      vars.reversed && _this.reverse();
1901      vars.paused && _this.paused(true);
1902      vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger);
1903      return _this;
1904    }
1905
1906    var _proto2 = Timeline.prototype;
1907
1908    _proto2.to = function to(targets, vars, position) {
1909      _createTweenType(0, arguments, this);
1910
1911      return this;
1912    };
1913
1914    _proto2.from = function from(targets, vars, position) {
1915      _createTweenType(1, arguments, this);
1916
1917      return this;
1918    };
1919
1920    _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) {
1921      _createTweenType(2, arguments, this);
1922
1923      return this;
1924    };
1925
1926    _proto2.set = function set(targets, vars, position) {
1927      vars.duration = 0;
1928      vars.parent = this;
1929      _inheritDefaults(vars).repeatDelay || (vars.repeat = 0);
1930      vars.immediateRender = !!vars.immediateRender;
1931      new Tween(targets, vars, _parsePosition(this, position), 1);
1932      return this;
1933    };
1934
1935    _proto2.call = function call(callback, params, position) {
1936      return _addToTimeline(this, Tween.delayedCall(0, callback, params), position);
1937    };
1938
1939    _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {
1940      vars.duration = duration;
1941      vars.stagger = vars.stagger || stagger;
1942      vars.onComplete = onCompleteAll;
1943      vars.onCompleteParams = onCompleteAllParams;
1944      vars.parent = this;
1945      new Tween(targets, vars, _parsePosition(this, position));
1946      return this;
1947    };
1948
1949    _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {
1950      vars.runBackwards = 1;
1951      _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender);
1952      return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams);
1953    };
1954
1955    _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) {
1956      toVars.startAt = fromVars;
1957      _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender);
1958      return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams);
1959    };
1960
1961    _proto2.render = function render(totalTime, suppressEvents, force) {
1962      var prevTime = this._time,
1963          tDur = this._dirty ? this.totalDuration() : this._tDur,
1964          dur = this._dur,
1965          tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime),
1966          crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur),
1967          time,
1968          child,
1969          next,
1970          iteration,
1971          cycleDuration,
1972          prevPaused,
1973          pauseTween,
1974          timeScale,
1975          prevStart,
1976          prevIteration,
1977          yoyo,
1978          isYoyo;
1979      this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur);
1980
1981      if (tTime !== this._tTime || force || crossingStart) {
1982        if (prevTime !== this._time && dur) {
1983          tTime += this._time - prevTime;
1984          totalTime += this._time - prevTime;
1985        }
1986
1987        time = tTime;
1988        prevStart = this._start;
1989        timeScale = this._ts;
1990        prevPaused = !timeScale;
1991
1992        if (crossingStart) {
1993          dur || (prevTime = this._zTime);
1994          (totalTime || !suppressEvents) && (this._zTime = totalTime);
1995        }
1996
1997        if (this._repeat) {
1998          yoyo = this._yoyo;
1999          cycleDuration = dur + this._rDelay;
2000
2001          if (this._repeat < -1 && totalTime < 0) {
2002            return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);
2003          }
2004
2005          time = _roundPrecise(tTime % cycleDuration);
2006
2007          if (tTime === tDur) {
2008            iteration = this._repeat;
2009            time = dur;
2010          } else {
2011            iteration = ~~(tTime / cycleDuration);
2012
2013            if (iteration && iteration === tTime / cycleDuration) {
2014              time = dur;
2015              iteration--;
2016            }
2017
2018            time > dur && (time = dur);
2019          }
2020
2021          prevIteration = _animationCycle(this._tTime, cycleDuration);
2022          !prevTime && this._tTime && prevIteration !== iteration && this._tTime - prevIteration * cycleDuration - this._dur <= 0 && (prevIteration = iteration);
2023
2024          if (yoyo && iteration & 1) {
2025            time = dur - time;
2026            isYoyo = 1;
2027          }
2028
2029          if (iteration !== prevIteration && !this._lock) {
2030            var rewinding = yoyo && prevIteration & 1,
2031                doesWrap = rewinding === (yoyo && iteration & 1);
2032            iteration < prevIteration && (rewinding = !rewinding);
2033            prevTime = rewinding ? 0 : tTime % dur ? dur : tTime;
2034            this._lock = 1;
2035            this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0;
2036            this._tTime = tTime;
2037            !suppressEvents && this.parent && _callback(this, "onRepeat");
2038            this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1);
2039
2040            if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) {
2041              return this;
2042            }
2043
2044            dur = this._dur;
2045            tDur = this._tDur;
2046
2047            if (doesWrap) {
2048              this._lock = 2;
2049              prevTime = rewinding ? dur : -0.0001;
2050              this.render(prevTime, true);
2051              this.vars.repeatRefresh && !isYoyo && this.invalidate();
2052            }
2053
2054            this._lock = 0;
2055
2056            if (!this._ts && !prevPaused) {
2057              return this;
2058            }
2059
2060            _propagateYoyoEase(this, isYoyo);
2061          }
2062        }
2063
2064        if (this._hasPause && !this._forcing && this._lock < 2) {
2065          pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time));
2066
2067          if (pauseTween) {
2068            tTime -= time - (time = pauseTween._start);
2069          }
2070        }
2071
2072        this._tTime = tTime;
2073        this._time = time;
2074        this._act = !timeScale;
2075
2076        if (!this._initted) {
vendor: 30,026 bytes, lines 2077-3039
2077          this._onUpdate = this.vars.onUpdate;
2078          this._initted = 1;
2079          this._zTime = totalTime;
2080          prevTime = 0;
2081        }
2082
2083        if (!prevTime && time && !suppressEvents && !iteration) {
2084          _callback(this, "onStart");
2085
2086          if (this._tTime !== tTime) {
2087            return this;
2088          }
2089        }
2090
2091        if (time >= prevTime && totalTime >= 0) {
2092          child = this._first;
2093
2094          while (child) {
2095            next = child._next;
2096
2097            if ((child._act || time >= child._start) && child._ts && pauseTween !== child) {
2098              if (child.parent !== this) {
2099                return this.render(totalTime, suppressEvents, force);
2100              }
2101
2102              child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force);
2103
2104              if (time !== this._time || !this._ts && !prevPaused) {
2105                pauseTween = 0;
2106                next && (tTime += this._zTime = -_tinyNum);
2107                break;
2108              }
2109            }
2110
2111            child = next;
2112          }
2113        } else {
2114          child = this._last;
2115          var adjustedTime = totalTime < 0 ? totalTime : time;
2116
2117          while (child) {
2118            next = child._prev;
2119
2120            if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) {
2121              if (child.parent !== this) {
2122                return this.render(totalTime, suppressEvents, force);
2123              }
2124
2125              child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force || _reverting && (child._initted || child._startAt));
2126
2127              if (time !== this._time || !this._ts && !prevPaused) {
2128                pauseTween = 0;
2129                next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum);
2130                break;
2131              }
2132            }
2133
2134            child = next;
2135          }
2136        }
2137
2138        if (pauseTween && !suppressEvents) {
2139          this.pause();
2140          pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1;
2141
2142          if (this._ts) {
2143            this._start = prevStart;
2144
2145            _setEnd(this);
2146
2147            return this.render(totalTime, suppressEvents, force);
2148          }
2149        }
2150
2151        this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true);
2152        if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) {
2153          (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1);
2154
2155          if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) {
2156            _callback(this, tTime === tDur && totalTime >= 0 ? "onComplete" : "onReverseComplete", true);
2157
2158            this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();
2159          }
2160        }
2161      }
2162
2163      return this;
2164    };
2165
2166    _proto2.add = function add(child, position) {
2167      var _this2 = this;
2168
2169      _isNumber(position) || (position = _parsePosition(this, position, child));
2170
2171      if (!(child instanceof Animation)) {
2172        if (_isArray(child)) {
2173          child.forEach(function (obj) {
2174            return _this2.add(obj, position);
2175          });
2176          return this;
2177        }
2178
2179        if (_isString(child)) {
2180          return this.addLabel(child, position);
2181        }
2182
2183        if (_isFunction(child)) {
2184          child = Tween.delayedCall(0, child);
2185        } else {
2186          return this;
2187        }
2188      }
2189
2190      return this !== child ? _addToTimeline(this, child, position) : this;
2191    };
2192
2193    _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) {
2194      if (nested === void 0) {
2195        nested = true;
2196      }
2197
2198      if (tweens === void 0) {
2199        tweens = true;
2200      }
2201
2202      if (timelines === void 0) {
2203        timelines = true;
2204      }
2205
2206      if (ignoreBeforeTime === void 0) {
2207        ignoreBeforeTime = -_bigNum;
2208      }
2209
2210      var a = [],
2211          child = this._first;
2212
2213      while (child) {
2214        if (child._start >= ignoreBeforeTime) {
2215          if (child instanceof Tween) {
2216            tweens && a.push(child);
2217          } else {
2218            timelines && a.push(child);
2219            nested && a.push.apply(a, child.getChildren(true, tweens, timelines));
2220          }
2221        }
2222
2223        child = child._next;
2224      }
2225
2226      return a;
2227    };
2228
2229    _proto2.getById = function getById(id) {
2230      var animations = this.getChildren(1, 1, 1),
2231          i = animations.length;
2232
2233      while (i--) {
2234        if (animations[i].vars.id === id) {
2235          return animations[i];
2236        }
2237      }
2238    };
2239
2240    _proto2.remove = function remove(child) {
2241      if (_isString(child)) {
2242        return this.removeLabel(child);
2243      }
2244
2245      if (_isFunction(child)) {
2246        return this.killTweensOf(child);
2247      }
2248
2249      _removeLinkedListItem(this, child);
2250
2251      if (child === this._recent) {
2252        this._recent = this._last;
2253      }
2254
2255      return _uncache(this);
2256    };
2257
2258    _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) {
2259      if (!arguments.length) {
2260        return this._tTime;
2261      }
2262
2263      this._forcing = 1;
2264
2265      if (!this._dp && this._ts) {
2266        this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts));
2267      }
2268
2269      _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents);
2270
2271      this._forcing = 0;
2272      return this;
2273    };
2274
2275    _proto2.addLabel = function addLabel(label, position) {
2276      this.labels[label] = _parsePosition(this, position);
2277      return this;
2278    };
2279
2280    _proto2.removeLabel = function removeLabel(label) {
2281      delete this.labels[label];
2282      return this;
2283    };
2284
2285    _proto2.addPause = function addPause(position, callback, params) {
2286      var t = Tween.delayedCall(0, callback || _emptyFunc, params);
2287      t.data = "isPause";
2288      this._hasPause = 1;
2289      return _addToTimeline(this, t, _parsePosition(this, position));
2290    };
2291
2292    _proto2.removePause = function removePause(position) {
2293      var child = this._first;
2294      position = _parsePosition(this, position);
2295
2296      while (child) {
2297        if (child._start === position && child.data === "isPause") {
2298          _removeFromParent(child);
2299        }
2300
2301        child = child._next;
2302      }
2303    };
2304
2305    _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) {
2306      var tweens = this.getTweensOf(targets, onlyActive),
2307          i = tweens.length;
2308
2309      while (i--) {
2310        _overwritingTween !== tweens[i] && tweens[i].kill(targets, props);
2311      }
2312
2313      return this;
2314    };
2315
2316    _proto2.getTweensOf = function getTweensOf(targets, onlyActive) {
2317      var a = [],
2318          parsedTargets = toArray(targets),
2319          child = this._first,
2320          isGlobalTime = _isNumber(onlyActive),
2321          children;
2322
2323      while (child) {
2324        if (child instanceof Tween) {
2325          if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) {
2326            a.push(child);
2327          }
2328        } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) {
2329          a.push.apply(a, children);
2330        }
2331
2332        child = child._next;
2333      }
2334
2335      return a;
2336    };
2337
2338    _proto2.tweenTo = function tweenTo(position, vars) {
2339      vars = vars || {};
2340
2341      var tl = this,
2342          endTime = _parsePosition(tl, position),
2343          _vars = vars,
2344          startAt = _vars.startAt,
2345          _onStart = _vars.onStart,
2346          onStartParams = _vars.onStartParams,
2347          immediateRender = _vars.immediateRender,
2348          initted,
2349          tween = Tween.to(tl, _setDefaults({
2350        ease: vars.ease || "none",
2351        lazy: false,
2352        immediateRender: false,
2353        time: endTime,
2354        overwrite: "auto",
2355        duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum,
2356        onStart: function onStart() {
2357          tl.pause();
2358
2359          if (!initted) {
2360            var duration = vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale());
2361            tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true);
2362            initted = 1;
2363          }
2364
2365          _onStart && _onStart.apply(tween, onStartParams || []);
2366        }
2367      }, vars));
2368
2369      return immediateRender ? tween.render(0) : tween;
2370    };
2371
2372    _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) {
2373      return this.tweenTo(toPosition, _setDefaults({
2374        startAt: {
2375          time: _parsePosition(this, fromPosition)
2376        }
2377      }, vars));
2378    };
2379
2380    _proto2.recent = function recent() {
2381      return this._recent;
2382    };
2383
2384    _proto2.nextLabel = function nextLabel(afterTime) {
2385      if (afterTime === void 0) {
2386        afterTime = this._time;
2387      }
2388
2389      return _getLabelInDirection(this, _parsePosition(this, afterTime));
2390    };
2391
2392    _proto2.previousLabel = function previousLabel(beforeTime) {
2393      if (beforeTime === void 0) {
2394        beforeTime = this._time;
2395      }
2396
2397      return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1);
2398    };
2399
2400    _proto2.currentLabel = function currentLabel(value) {
2401      return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum);
2402    };
2403
2404    _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) {
2405      if (ignoreBeforeTime === void 0) {
2406        ignoreBeforeTime = 0;
2407      }
2408
2409      var child = this._first,
2410          labels = this.labels,
2411          p;
2412
2413      while (child) {
2414        if (child._start >= ignoreBeforeTime) {
2415          child._start += amount;
2416          child._end += amount;
2417        }
2418
2419        child = child._next;
2420      }
2421
2422      if (adjustLabels) {
2423        for (p in labels) {
2424          if (labels[p] >= ignoreBeforeTime) {
2425            labels[p] += amount;
2426          }
2427        }
2428      }
2429
2430      return _uncache(this);
2431    };
2432
2433    _proto2.invalidate = function invalidate(soft) {
2434      var child = this._first;
2435      this._lock = 0;
2436
2437      while (child) {
2438        child.invalidate(soft);
2439        child = child._next;
2440      }
2441
2442      return _Animation.prototype.invalidate.call(this, soft);
2443    };
2444
2445    _proto2.clear = function clear(includeLabels) {
2446      if (includeLabels === void 0) {
2447        includeLabels = true;
2448      }
2449
2450      var child = this._first,
2451          next;
2452
2453      while (child) {
2454        next = child._next;
2455        this.remove(child);
2456        child = next;
2457      }
2458
2459      this._dp && (this._time = this._tTime = this._pTime = 0);
2460      includeLabels && (this.labels = {});
2461      return _uncache(this);
2462    };
2463
2464    _proto2.totalDuration = function totalDuration(value) {
2465      var max = 0,
2466          self = this,
2467          child = self._last,
2468          prevStart = _bigNum,
2469          prev,
2470          start,
2471          parent;
2472
2473      if (arguments.length) {
2474        return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value));
2475      }
2476
2477      if (self._dirty) {
2478        parent = self.parent;
2479
2480        while (child) {
2481          prev = child._prev;
2482          child._dirty && child.totalDuration();
2483          start = child._start;
2484
2485          if (start > prevStart && self._sort && child._ts && !self._lock) {
2486            self._lock = 1;
2487            _addToTimeline(self, child, start - child._delay, 1)._lock = 0;
2488          } else {
2489            prevStart = start;
2490          }
2491
2492          if (start < 0 && child._ts) {
2493            max -= start;
2494
2495            if (!parent && !self._dp || parent && parent.smoothChildTiming) {
2496              self._start += start / self._ts;
2497              self._time -= start;
2498              self._tTime -= start;
2499            }
2500
2501            self.shiftChildren(-start, false, -1e999);
2502            prevStart = 0;
2503          }
2504
2505          child._end > max && child._ts && (max = child._end);
2506          child = prev;
2507        }
2508
2509        _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1);
2510
2511        self._dirty = 0;
2512      }
2513
2514      return self._tDur;
2515    };
2516
2517    Timeline.updateRoot = function updateRoot(time) {
2518      if (_globalTimeline._ts) {
2519        _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline));
2520
2521        _lastRenderedFrame = _ticker.frame;
2522      }
2523
2524      if (_ticker.frame >= _nextGCFrame) {
2525        _nextGCFrame += _config.autoSleep || 120;
2526        var child = _globalTimeline._first;
2527        if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) {
2528          while (child && !child._ts) {
2529            child = child._next;
2530          }
2531
2532          child || _ticker.sleep();
2533        }
2534      }
2535    };
2536
2537    return Timeline;
2538  }(Animation);
2539
2540  _setDefaults(Timeline.prototype, {
2541    _lock: 0,
2542    _hasPause: 0,
2543    _forcing: 0
2544  });
2545
2546  var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) {
2547    var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter),
2548        index = 0,
2549        matchIndex = 0,
2550        result,
2551        startNums,
2552        color,
2553        endNum,
2554        chunk,
2555        startNum,
2556        hasRandom,
2557        a;
2558    pt.b = start;
2559    pt.e = end;
2560    start += "";
2561    end += "";
2562
2563    if (hasRandom = ~end.indexOf("random(")) {
2564      end = _replaceRandom(end);
2565    }
2566
2567    if (stringFilter) {
2568      a = [start, end];
2569      stringFilter(a, target, prop);
2570      start = a[0];
2571      end = a[1];
2572    }
2573
2574    startNums = start.match(_complexStringNumExp) || [];
2575
2576    while (result = _complexStringNumExp.exec(end)) {
2577      endNum = result[0];
2578      chunk = end.substring(index, result.index);
2579
2580      if (color) {
2581        color = (color + 1) % 5;
2582      } else if (chunk.substr(-5) === "rgba(") {
2583        color = 1;
2584      }
2585
2586      if (endNum !== startNums[matchIndex++]) {
2587        startNum = parseFloat(startNums[matchIndex - 1]) || 0;
2588        pt._pt = {
2589          _next: pt._pt,
2590          p: chunk || matchIndex === 1 ? chunk : ",",
2591          s: startNum,
2592          c: endNum.charAt(1) === "=" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum,
2593          m: color && color < 4 ? Math.round : 0
2594        };
2595        index = _complexStringNumExp.lastIndex;
2596      }
2597    }
2598
2599    pt.c = index < end.length ? end.substring(index, end.length) : "";
2600    pt.fp = funcParam;
2601
2602    if (_relExp.test(end) || hasRandom) {
2603      pt.e = 0;
2604    }
2605
2606    this._pt = pt;
2607    return pt;
2608  },
2609      _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) {
2610    _isFunction(end) && (end = end(index || 0, target, targets));
2611    var currentValue = target[prop],
2612        parsedStart = start !== "get" ? start : !_isFunction(currentValue) ? currentValue : funcParam ? target[prop.indexOf("set") || !_isFunction(target["get" + prop.substr(3)]) ? prop : "get" + prop.substr(3)](funcParam) : target[prop](),
2613        setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc,
2614        pt;
2615
2616    if (_isString(end)) {
2617      if (~end.indexOf("random(")) {
2618        end = _replaceRandom(end);
2619      }
2620
2621      if (end.charAt(1) === "=") {
2622        pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0);
2623
2624        if (pt || pt === 0) {
2625          end = pt;
2626        }
2627      }
2628    }
2629
2630    if (!optional || parsedStart !== end || _forceAllPropTweens) {
2631      if (!isNaN(parsedStart * end) && end !== "") {
2632        pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter);
2633        funcParam && (pt.fp = funcParam);
2634        modifier && pt.modifier(modifier, this, target);
2635        return this._pt = pt;
2636      }
2637
2638      !currentValue && !(prop in target) && _missingPlugin(prop, end);
2639      return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam);
2640    }
2641  },
2642      _processVars = function _processVars(vars, index, target, targets, tween) {
2643    _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets));
2644
2645    if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) {
2646      return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars;
2647    }
2648
2649    var copy = {},
2650        p;
2651
2652    for (p in vars) {
2653      copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets);
2654    }
2655
2656    return copy;
2657  },
2658      _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) {
2659    var plugin, pt, ptLookup, i;
2660
2661    if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) {
2662      tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority);
2663
2664      if (tween !== _quickTween) {
2665        ptLookup = tween._ptLookup[tween._targets.indexOf(target)];
2666        i = plugin._props.length;
2667
2668        while (i--) {
2669          ptLookup[plugin._props[i]] = pt;
2670        }
2671      }
2672    }
2673
2674    return plugin;
2675  },
2676      _overwritingTween,
2677      _forceAllPropTweens,
2678      _initTween = function _initTween(tween, time, tTime) {
2679    var vars = tween.vars,
2680        ease = vars.ease,
2681        startAt = vars.startAt,
2682        immediateRender = vars.immediateRender,
2683        lazy = vars.lazy,
2684        onUpdate = vars.onUpdate,
2685        runBackwards = vars.runBackwards,
2686        yoyoEase = vars.yoyoEase,
2687        keyframes = vars.keyframes,
2688        autoRevert = vars.autoRevert,
2689        dur = tween._dur,
2690        prevStartAt = tween._startAt,
2691        targets = tween._targets,
2692        parent = tween.parent,
2693        fullTargets = parent && parent.data === "nested" ? parent.vars.targets : targets,
2694        autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites,
2695        tl = tween.timeline,
2696        cleanVars,
2697        i,
2698        p,
2699        pt,
2700        target,
2701        hasPriority,
2702        gsData,
2703        harness,
2704        plugin,
2705        ptLookup,
2706        index,
2707        harnessVars,
2708        overwritten;
2709    tl && (!keyframes || !ease) && (ease = "none");
2710    tween._ease = _parseEase(ease, _defaults.ease);
2711    tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0;
2712
2713    if (yoyoEase && tween._yoyo && !tween._repeat) {
2714      yoyoEase = tween._yEase;
2715      tween._yEase = tween._ease;
2716      tween._ease = yoyoEase;
2717    }
2718
2719    tween._from = !tl && !!vars.runBackwards;
2720
2721    if (!tl || keyframes && !vars.stagger) {
2722      harness = targets[0] ? _getCache(targets[0]).harness : 0;
2723      harnessVars = harness && vars[harness.prop];
2724      cleanVars = _copyExcluding(vars, _reservedProps);
2725
2726      if (prevStartAt) {
2727        prevStartAt._zTime < 0 && prevStartAt.progress(1);
2728        time < 0 && runBackwards && immediateRender && !autoRevert ? prevStartAt.render(-1, true) : prevStartAt.revert(runBackwards && dur ? _revertConfigNoKill : _startAtRevertConfig);
2729        prevStartAt._lazy = 0;
2730      }
2731
2732      if (startAt) {
2733        _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({
2734          data: "isStart",
2735          overwrite: false,
2736          parent: parent,
2737          immediateRender: true,
2738          lazy: !prevStartAt && _isNotFalse(lazy),
2739          startAt: null,
2740          delay: 0,
2741          onUpdate: onUpdate && function () {
2742            return _callback(tween, "onUpdate");
2743          },
2744          stagger: 0
2745        }, startAt)));
2746
2747        tween._startAt._dp = 0;
2748        tween._startAt._sat = tween;
2749        time < 0 && (_reverting || !immediateRender && !autoRevert) && tween._startAt.revert(_revertConfigNoKill);
2750
2751        if (immediateRender) {
2752          if (dur && time <= 0 && tTime <= 0) {
2753            time && (tween._zTime = time);
2754            return;
2755          }
2756        }
2757      } else if (runBackwards && dur) {
2758        if (!prevStartAt) {
2759          time && (immediateRender = false);
2760          p = _setDefaults({
2761            overwrite: false,
2762            data: "isFromStart",
2763            lazy: immediateRender && !prevStartAt && _isNotFalse(lazy),
2764            immediateRender: immediateRender,
2765            stagger: 0,
2766            parent: parent
2767          }, cleanVars);
2768          harnessVars && (p[harness.prop] = harnessVars);
2769
2770          _removeFromParent(tween._startAt = Tween.set(targets, p));
2771
2772          tween._startAt._dp = 0;
2773          tween._startAt._sat = tween;
2774          time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true));
2775          tween._zTime = time;
2776
2777          if (!immediateRender) {
2778            _initTween(tween._startAt, _tinyNum, _tinyNum);
2779          } else if (!time) {
2780            return;
2781          }
2782        }
2783      }
2784
2785      tween._pt = tween._ptCache = 0;
2786      lazy = dur && _isNotFalse(lazy) || lazy && !dur;
2787
2788      for (i = 0; i < targets.length; i++) {
2789        target = targets[i];
2790        gsData = target._gsap || _harness(targets)[i]._gsap;
2791        tween._ptLookup[i] = ptLookup = {};
2792        _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender();
2793        index = fullTargets === targets ? i : fullTargets.indexOf(target);
2794
2795        if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) {
2796          tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority);
2797
2798          plugin._props.forEach(function (name) {
2799            ptLookup[name] = pt;
2800          });
2801
2802          plugin.priority && (hasPriority = 1);
2803        }
2804
2805        if (!harness || harnessVars) {
2806          for (p in cleanVars) {
2807            if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) {
2808              plugin.priority && (hasPriority = 1);
2809            } else {
2810              ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter);
2811            }
2812          }
2813        }
2814
2815        tween._op && tween._op[i] && tween.kill(target, tween._op[i]);
2816
2817        if (autoOverwrite && tween._pt) {
2818          _overwritingTween = tween;
2819
2820          _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time));
2821
2822          overwritten = !tween.parent;
2823          _overwritingTween = 0;
2824        }
2825
2826        tween._pt && lazy && (_lazyLookup[gsData.id] = 1);
2827      }
2828
2829      hasPriority && _sortPropTweensByPriority(tween);
2830      tween._onInit && tween._onInit(tween);
2831    }
2832
2833    tween._onUpdate = onUpdate;
2834    tween._initted = (!tween._op || tween._pt) && !overwritten;
2835    keyframes && time <= 0 && tl.render(_bigNum, true, true);
2836  },
2837      _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time, skipRecursion) {
2838    var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property],
2839        pt,
2840        rootPT,
2841        lookup,
2842        i;
2843
2844    if (!ptCache) {
2845      ptCache = tween._ptCache[property] = [];
2846      lookup = tween._ptLookup;
2847      i = tween._targets.length;
2848
2849      while (i--) {
2850        pt = lookup[i][property];
2851
2852        if (pt && pt.d && pt.d._pt) {
2853          pt = pt.d._pt;
2854
2855          while (pt && pt.p !== property && pt.fp !== property) {
2856            pt = pt._next;
2857          }
2858        }
2859
2860        if (!pt) {
2861          _forceAllPropTweens = 1;
2862          tween.vars[property] = "+=0";
2863
2864          _initTween(tween, time);
2865
2866          _forceAllPropTweens = 0;
2867          return skipRecursion ? _warn(property + " not eligible for reset") : 1;
2868        }
2869
2870        ptCache.push(pt);
2871      }
2872    }
2873
2874    i = ptCache.length;
2875
2876    while (i--) {
2877      rootPT = ptCache[i];
2878      pt = rootPT._pt || rootPT;
2879      pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c;
2880      pt.c = value - pt.s;
2881      rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e));
2882      rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b));
2883    }
2884  },
2885      _addAliasesToVars = function _addAliasesToVars(targets, vars) {
2886    var harness = targets[0] ? _getCache(targets[0]).harness : 0,
2887        propertyAliases = harness && harness.aliases,
2888        copy,
2889        p,
2890        i,
2891        aliases;
2892
2893    if (!propertyAliases) {
2894      return vars;
2895    }
2896
2897    copy = _merge({}, vars);
2898
2899    for (p in propertyAliases) {
2900      if (p in copy) {
2901        aliases = propertyAliases[p].split(",");
2902        i = aliases.length;
2903
2904        while (i--) {
2905          copy[aliases[i]] = copy[p];
2906        }
2907      }
2908    }
2909
2910    return copy;
2911  },
2912      _parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) {
2913    var ease = obj.ease || easeEach || "power1.inOut",
2914        p,
2915        a;
2916
2917    if (_isArray(obj)) {
2918      a = allProps[prop] || (allProps[prop] = []);
2919      obj.forEach(function (value, i) {
2920        return a.push({
2921          t: i / (obj.length - 1) * 100,
2922          v: value,
2923          e: ease
2924        });
2925      });
2926    } else {
2927      for (p in obj) {
2928        a = allProps[p] || (allProps[p] = []);
2929        p === "ease" || a.push({
2930          t: parseFloat(prop),
2931          v: obj[p],
2932          e: ease
2933        });
2934      }
2935    }
2936  },
2937      _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) {
2938    return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value;
2939  },
2940      _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert",
2941      _staggerPropsToSkip = {};
2942
2943  _forEachName(_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger", function (name) {
2944    return _staggerPropsToSkip[name] = 1;
2945  });
2946
2947  var Tween = function (_Animation2) {
2948    _inheritsLoose(Tween, _Animation2);
2949
2950    function Tween(targets, vars, position, skipInherit) {
2951      var _this3;
2952
2953      if (typeof vars === "number") {
2954        position.duration = vars;
2955        vars = position;
2956        position = null;
2957      }
2958
2959      _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this;
2960      var _this3$vars = _this3.vars,
2961          duration = _this3$vars.duration,
2962          delay = _this3$vars.delay,
2963          immediateRender = _this3$vars.immediateRender,
2964          stagger = _this3$vars.stagger,
2965          overwrite = _this3$vars.overwrite,
2966          keyframes = _this3$vars.keyframes,
2967          defaults = _this3$vars.defaults,
2968          scrollTrigger = _this3$vars.scrollTrigger,
2969          yoyoEase = _this3$vars.yoyoEase,
2970          parent = vars.parent || _globalTimeline,
2971          parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets),
2972          tl,
2973          i,
2974          copy,
2975          l,
2976          p,
2977          curTarget,
2978          staggerFunc,
2979          staggerVarsToMerge;
2980      _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://gsap.com", !_config.nullTargetWarn) || [];
2981      _this3._ptLookup = [];
2982      _this3._overwrite = overwrite;
2983
2984      if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {
2985        vars = _this3.vars;
2986        tl = _this3.timeline = new Timeline({
2987          data: "nested",
2988          defaults: defaults || {},
2989          targets: parent && parent.data === "nested" ? parent.vars.targets : parsedTargets
2990        });
2991        tl.kill();
2992        tl.parent = tl._dp = _assertThisInitialized(_this3);
2993        tl._start = 0;
2994
2995        if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {
2996          l = parsedTargets.length;
2997          staggerFunc = stagger && distribute(stagger);
2998
2999          if (_isObject(stagger)) {
3000            for (p in stagger) {
3001              if (~_staggerTweenProps.indexOf(p)) {
3002                staggerVarsToMerge || (staggerVarsToMerge = {});
3003                staggerVarsToMerge[p] = stagger[p];
3004              }
3005            }
3006          }
3007
3008          for (i = 0; i < l; i++) {
3009            copy = _copyExcluding(vars, _staggerPropsToSkip);
3010            copy.stagger = 0;
3011            yoyoEase && (copy.yoyoEase = yoyoEase);
3012            staggerVarsToMerge && _merge(copy, staggerVarsToMerge);
3013            curTarget = parsedTargets[i];
3014            copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets);
3015            copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay;
3016
3017            if (!stagger && l === 1 && copy.delay) {
3018              _this3._delay = delay = copy.delay;
3019              _this3._start += delay;
3020              copy.delay = 0;
3021            }
3022
3023            tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0);
3024            tl._ease = _easeMap.none;
3025          }
3026
3027          tl.duration() ? duration = delay = 0 : _this3.timeline = 0;
3028        } else if (keyframes) {
3029          _inheritDefaults(_setDefaults(tl.vars.defaults, {
3030            ease: "none"
3031          }));
3032
3033          tl._ease = _parseEase(keyframes.ease || vars.ease || "none");
3034          var time = 0,
3035              a,
3036              kf,
3037              v;
3038
3039          if (_isArray(keyframes)) {
vendor: 6,477 bytes, lines 3040-3246
3040            keyframes.forEach(function (frame) {
3041              return tl.to(parsedTargets, frame, ">");
3042            });
3043            tl.duration();
3044          } else {
3045            copy = {};
3046
3047            for (p in keyframes) {
3048              p === "ease" || p === "easeEach" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach);
3049            }
3050
3051            for (p in copy) {
3052              a = copy[p].sort(function (a, b) {
3053                return a.t - b.t;
3054              });
3055              time = 0;
3056
3057              for (i = 0; i < a.length; i++) {
3058                kf = a[i];
3059                v = {
3060                  ease: kf.e,
3061                  duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration
3062                };
3063                v[p] = kf.v;
3064                tl.to(parsedTargets, v, time);
3065                time += v.duration;
3066              }
3067            }
3068
3069            tl.duration() < duration && tl.to({}, {
3070              duration: duration - tl.duration()
3071            });
3072          }
3073        }
3074
3075        duration || _this3.duration(duration = tl.duration());
3076      } else {
3077        _this3.timeline = 0;
3078      }
3079
3080      if (overwrite === true && !_suppressOverwrites) {
3081        _overwritingTween = _assertThisInitialized(_this3);
3082
3083        _globalTimeline.killTweensOf(parsedTargets);
3084
3085        _overwritingTween = 0;
3086      }
3087
3088      _addToTimeline(parent, _assertThisInitialized(_this3), position);
3089
3090      vars.reversed && _this3.reverse();
3091      vars.paused && _this3.paused(true);
3092
3093      if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") {
3094        _this3._tTime = -_tinyNum;
3095
3096        _this3.render(Math.max(0, -delay) || 0);
3097      }
3098
3099      scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger);
3100      return _this3;
3101    }
3102
3103    var _proto3 = Tween.prototype;
3104
3105    _proto3.render = function render(totalTime, suppressEvents, force) {
3106      var prevTime = this._time,
3107          tDur = this._tDur,
3108          dur = this._dur,
3109          isNegative = totalTime < 0,
3110          tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime,
3111          time,
3112          pt,
3113          iteration,
3114          cycleDuration,
3115          prevIteration,
3116          isYoyo,
3117          ratio,
3118          timeline,
3119          yoyoEase;
3120
3121      if (!dur) {
3122        _renderZeroDurationTween(this, totalTime, suppressEvents, force);
3123      } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative) {
3124        time = tTime;
3125        timeline = this.timeline;
3126
3127        if (this._repeat) {
3128          cycleDuration = dur + this._rDelay;
3129
3130          if (this._repeat < -1 && isNegative) {
3131            return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);
3132          }
3133
3134          time = _roundPrecise(tTime % cycleDuration);
3135
3136          if (tTime === tDur) {
3137            iteration = this._repeat;
3138            time = dur;
3139          } else {
3140            iteration = ~~(tTime / cycleDuration);
3141
3142            if (iteration && iteration === _roundPrecise(tTime / cycleDuration)) {
3143              time = dur;
3144              iteration--;
3145            }
3146
3147            time > dur && (time = dur);
3148          }
3149
3150          isYoyo = this._yoyo && iteration & 1;
3151
3152          if (isYoyo) {
3153            yoyoEase = this._yEase;
3154            time = dur - time;
3155          }
3156
3157          prevIteration = _animationCycle(this._tTime, cycleDuration);
3158
3159          if (time === prevTime && !force && this._initted && iteration === prevIteration) {
3160            this._tTime = tTime;
3161            return this;
3162          }
3163
3164          if (iteration !== prevIteration) {
3165            timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo);
3166
3167            if (this.vars.repeatRefresh && !isYoyo && !this._lock && this._time !== cycleDuration && this._initted) {
3168              this._lock = force = 1;
3169              this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0;
3170            }
3171          }
3172        }
3173
3174        if (!this._initted) {
3175          if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) {
3176            this._tTime = 0;
3177            return this;
3178          }
3179
3180          if (prevTime !== this._time && !(force && this.vars.repeatRefresh && iteration !== prevIteration)) {
3181            return this;
3182          }
3183
3184          if (dur !== this._dur) {
3185            return this.render(totalTime, suppressEvents, force);
3186          }
3187        }
3188
3189        this._tTime = tTime;
3190        this._time = time;
3191
3192        if (!this._act && this._ts) {
3193          this._act = 1;
3194          this._lazy = 0;
3195        }
3196
3197        this.ratio = ratio = (yoyoEase || this._ease)(time / dur);
3198
3199        if (this._from) {
3200          this.ratio = ratio = 1 - ratio;
3201        }
3202
3203        if (time && !prevTime && !suppressEvents && !iteration) {
3204          _callback(this, "onStart");
3205
3206          if (this._tTime !== tTime) {
3207            return this;
3208          }
3209        }
3210
3211        pt = this._pt;
3212
3213        while (pt) {
3214          pt.r(ratio, pt.d);
3215          pt = pt._next;
3216        }
3217
3218        timeline && timeline.render(totalTime < 0 ? totalTime : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime);
3219
3220        if (this._onUpdate && !suppressEvents) {
3221          isNegative && _rewindStartAt(this, totalTime, suppressEvents, force);
3222
3223          _callback(this, "onUpdate");
3224        }
3225
3226        this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat");
3227
3228        if ((tTime === this._tDur || !tTime) && this._tTime === tTime) {
3229          isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true);
3230          (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1);
3231
3232          if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) {
3233            _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true);
3234
3235            this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();
3236          }
3237        }
3238      }
3239
3240      return this;
3241    };
3242
3243    _proto3.targets = function targets() {
3244      return this._targets;
3245    };
3246
vendor: 1,310 bytes, lines 3247-3280
3247    _proto3.invalidate = function invalidate(soft) {
3248      (!soft || !this.vars.runBackwards) && (this._startAt = 0);
3249      this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0;
3250      this._ptLookup = [];
3251      this.timeline && this.timeline.invalidate(soft);
3252      return _Animation2.prototype.invalidate.call(this, soft);
3253    };
3254
3255    _proto3.resetTo = function resetTo(property, value, start, startIsRelative, skipRecursion) {
3256      _tickerActive || _ticker.wake();
3257      this._ts || this.play();
3258      var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts),
3259          ratio;
3260      this._initted || _initTween(this, time);
3261      ratio = this._ease(time / this._dur);
3262
3263      if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time, skipRecursion)) {
3264        return this.resetTo(property, value, start, startIsRelative, 1);
3265      }
3266
3267      _alignPlayhead(this, 0);
3268
3269      this.parent || _addLinkedListItem(this._dp, this, "_first", "_last", this._dp._sort ? "_start" : 0);
3270      return this.render(0);
3271    };
3272
3273    _proto3.kill = function kill(targets, vars) {
3274      if (vars === void 0) {
3275        vars = "all";
3276      }
3277
3278      if (!targets && (!vars || vars === "all")) {
3279        this._lazy = this._pt = 0;
3280        return this.parent ? _interrupt(this) :
vendor: 16,527 bytes, lines 3280-3882
3280 this;
3281      }
3282
3283      if (this.timeline) {
3284        var tDur = this.timeline.totalDuration();
3285        this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this);
3286        this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1);
3287        return this;
3288      }
3289
3290      var parsedTargets = this._targets,
3291          killingTargets = targets ? toArray(targets) : parsedTargets,
3292          propTweenLookup = this._ptLookup,
3293          firstPT = this._pt,
3294          overwrittenProps,
3295          curLookup,
3296          curOverwriteProps,
3297          props,
3298          p,
3299          pt,
3300          i;
3301
3302      if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) {
3303        vars === "all" && (this._pt = 0);
3304        return _interrupt(this);
3305      }
3306
3307      overwrittenProps = this._op = this._op || [];
3308
3309      if (vars !== "all") {
3310        if (_isString(vars)) {
3311          p = {};
3312
3313          _forEachName(vars, function (name) {
3314            return p[name] = 1;
3315          });
3316
3317          vars = p;
3318        }
3319
3320        vars = _addAliasesToVars(parsedTargets, vars);
3321      }
3322
3323      i = parsedTargets.length;
3324
3325      while (i--) {
3326        if (~killingTargets.indexOf(parsedTargets[i])) {
3327          curLookup = propTweenLookup[i];
3328
3329          if (vars === "all") {
3330            overwrittenProps[i] = vars;
3331            props = curLookup;
3332            curOverwriteProps = {};
3333          } else {
3334            curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {};
3335            props = vars;
3336          }
3337
3338          for (p in props) {
3339            pt = curLookup && curLookup[p];
3340
3341            if (pt) {
3342              if (!("kill" in pt.d) || pt.d.kill(p) === true) {
3343                _removeLinkedListItem(this, pt, "_pt");
3344              }
3345
3346              delete curLookup[p];
3347            }
3348
3349            if (curOverwriteProps !== "all") {
3350              curOverwriteProps[p] = 1;
3351            }
3352          }
3353        }
3354      }
3355
3356      this._initted && !this._pt && firstPT && _interrupt(this);
3357      return this;
3358    };
3359
3360    Tween.to = function to(targets, vars) {
3361      return new Tween(targets, vars, arguments[2]);
3362    };
3363
3364    Tween.from = function from(targets, vars) {
3365      return _createTweenType(1, arguments);
3366    };
3367
3368    Tween.delayedCall = function delayedCall(delay, callback, params, scope) {
3369      return new Tween(callback, 0, {
3370        immediateRender: false,
3371        lazy: false,
3372        overwrite: false,
3373        delay: delay,
3374        onComplete: callback,
3375        onReverseComplete: callback,
3376        onCompleteParams: params,
3377        onReverseCompleteParams: params,
3378        callbackScope: scope
3379      });
3380    };
3381
3382    Tween.fromTo = function fromTo(targets, fromVars, toVars) {
3383      return _createTweenType(2, arguments);
3384    };
3385
3386    Tween.set = function set(targets, vars) {
3387      vars.duration = 0;
3388      vars.repeatDelay || (vars.repeat = 0);
3389      return new Tween(targets, vars);
3390    };
3391
3392    Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) {
3393      return _globalTimeline.killTweensOf(targets, props, onlyActive);
3394    };
3395
3396    return Tween;
3397  }(Animation);
3398
3399  _setDefaults(Tween.prototype, {
3400    _targets: [],
3401    _lazy: 0,
3402    _startAt: 0,
3403    _op: 0,
3404    _onInit: 0
3405  });
3406
3407  _forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) {
3408    Tween[name] = function () {
3409      var tl = new Timeline(),
3410          params = _slice.call(arguments, 0);
3411
3412      params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0);
3413      return tl[name].apply(tl, params);
3414    };
3415  });
3416
3417  var _setterPlain = function _setterPlain(target, property, value) {
3418    return target[property] = value;
3419  },
3420      _setterFunc = function _setterFunc(target, property, value) {
3421    return target[property](value);
3422  },
3423      _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) {
3424    return target[property](data.fp, value);
3425  },
3426      _setterAttribute = function _setterAttribute(target, property, value) {
3427    return target.setAttribute(property, value);
3428  },
3429      _getSetter = function _getSetter(target, property) {
3430    return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain;
3431  },
3432      _renderPlain = function _renderPlain(ratio, data) {
3433    return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data);
3434  },
3435      _renderBoolean = function _renderBoolean(ratio, data) {
3436    return data.set(data.t, data.p, !!(data.s + data.c * ratio), data);
3437  },
3438      _renderComplexString = function _renderComplexString(ratio, data) {
3439    var pt = data._pt,
3440        s = "";
3441
3442    if (!ratio && data.b) {
3443      s = data.b;
3444    } else if (ratio === 1 && data.e) {
3445      s = data.e;
3446    } else {
3447      while (pt) {
3448        s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s;
3449        pt = pt._next;
3450      }
3451
3452      s += data.c;
3453    }
3454
3455    data.set(data.t, data.p, s, data);
3456  },
3457      _renderPropTweens = function _renderPropTweens(ratio, data) {
3458    var pt = data._pt;
3459
3460    while (pt) {
3461      pt.r(ratio, pt.d);
3462      pt = pt._next;
3463    }
3464  },
3465      _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) {
3466    var pt = this._pt,
3467        next;
3468
3469    while (pt) {
3470      next = pt._next;
3471      pt.p === property && pt.modifier(modifier, tween, target);
3472      pt = next;
3473    }
3474  },
3475      _killPropTweensOf = function _killPropTweensOf(property) {
3476    var pt = this._pt,
3477        hasNonDependentRemaining,
3478        next;
3479
3480    while (pt) {
3481      next = pt._next;
3482
3483      if (pt.p === property && !pt.op || pt.op === property) {
3484        _removeLinkedListItem(this, pt, "_pt");
3485      } else if (!pt.dep) {
3486        hasNonDependentRemaining = 1;
3487      }
3488
3489      pt = next;
3490    }
3491
3492    return !hasNonDependentRemaining;
3493  },
3494      _setterWithModifier = function _setterWithModifier(target, property, value, data) {
3495    data.mSet(target, property, data.m.call(data.tween, value, data.mt), data);
3496  },
3497      _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) {
3498    var pt = parent._pt,
3499        next,
3500        pt2,
3501        first,
3502        last;
3503
3504    while (pt) {
3505      next = pt._next;
3506      pt2 = first;
3507
3508      while (pt2 && pt2.pr > pt.pr) {
3509        pt2 = pt2._next;
3510      }
3511
3512      if (pt._prev = pt2 ? pt2._prev : last) {
3513        pt._prev._next = pt;
3514      } else {
3515        first = pt;
3516      }
3517
3518      if (pt._next = pt2) {
3519        pt2._prev = pt;
3520      } else {
3521        last = pt;
3522      }
3523
3524      pt = next;
3525    }
3526
3527    parent._pt = first;
3528  };
3529
3530  var PropTween = function () {
3531    function PropTween(next, target, prop, start, change, renderer, data, setter, priority) {
3532      this.t = target;
3533      this.s = start;
3534      this.c = change;
3535      this.p = prop;
3536      this.r = renderer || _renderPlain;
3537      this.d = data || this;
3538      this.set = setter || _setterPlain;
3539      this.pr = priority || 0;
3540      this._next = next;
3541
3542      if (next) {
3543        next._prev = this;
3544      }
3545    }
3546
3547    var _proto4 = PropTween.prototype;
3548
3549    _proto4.modifier = function modifier(func, tween, target) {
3550      this.mSet = this.mSet || this.set;
3551      this.set = _setterWithModifier;
3552      this.m = func;
3553      this.mt = target;
3554      this.tween = tween;
3555    };
3556
3557    return PropTween;
3558  }();
3559
3560  _forEachName(_callbackNames + "parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger", function (name) {
3561    return _reservedProps[name] = 1;
3562  });
3563
3564  _globals.TweenMax = _globals.TweenLite = Tween;
3565  _globals.TimelineLite = _globals.TimelineMax = Timeline;
3566  _globalTimeline = new Timeline({
3567    sortChildren: false,
3568    defaults: _defaults,
3569    autoRemoveChildren: true,
3570    id: "root",
3571    smoothChildTiming: true
3572  });
3573  _config.stringFilter = _colorStringFilter;
3574
3575  var _media = [],
3576      _listeners = {},
3577      _emptyArray = [],
3578      _lastMediaTime = 0,
3579      _contextID = 0,
3580      _dispatch = function _dispatch(type) {
3581    return (_listeners[type] || _emptyArray).map(function (f) {
3582      return f();
3583    });
3584  },
3585      _onMediaChange = function _onMediaChange() {
3586    var time = Date.now(),
3587        matches = [];
3588
3589    if (time - _lastMediaTime > 2) {
3590      _dispatch("matchMediaInit");
3591
3592      _media.forEach(function (c) {
3593        var queries = c.queries,
3594            conditions = c.conditions,
3595            match,
3596            p,
3597            anyMatch,
3598            toggled;
3599
3600        for (p in queries) {
3601          match = _win.matchMedia(queries[p]).matches;
3602          match && (anyMatch = 1);
3603
3604          if (match !== conditions[p]) {
3605            conditions[p] = match;
3606            toggled = 1;
3607          }
3608        }
3609
3610        if (toggled) {
3611          c.revert();
3612          anyMatch && matches.push(c);
3613        }
3614      });
3615
3616      _dispatch("matchMediaRevert");
3617
3618      matches.forEach(function (c) {
3619        return c.onMatch(c, function (func) {
3620          return c.add(null, func);
3621        });
3622      });
3623      _lastMediaTime = time;
3624
3625      _dispatch("matchMedia");
3626    }
3627  };
3628
3629  var Context = function () {
3630    function Context(func, scope) {
3631      this.selector = scope && selector(scope);
3632      this.data = [];
3633      this._r = [];
3634      this.isReverted = false;
3635      this.id = _contextID++;
3636      func && this.add(func);
3637    }
3638
3639    var _proto5 = Context.prototype;
3640
3641    _proto5.add = function add(name, func, scope) {
3642      if (_isFunction(name)) {
3643        scope = func;
3644        func = name;
3645        name = _isFunction;
3646      }
3647
3648      var self = this,
3649          f = function f() {
3650        var prev = _context,
3651            prevSelector = self.selector,
3652            result;
3653        prev && prev !== self && prev.data.push(self);
3654        scope && (self.selector = selector(scope));
3655        _context = self;
3656        result = func.apply(self, arguments);
3657        _isFunction(result) && self._r.push(result);
3658        _context = prev;
3659        self.selector = prevSelector;
3660        self.isReverted = false;
3661        return result;
3662      };
3663
3664      self.last = f;
3665      return name === _isFunction ? f(self, function (func) {
3666        return self.add(null, func);
3667      }) : name ? self[name] = f : f;
3668    };
3669
3670    _proto5.ignore = function ignore(func) {
3671      var prev = _context;
3672      _context = null;
3673      func(this);
3674      _context = prev;
3675    };
3676
3677    _proto5.getTweens = function getTweens() {
3678      var a = [];
3679      this.data.forEach(function (e) {
3680        return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === "nested") && a.push(e);
3681      });
3682      return a;
3683    };
3684
3685    _proto5.clear = function clear() {
3686      this._r.length = this.data.length = 0;
3687    };
3688
3689    _proto5.kill = function kill(revert, matchMedia) {
3690      var _this4 = this;
3691
3692      if (revert) {
3693        (function () {
3694          var tweens = _this4.getTweens(),
3695              i = _this4.data.length,
3696              t;
3697
3698          while (i--) {
3699            t = _this4.data[i];
3700
3701            if (t.data === "isFlip") {
3702              t.revert();
3703              t.getChildren(true, true, false).forEach(function (tween) {
3704                return tweens.splice(tweens.indexOf(tween), 1);
3705              });
3706            }
3707          }
3708
3709          tweens.map(function (t) {
3710            return {
3711              g: t._dur || t._delay || t._sat && !t._sat.vars.immediateRender ? t.globalTime(0) : -Infinity,
3712              t: t
3713            };
3714          }).sort(function (a, b) {
3715            return b.g - a.g || -Infinity;
3716          }).forEach(function (o) {
3717            return o.t.revert(revert);
3718          });
3719          i = _this4.data.length;
3720
3721          while (i--) {
3722            t = _this4.data[i];
3723
3724            if (t instanceof Timeline) {
3725              if (t.data !== "nested") {
3726                t.scrollTrigger && t.scrollTrigger.revert();
3727                t.kill();
3728              }
3729            } else {
3730              !(t instanceof Tween) && t.revert && t.revert(revert);
3731            }
3732          }
3733
3734          _this4._r.forEach(function (f) {
3735            return f(revert, _this4);
3736          });
3737
3738          _this4.isReverted = true;
3739        })();
3740      } else {
3741        this.data.forEach(function (e) {
3742          return e.kill && e.kill();
3743        });
3744      }
3745
3746      this.clear();
3747
3748      if (matchMedia) {
3749        var i = _media.length;
3750
3751        while (i--) {
3752          _media[i].id === this.id && _media.splice(i, 1);
3753        }
3754      }
3755    };
3756
3757    _proto5.revert = function revert(config) {
3758      this.kill(config || {});
3759    };
3760
3761    return Context;
3762  }();
3763
3764  var MatchMedia = function () {
3765    function MatchMedia(scope) {
3766      this.contexts = [];
3767      this.scope = scope;
3768      _context && _context.data.push(this);
3769    }
3770
3771    var _proto6 = MatchMedia.prototype;
3772
3773    _proto6.add = function add(conditions, func, scope) {
3774      _isObject(conditions) || (conditions = {
3775        matches: conditions
3776      });
3777      var context = new Context(0, scope || this.scope),
3778          cond = context.conditions = {},
3779          mq,
3780          p,
3781          active;
3782      _context && !context.selector && (context.selector = _context.selector);
3783      this.contexts.push(context);
3784      func = context.add("onMatch", func);
3785      context.queries = conditions;
3786
3787      for (p in conditions) {
3788        if (p === "all") {
3789          active = 1;
3790        } else {
3791          mq = _win.matchMedia(conditions[p]);
3792
3793          if (mq) {
3794            _media.indexOf(context) < 0 && _media.push(context);
3795            (cond[p] = mq.matches) && (active = 1);
3796            mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange);
3797          }
3798        }
3799      }
3800
3801      active && func(context, function (f) {
3802        return context.add(null, f);
3803      });
3804      return this;
3805    };
3806
3807    _proto6.revert = function revert(config) {
3808      this.kill(config || {});
3809    };
3810
3811    _proto6.kill = function kill(revert) {
3812      this.contexts.forEach(function (c) {
3813        return c.kill(revert, true);
3814      });
3815    };
3816
3817    return MatchMedia;
3818  }();
3819
3820  var _gsap = {
3821    registerPlugin: function registerPlugin() {
3822      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
3823        args[_key2] = arguments[_key2];
3824      }
3825
3826      args.forEach(function (config) {
3827        return _createPlugin(config);
3828      });
3829    },
3830    timeline: function timeline(vars) {
3831      return new Timeline(vars);
3832    },
3833    getTweensOf: function getTweensOf(targets, onlyActive) {
3834      return _globalTimeline.getTweensOf(targets, onlyActive);
3835    },
3836    getProperty: function getProperty(target, property, unit, uncache) {
3837      _isString(target) && (target = toArray(target)[0]);
3838
3839      var getter = _getCache(target || {}).get,
3840          format = unit ? _passThrough : _numericIfPossible;
3841
3842      unit === "native" && (unit = "");
3843      return !target ? target : !property ? function (property, unit, uncache) {
3844        return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));
3845      } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));
3846    },
3847    quickSetter: function quickSetter(target, property, unit) {
3848      target = toArray(target);
3849
3850      if (target.length > 1) {
3851        var setters = target.map(function (t) {
3852          return gsap.quickSetter(t, property, unit);
3853        }),
3854            l = setters.length;
3855        return function (value) {
3856          var i = l;
3857
3858          while (i--) {
3859            setters[i](value);
3860          }
3861        };
3862      }
3863
3864      target = target[0] || {};
3865
3866      var Plugin = _plugins[property],
3867          cache = _getCache(target),
3868          p = cache.harness && (cache.harness.aliases || {})[property] || property,
3869          setter = Plugin ? function (value) {
3870        var p = new Plugin();
3871        _quickTween._pt = 0;
3872        p.init(target, unit ? value + unit : value, _quickTween, 0, [target]);
3873        p.render(1, p);
3874        _quickTween._pt && _renderPropTweens(1, _quickTween);
3875      } : cache.set(target, p);
3876
3877      return Plugin ? setter : function (value) {
3878        return setter(target, p, unit ? value + unit : value, cache, 1);
3879      };
3880    },
3881    quickTo: function quickTo(target, property, vars) {
3882      var _
3882merge2;
3883
3884      var tween = gsap.to(target, _merge((_merge2 = {}, _merge2[property] = "+=0.1", _merge2.paused = true, _merge
vendor: 5,649 bytes, lines 3884-4086
38842), vars || {})),
3885          func = function func(value, start, startIsRelative) {
3886        return tween.resetTo(property, value, start, startIsRelative);
3887      };
3888
3889      func.tween = tween;
3890      return func;
3891    },
3892    isTweening: function isTweening(targets) {
3893      return _globalTimeline.getTweensOf(targets, true).length > 0;
3894    },
3895    defaults: function defaults(value) {
3896      value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease));
3897      return _mergeDeep(_defaults, value || {});
3898    },
3899    config: function config(value) {
3900      return _mergeDeep(_config, value || {});
3901    },
3902    registerEffect: function registerEffect(_ref3) {
3903      var name = _ref3.name,
3904          effect = _ref3.effect,
3905          plugins = _ref3.plugins,
3906          defaults = _ref3.defaults,
3907          extendTimeline = _ref3.extendTimeline;
3908      (plugins || "").split(",").forEach(function (pluginName) {
3909        return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin.");
3910      });
3911
3912      _effects[name] = function (targets, vars, tl) {
3913        return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl);
3914      };
3915
3916      if (extendTimeline) {
3917        Timeline.prototype[name] = function (targets, vars, position) {
3918          return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position);
3919        };
3920      }
3921    },
3922    registerEase: function registerEase(name, ease) {
3923      _easeMap[name] = _parseEase(ease);
3924    },
3925    parseEase: function parseEase(ease, defaultEase) {
3926      return arguments.length ? _parseEase(ease, defaultEase) : _easeMap;
3927    },
3928    getById: function getById(id) {
3929      return _globalTimeline.getById(id);
3930    },
3931    exportRoot: function exportRoot(vars, includeDelayedCalls) {
3932      if (vars === void 0) {
3933        vars = {};
3934      }
3935
3936      var tl = new Timeline(vars),
3937          child,
3938          next;
3939      tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming);
3940
3941      _globalTimeline.remove(tl);
3942
3943      tl._dp = 0;
3944      tl._time = tl._tTime = _globalTimeline._time;
3945      child = _globalTimeline._first;
3946
3947      while (child) {
3948        next = child._next;
3949
3950        if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) {
3951          _addToTimeline(tl, child, child._start - child._delay);
3952        }
3953
3954        child = next;
3955      }
3956
3957      _addToTimeline(_globalTimeline, tl, 0);
3958
3959      return tl;
3960    },
3961    context: function context(func, scope) {
3962      return func ? new Context(func, scope) : _context;
3963    },
3964    matchMedia: function matchMedia(scope) {
3965      return new MatchMedia(scope);
3966    },
3967    matchMediaRefresh: function matchMediaRefresh() {
3968      return _media.forEach(function (c) {
3969        var cond = c.conditions,
3970            found,
3971            p;
3972
3973        for (p in cond) {
3974          if (cond[p]) {
3975            cond[p] = false;
3976            found = 1;
3977          }
3978        }
3979
3980        found && c.revert();
3981      }) || _onMediaChange();
3982    },
3983    addEventListener: function addEventListener(type, callback) {
3984      var a = _listeners[type] || (_listeners[type] = []);
3985      ~a.indexOf(callback) || a.push(callback);
3986    },
3987    removeEventListener: function removeEventListener(type, callback) {
3988      var a = _listeners[type],
3989          i = a && a.indexOf(callback);
3990      i >= 0 && a.splice(i, 1);
3991    },
3992    utils: {
3993      wrap: wrap,
3994      wrapYoyo: wrapYoyo,
3995      distribute: distribute,
3996      random: random,
3997      snap: snap,
3998      normalize: normalize,
3999      getUnit: getUnit,
4000      clamp: clamp,
4001      splitColor: splitColor,
4002      toArray: toArray,
4003      selector: selector,
4004      mapRange: mapRange,
4005      pipe: pipe,
4006      unitize: unitize,
4007      interpolate: interpolate,
4008      shuffle: shuffle
4009    },
4010    install: _install,
4011    effects: _effects,
4012    ticker: _ticker,
4013    updateRoot: Timeline.updateRoot,
4014    plugins: _plugins,
4015    globalTimeline: _globalTimeline,
4016    core: {
4017      PropTween: PropTween,
4018      globals: _addGlobal,
4019      Tween: Tween,
4020      Timeline: Timeline,
4021      Animation: Animation,
4022      getCache: _getCache,
4023      _removeLinkedListItem: _removeLinkedListItem,
4024      reverting: function reverting() {
4025        return _reverting;
4026      },
4027      context: function context(toAdd) {
4028        if (toAdd && _context) {
4029          _context.data.push(toAdd);
4030
4031          toAdd._ctx = _context;
4032        }
4033
4034        return _context;
4035      },
4036      suppressOverwrites: function suppressOverwrites(value) {
4037        return _suppressOverwrites = value;
4038      }
4039    }
4040  };
4041
4042  _forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) {
4043    return _gsap[name] = Tween[name];
4044  });
4045
4046  _ticker.add(Timeline.updateRoot);
4047
4048  _quickTween = _gsap.to({}, {
4049    duration: 0
4050  });
4051
4052  var _getPluginPropTween = function _getPluginPropTween(plugin, prop) {
4053    var pt = plugin._pt;
4054
4055    while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) {
4056      pt = pt._next;
4057    }
4058
4059    return pt;
4060  },
4061      _addModifiers = function _addModifiers(tween, modifiers) {
4062    var targets = tween._targets,
4063        p,
4064        i,
4065        pt;
4066
4067    for (p in modifiers) {
4068      i = targets.length;
4069
4070      while (i--) {
4071        pt = tween._ptLookup[i][p];
4072
4073        if (pt && (pt = pt.d)) {
4074          if (pt._pt) {
4075            pt = _getPluginPropTween(pt, p);
4076          }
4077
4078          pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p);
4079        }
4080      }
4081    }
4082  },
4083      _buildModifierPlugin = function _buildModifierPlugin(name, modifier) {
4084    return {
4085      name: name,
4086      
vendor: 21,125 bytes, lines 4086-4737
4086rawVars: 1,
4087      init: function init(target, vars, tween) {
4088        tween._onInit = function (tween) {
4089          var temp, p;
4090
4091          if (_isString(vars)) {
4092            temp = {};
4093
4094            _forEachName(vars, function (name) {
4095              return temp[name] = 1;
4096            });
4097
4098            vars = temp;
4099          }
4100
4101          if (modifier) {
4102            temp = {};
4103
4104            for (p in vars) {
4105              temp[p] = modifier(vars[p]);
4106            }
4107
4108            vars = temp;
4109          }
4110
4111          _addModifiers(tween, vars);
4112        };
4113      }
4114    };
4115  };
4116
4117  var gsap = _gsap.registerPlugin({
4118    name: "attr",
4119    init: function init(target, vars, tween, index, targets) {
4120      var p, pt, v;
4121      this.tween = tween;
4122
4123      for (p in vars) {
4124        v = target.getAttribute(p) || "";
4125        pt = this.add(target, "setAttribute", (v || 0) + "", vars[p], index, targets, 0, 0, p);
4126        pt.op = p;
4127        pt.b = v;
4128
4129        this._props.push(p);
4130      }
4131    },
4132    render: function render(ratio, data) {
4133      var pt = data._pt;
4134
4135      while (pt) {
4136        _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d);
4137        pt = pt._next;
4138      }
4139    }
4140  }, {
4141    name: "endArray",
4142    init: function init(target, value) {
4143      var i = value.length;
4144
4145      while (i--) {
4146        this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1);
4147      }
4148    }
4149  }, _buildModifierPlugin("roundProps", _roundModifier), _buildModifierPlugin("modifiers"), _buildModifierPlugin("snap", snap)) || _gsap;
4150  Tween.version = Timeline.version = gsap.version = "3.12.5";
4151  _coreReady = 1;
4152  _windowExists() && _wake();
4153  var Power0 = _easeMap.Power0,
4154      Power1 = _easeMap.Power1,
4155      Power2 = _easeMap.Power2,
4156      Power3 = _easeMap.Power3,
4157      Power4 = _easeMap.Power4,
4158      Linear = _easeMap.Linear,
4159      Quad = _easeMap.Quad,
4160      Cubic = _easeMap.Cubic,
4161      Quart = _easeMap.Quart,
4162      Quint = _easeMap.Quint,
4163      Strong = _easeMap.Strong,
4164      Elastic = _easeMap.Elastic,
4165      Back = _easeMap.Back,
4166      SteppedEase = _easeMap.SteppedEase,
4167      Bounce = _easeMap.Bounce,
4168      Sine = _easeMap.Sine,
4169      Expo = _easeMap.Expo,
4170      Circ = _easeMap.Circ;
4171
4172  var _win$1,
4173      _doc$1,
4174      _docElement,
4175      _pluginInitted,
4176      _tempDiv,
4177      _tempDivStyler,
4178      _recentSetterPlugin,
4179      _reverting$1,
4180      _windowExists$1 = function _windowExists() {
4181    return typeof window !== "undefined";
4182  },
4183      _transformProps = {},
4184      _RAD2DEG = 180 / Math.PI,
4185      _DEG2RAD = Math.PI / 180,
4186      _atan2 = Math.atan2,
4187      _bigNum$1 = 1e8,
4188      _capsExp = /([A-Z])/g,
4189      _horizontalExp = /(left|right|width|margin|padding|x)/i,
4190      _complexExp = /[\s,\(]\S/,
4191      _propertyAliases = {
4192    autoAlpha: "opacity,visibility",
4193    scale: "scaleX,scaleY",
4194    alpha: "opacity"
4195  },
4196      _renderCSSProp = function _renderCSSProp(ratio, data) {
4197    return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);
4198  },
4199      _renderPropWithEnd = function _renderPropWithEnd(ratio, data) {
4200    return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);
4201  },
4202      _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) {
4203    return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data);
4204  },
4205      _renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) {
4206    var value = data.s + data.c * ratio;
4207    data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data);
4208  },
4209      _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) {
4210    return data.set(data.t, data.p, ratio ? data.e : data.b, data);
4211  },
4212      _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) {
4213    return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data);
4214  },
4215      _setterCSSStyle = function _setterCSSStyle(target, property, value) {
4216    return target.style[property] = value;
4217  },
4218      _setterCSSProp = function _setterCSSProp(target, property, value) {
4219    return target.style.setProperty(property, value);
4220  },
4221      _setterTransform = function _setterTransform(target, property, value) {
4222    return target._gsap[property] = value;
4223  },
4224      _setterScale = function _setterScale(target, property, value) {
4225    return target._gsap.scaleX = target._gsap.scaleY = value;
4226  },
4227      _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) {
4228    var cache = target._gsap;
4229    cache.scaleX = cache.scaleY = value;
4230    cache.renderTransform(ratio, cache);
4231  },
4232      _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) {
4233    var cache = target._gsap;
4234    cache[property] = value;
4235    cache.renderTransform(ratio, cache);
4236  },
4237      _transformProp = "transform",
4238      _transformOriginProp = _transformProp + "Origin",
4239      _saveStyle = function _saveStyle(property, isNotCSS) {
4240    var _this = this;
4241
4242    var target = this.target,
4243        style = target.style,
4244        cache = target._gsap;
4245
4246    if (property in _transformProps && style) {
4247      this.tfm = this.tfm || {};
4248
4249      if (property !== "transform") {
4250        property = _propertyAliases[property] || property;
4251        ~property.indexOf(",") ? property.split(",").forEach(function (a) {
4252          return _this.tfm[a] = _get(target, a);
4253        }) : this.tfm[property] = cache.x ? cache[property] : _get(target, property);
4254        property === _transformOriginProp && (this.tfm.zOrigin = cache.zOrigin);
4255      } else {
4256        return _propertyAliases.transform.split(",").forEach(function (p) {
4257          return _saveStyle.call(_this, p, isNotCSS);
4258        });
4259      }
4260
4261      if (this.props.indexOf(_transformProp) >= 0) {
4262        return;
4263      }
4264
4265      if (cache.svg) {
4266        this.svgo = target.getAttribute("data-svg-origin");
4267        this.props.push(_transformOriginProp, isNotCSS, "");
4268      }
4269
4270      property = _transformProp;
4271    }
4272
4273    (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]);
4274  },
4275      _removeIndependentTransforms = function _removeIndependentTransforms(style) {
4276    if (style.translate) {
4277      style.removeProperty("translate");
4278      style.removeProperty("scale");
4279      style.removeProperty("rotate");
4280    }
4281  },
4282      _revertStyle = function _revertStyle() {
4283    var props = this.props,
4284        target = this.target,
4285        style = target.style,
4286        cache = target._gsap,
4287        i,
4288        p;
4289
4290    for (i = 0; i < props.length; i += 3) {
4291      props[i + 1] ? target[props[i]] = props[i + 2] : props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].substr(0, 2) === "--" ? props[i] : props[i].replace(_capsExp, "-$1").toLowerCase());
4292    }
4293
4294    if (this.tfm) {
4295      for (p in this.tfm) {
4296        cache[p] = this.tfm[p];
4297      }
4298
4299      if (cache.svg) {
4300        cache.renderTransform();
4301        target.setAttribute("data-svg-origin", this.svgo || "");
4302      }
4303
4304      i = _reverting$1();
4305
4306      if ((!i || !i.isStart) && !style[_transformProp]) {
4307        _removeIndependentTransforms(style);
4308
4309        if (cache.zOrigin && style[_transformOriginProp]) {
4310          style[_transformOriginProp] += " " + cache.zOrigin + "px";
4311          cache.zOrigin = 0;
4312          cache.renderTransform();
4313        }
4314
4315        cache.uncache = 1;
4316      }
4317    }
4318  },
4319      _getStyleSaver = function _getStyleSaver(target, properties) {
4320    var saver = {
4321      target: target,
4322      props: [],
4323      revert: _revertStyle,
4324      save: _saveStyle
4325    };
4326    target._gsap || gsap.core.getCache(target);
4327    properties && properties.split(",").forEach(function (p) {
4328      return saver.save(p);
4329    });
4330    return saver;
4331  },
4332      _supports3D,
4333      _createElement = function _createElement(type, ns) {
4334    var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type);
4335    return e && e.style ? e : _doc$1.createElement(type);
4336  },
4337      _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) {
4338    var cs = getComputedStyle(target);
4339    return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || "";
4340  },
4341      _prefixes = "O,Moz,ms,Ms,Webkit".split(","),
4342      _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) {
4343    var e = element || _tempDiv,
4344        s = e.style,
4345        i = 5;
4346
4347    if (property in s && !preferPrefix) {
4348      return property;
4349    }
4350
4351    property = property.charAt(0).toUpperCase() + property.substr(1);
4352
4353    while (i-- && !(_prefixes[i] + property in s)) {}
4354
4355    return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property;
4356  },
4357      _initCore = function _initCore() {
4358    if (_windowExists$1() && window.document) {
4359      _win$1 = window;
4360      _doc$1 = _win$1.document;
4361      _docElement = _doc$1.documentElement;
4362      _tempDiv = _createElement("div") || {
4363        style: {}
4364      };
4365      _tempDivStyler = _createElement("div");
4366      _transformProp = _checkPropPrefix(_transformProp);
4367      _transformOriginProp = _transformProp + "Origin";
4368      _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0";
4369      _supports3D = !!_checkPropPrefix("perspective");
4370      _reverting$1 = gsap.core.reverting;
4371      _pluginInitted = 1;
4372    }
4373  },
4374      _getBBoxHack = function _getBBoxHack(swapIfPossible) {
4375    var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"),
4376        oldParent = this.parentNode,
4377        oldSibling = this.nextSibling,
4378        oldCSS = this.style.cssText,
4379        bbox;
4380
4381    _docElement.appendChild(svg);
4382
4383    svg.appendChild(this);
4384    this.style.display = "block";
4385
4386    if (swapIfPossible) {
4387      try {
4388        bbox = this.getBBox();
4389        this._gsapBBox = this.getBBox;
4390        this.getBBox = _getBBoxHack;
4391      } catch (e) {}
4392    } else if (this._gsapBBox) {
4393      bbox = this._gsapBBox();
4394    }
4395
4396    if (oldParent) {
4397      if (oldSibling) {
4398        oldParent.insertBefore(this, oldSibling);
4399      } else {
4400        oldParent.appendChild(this);
4401      }
4402    }
4403
4404    _docElement.removeChild(svg);
4405
4406    this.style.cssText = oldCSS;
4407    return bbox;
4408  },
4409      _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) {
4410    var i = attributesArray.length;
4411
4412    while (i--) {
4413      if (target.hasAttribute(attributesArray[i])) {
4414        return target.getAttribute(attributesArray[i]);
4415      }
4416    }
4417  },
4418      _getBBox = function _getBBox(target) {
4419    var bounds;
4420
4421    try {
4422      bounds = target.getBBox();
4423    } catch (error) {
4424      bounds = _getBBoxHack.call(target, true);
4425    }
4426
4427    bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true));
4428    return bounds && !bounds.width && !bounds.x && !bounds.y ? {
4429      x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0,
4430      y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0,
4431      width: 0,
4432      height: 0
4433    } : bounds;
4434  },
4435      _isSVG = function _isSVG(e) {
4436    return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));
4437  },
4438      _removeProperty = function _removeProperty(target, property) {
4439    if (property) {
4440      var style = target.style,
4441          first2Chars;
4442
4443      if (property in _transformProps && property !== _transformOriginProp) {
4444        property = _transformProp;
4445      }
4446
4447      if (style.removeProperty) {
4448        first2Chars = property.substr(0, 2);
4449
4450        if (first2Chars === "ms" || property.substr(0, 6) === "webkit") {
4451          property = "-" + property;
4452        }
4453
4454        style.removeProperty(first2Chars === "--" ? property : property.replace(_capsExp, "-$1").toLowerCase());
4455      } else {
4456        style.removeAttribute(property);
4457      }
4458    }
4459  },
4460      _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) {
4461    var pt = new PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue);
4462    plugin._pt = pt;
4463    pt.b = beginning;
4464    pt.e = end;
4465
4466    plugin._props.push(property);
4467
4468    return pt;
4469  },
4470      _nonConvertibleUnits = {
4471    deg: 1,
4472    rad: 1,
4473    turn: 1
4474  },
4475      _nonStandardLayouts = {
4476    grid: 1,
4477    flex: 1
4478  },
4479      _convertToUnit = function _convertToUnit(target, property, value, unit) {
4480    var curValue = parseFloat(value) || 0,
4481        curUnit = (value + "").trim().substr((curValue + "").length) || "px",
4482        style = _tempDiv.style,
4483        horizontal = _horizontalExp.test(property),
4484        isRootSVG = target.tagName.toLowerCase() === "svg",
4485        measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"),
4486        amount = 100,
4487        toPixels = unit === "px",
4488        toPercent = unit === "%",
4489        px,
4490        parent,
4491        cache,
4492        isSVG;
4493
4494    if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) {
4495      return curValue;
4496    }
4497
4498    curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px"));
4499    isSVG = target.getCTM && _isSVG(target);
4500
4501    if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) {
4502      px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty];
4503      return _round(toPercent ? curValue / px * amount : curValue / 100 * px);
4504    }
4505
4506    style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit);
4507    parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode;
4508
4509    if (isSVG) {
4510      parent = (target.ownerSVGElement || {}).parentNode;
4511    }
4512
4513    if (!parent || parent === _doc$1 || !parent.appendChild) {
4514      parent = _doc$1.body;
4515    }
4516
4517    cache = parent._gsap;
4518
4519    if (cache && toPercent && cache.width && horizontal && cache.time === _ticker.time && !cache.uncache) {
4520      return _round(curValue / cache.width * amount);
4521    } else {
4522      if (toPercent && (property === "height" || property === "width")) {
4523        var v = target.style[property];
4524        target.style[property] = amount + unit;
4525        px = target[measureProperty];
4526        v ? target.style[property] = v : _removeProperty(target, property);
4527      } else {
4528        (toPercent || curUnit === "%") && !_nonStandardLayouts[_getComputedProperty(parent, "display")] && (style.position = _getComputedProperty(target, "position"));
4529        parent === target && (style.position = "static");
4530        parent.appendChild(_tempDiv);
4531        px = _tempDiv[measureProperty];
4532        parent.removeChild(_tempDiv);
4533        style.position = "absolute";
4534      }
4535
4536      if (horizontal && toPercent) {
4537        cache = _getCache(parent);
4538        cache.time = _ticker.time;
4539        cache.width = parent[measureProperty];
4540      }
4541    }
4542
4543    return _round(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0);
4544  },
4545      _get = function _get(target, property, unit, uncache) {
4546    var value;
4547    _pluginInitted || _initCore();
4548
4549    if (property in _propertyAliases && property !== "transform") {
4550      property = _propertyAliases[property];
4551
4552      if (~property.indexOf(",")) {
4553        property = property.split(",")[0];
4554      }
4555    }
4556
4557    if (_transformProps[property] && property !== "transform") {
4558      value = _parseTransform(target, uncache);
4559      value = property !== "transformOrigin" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px";
4560    } else {
4561      value = target.style[property];
4562
4563      if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) {
4564        value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || _getProperty(target, property) || (property === "opacity" ? 1 : 0);
4565      }
4566    }
4567
4568    return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value;
4569  },
4570      _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) {
4571    if (!start || start === "none") {
4572      var p = _checkPropPrefix(prop, target, 1),
4573          s = p && _getComputedProperty(target, p, 1);
4574
4575      if (s && s !== start) {
4576        prop = p;
4577        start = s;
4578      } else if (prop === "borderColor") {
4579        start = _getComputedProperty(target, "borderTopColor");
4580      }
4581    }
4582
4583    var pt = new PropTween(this._pt, target.style, prop, 0, 1, _renderComplexString),
4584        index = 0,
4585        matchIndex = 0,
4586        a,
4587        result,
4588        startValues,
4589        startNum,
4590        color,
4591        startValue,
4592        endValue,
4593        endNum,
4594        chunk,
4595        endUnit,
4596        startUnit,
4597        endValues;
4598    pt.b = start;
4599    pt.e = end;
4600    start += "";
4601    end += "";
4602
4603    if (end === "auto") {
4604      startValue = target.style[prop];
4605      target.style[prop] = end;
4606      end = _getComputedProperty(target, prop) || end;
4607      startValue ? target.style[prop] = startValue : _removeProperty(target, prop);
4608    }
4609
4610    a = [start, end];
4611
4612    _colorStringFilter(a);
4613
4614    start = a[0];
4615    end = a[1];
4616    startValues = start.match(_numWithUnitExp) || [];
4617    endValues = end.match(_numWithUnitExp) || [];
4618
4619    if (endValues.length) {
4620      while (result = _numWithUnitExp.exec(end)) {
4621        endValue = result[0];
4622        chunk = end.substring(index, result.index);
4623
4624        if (color) {
4625          color = (color + 1) % 5;
4626        } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") {
4627          color = 1;
4628        }
4629
4630        if (endValue !== (startValue = startValues[matchIndex++] || "")) {
4631          startNum = parseFloat(startValue) || 0;
4632          startUnit = startValue.substr((startNum + "").length);
4633          endValue.charAt(1) === "=" && (endValue = _parseRelative(startNum, endValue) + startUnit);
4634          endNum = parseFloat(endValue);
4635          endUnit = endValue.substr((endNum + "").length);
4636          index = _numWithUnitExp.lastIndex - endUnit.length;
4637
4638          if (!endUnit) {
4639            endUnit = endUnit || _config.units[prop] || startUnit;
4640
4641            if (index === end.length) {
4642              end += endUnit;
4643              pt.e += endUnit;
4644            }
4645          }
4646
4647          if (startUnit !== endUnit) {
4648            startNum = _convertToUnit(target, prop, startValue, endUnit) || 0;
4649          }
4650
4651          pt._pt = {
4652            _next: pt._pt,
4653            p: chunk || matchIndex === 1 ? chunk : ",",
4654            s: startNum,
4655            c: endNum - startNum,
4656            m: color && color < 4 || prop === "zIndex" ? Math.round : 0
4657          };
4658        }
4659      }
4660
4661      pt.c = index < end.length ? end.substring(index, end.length) : "";
4662    } else {
4663      pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue;
4664    }
4665
4666    _relExp.test(end) && (pt.e = 0);
4667    this._pt = pt;
4668    return pt;
4669  },
4670      _keywordToPercent = {
4671    top: "0%",
4672    bottom: "100%",
4673    left: "0%",
4674    right: "100%",
4675    center: "50%"
4676  },
4677      _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) {
4678    var split = value.split(" "),
4679        x = split[0],
4680        y = split[1] || "50%";
4681
4682    if (x === "top" || x === "bottom" || y === "left" || y === "right") {
4683      value = x;
4684      x = y;
4685      y = value;
4686    }
4687
4688    split[0] = _keywordToPercent[x] || x;
4689    split[1] = _keywordToPercent[y] || y;
4690    return split.join(" ");
4691  },
4692      _renderClearProps = function _renderClearProps(ratio, data) {
4693    if (data.tween && data.tween._time === data.tween._dur) {
4694      var target = data.t,
4695          style = target.style,
4696          props = data.u,
4697          cache = target._gsap,
4698          prop,
4699          clearTransforms,
4700          i;
4701
4702      if (props === "all" || props === true) {
4703        style.cssText = "";
4704        clearTransforms = 1;
4705      } else {
4706        props = props.split(",");
4707        i = props.length;
4708
4709        while (--i > -1) {
4710          prop = props[i];
4711
4712          if (_transformProps[prop]) {
4713            clearTransforms = 1;
4714            prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp;
4715          }
4716
4717          _removeProperty(target, prop);
4718        }
4719      }
4720
4721      if (clearTransforms) {
4722        _removeProperty(target, _transformProp);
4723
4724        if (cache) {
4725          cache.svg && target.removeAttribute("transform");
4726
4727          _parseTransform(target, 1);
4728
4729          cache.uncache = 1;
4730
4731          _removeIndependentTransforms(style);
4732        }
4733      }
4734    }
4735  },
4736      _specialProps = {
4737    clearProps: function clearProps(plugin, target, property, endValue, tween) {
vendor: 1,580 bytes, lines 4738-4778
4738      if (tween.data !== "isFromStart") {
4739        var pt = plugin._pt = new PropTween(plugin._pt, target, property, 0, 0, _renderClearProps);
4740        pt.u = endValue;
4741        pt.pr = -10;
4742        pt.tween = tween;
4743
4744        plugin._props.push(property);
4745
4746        return 1;
4747      }
4748    }
4749  },
4750      _identity2DMatrix = [1, 0, 0, 1, 0, 0],
4751      _rotationalProperties = {},
4752      _isNullTransform = function _isNullTransform(value) {
4753    return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value;
4754  },
4755      _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) {
4756    var matrixString = _getComputedProperty(target, _transformProp);
4757
4758    return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_numExp).map(_round);
4759  },
4760      _getMatrix = function _getMatrix(target, force2D) {
4761    var cache = target._gsap || _getCache(target),
4762        style = target.style,
4763        matrix = _getComputedTransformMatrixAsArray(target),
4764        parent,
4765        nextSibling,
4766        temp,
4767        addedToDOM;
4768
4769    if (cache.svg && target.getAttribute("transform")) {
4770      temp = target.transform.baseVal.consolidate().matrix;
4771      matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f];
4772      return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix;
4773    } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) {
4774      temp = style.display;
4775      style.display = "block";
4776      parent = target.parentNode;
4777
4778      if (!parent || !target.offsetParent
vendor: 18,926 bytes, lines 4778-5375
4778) {
4779        addedToDOM = 1;
4780        nextSibling = target.nextElementSibling;
4781
4782        _docElement.appendChild(target);
4783      }
4784
4785      matrix = _getComputedTransformMatrixAsArray(target);
4786      temp ? style.display = temp : _removeProperty(target, "display");
4787
4788      if (addedToDOM) {
4789        nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target);
4790      }
4791    }
4792
4793    return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix;
4794  },
4795      _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) {
4796    var cache = target._gsap,
4797        matrix = matrixArray || _getMatrix(target, true),
4798        xOriginOld = cache.xOrigin || 0,
4799        yOriginOld = cache.yOrigin || 0,
4800        xOffsetOld = cache.xOffset || 0,
4801        yOffsetOld = cache.yOffset || 0,
4802        a = matrix[0],
4803        b = matrix[1],
4804        c = matrix[2],
4805        d = matrix[3],
4806        tx = matrix[4],
4807        ty = matrix[5],
4808        originSplit = origin.split(" "),
4809        xOrigin = parseFloat(originSplit[0]) || 0,
4810        yOrigin = parseFloat(originSplit[1]) || 0,
4811        bounds,
4812        determinant,
4813        x,
4814        y;
4815
4816    if (!originIsAbsolute) {
4817      bounds = _getBBox(target);
4818      xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin);
4819      yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin);
4820    } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) {
4821      x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;
4822      y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;
4823      xOrigin = x;
4824      yOrigin = y;
4825    }
4826
4827    if (smooth || smooth !== false && cache.smooth) {
4828      tx = xOrigin - xOriginOld;
4829      ty = yOrigin - yOriginOld;
4830      cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx;
4831      cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty;
4832    } else {
4833      cache.xOffset = cache.yOffset = 0;
4834    }
4835
4836    cache.xOrigin = xOrigin;
4837    cache.yOrigin = yOrigin;
4838    cache.smooth = !!smooth;
4839    cache.origin = origin;
4840    cache.originIsAbsolute = !!originIsAbsolute;
4841    target.style[_transformOriginProp] = "0px 0px";
4842
4843    if (pluginToAddPropTweensTo) {
4844      _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin);
4845
4846      _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin);
4847
4848      _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset);
4849
4850      _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset);
4851    }
4852
4853    target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin);
4854  },
4855      _parseTransform = function _parseTransform(target, uncache) {
4856    var cache = target._gsap || new GSCache(target);
4857
4858    if ("x" in cache && !uncache && !cache.uncache) {
4859      return cache;
4860    }
4861
4862    var style = target.style,
4863        invertedScaleX = cache.scaleX < 0,
4864        px = "px",
4865        deg = "deg",
4866        cs = getComputedStyle(target),
4867        origin = _getComputedProperty(target, _transformOriginProp) || "0",
4868        x,
4869        y,
4870        z,
4871        scaleX,
4872        scaleY,
4873        rotation,
4874        rotationX,
4875        rotationY,
4876        skewX,
4877        skewY,
4878        perspective,
4879        xOrigin,
4880        yOrigin,
4881        matrix,
4882        angle,
4883        cos,
4884        sin,
4885        a,
4886        b,
4887        c,
4888        d,
4889        a12,
4890        a22,
4891        t1,
4892        t2,
4893        t3,
4894        a13,
4895        a23,
4896        a33,
4897        a42,
4898        a43,
4899        a32;
4900    x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0;
4901    scaleX = scaleY = 1;
4902    cache.svg = !!(target.getCTM && _isSVG(target));
4903
4904    if (cs.translate) {
4905      if (cs.translate !== "none" || cs.scale !== "none" || cs.rotate !== "none") {
4906        style[_transformProp] = (cs.translate !== "none" ? "translate3d(" + (cs.translate + " 0 0").split(" ").slice(0, 3).join(", ") + ") " : "") + (cs.rotate !== "none" ? "rotate(" + cs.rotate + ") " : "") + (cs.scale !== "none" ? "scale(" + cs.scale.split(" ").join(",") + ") " : "") + (cs[_transformProp] !== "none" ? cs[_transformProp] : "");
4907      }
4908
4909      style.scale = style.rotate = style.translate = "none";
4910    }
4911
4912    matrix = _getMatrix(target, cache.svg);
4913
4914    if (cache.svg) {
4915      if (cache.uncache) {
4916        t2 = target.getBBox();
4917        origin = cache.xOrigin - t2.x + "px " + (cache.yOrigin - t2.y) + "px";
4918        t1 = "";
4919      } else {
4920        t1 = !uncache && target.getAttribute("data-svg-origin");
4921      }
4922
4923      _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix);
4924    }
4925
4926    xOrigin = cache.xOrigin || 0;
4927    yOrigin = cache.yOrigin || 0;
4928
4929    if (matrix !== _identity2DMatrix) {
4930      a = matrix[0];
4931      b = matrix[1];
4932      c = matrix[2];
4933      d = matrix[3];
4934      x = a12 = matrix[4];
4935      y = a22 = matrix[5];
4936
4937      if (matrix.length === 6) {
4938        scaleX = Math.sqrt(a * a + b * b);
4939        scaleY = Math.sqrt(d * d + c * c);
4940        rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0;
4941        skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0;
4942        skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD)));
4943
4944        if (cache.svg) {
4945          x -= xOrigin - (xOrigin * a + yOrigin * c);
4946          y -= yOrigin - (xOrigin * b + yOrigin * d);
4947        }
4948      } else {
4949        a32 = matrix[6];
4950        a42 = matrix[7];
4951        a13 = matrix[8];
4952        a23 = matrix[9];
4953        a33 = matrix[10];
4954        a43 = matrix[11];
4955        x = matrix[12];
4956        y = matrix[13];
4957        z = matrix[14];
4958        angle = _atan2(a32, a33);
4959        rotationX = angle * _RAD2DEG;
4960
4961        if (angle) {
4962          cos = Math.cos(-angle);
4963          sin = Math.sin(-angle);
4964          t1 = a12 * cos + a13 * sin;
4965          t2 = a22 * cos + a23 * sin;
4966          t3 = a32 * cos + a33 * sin;
4967          a13 = a12 * -sin + a13 * cos;
4968          a23 = a22 * -sin + a23 * cos;
4969          a33 = a32 * -sin + a33 * cos;
4970          a43 = a42 * -sin + a43 * cos;
4971          a12 = t1;
4972          a22 = t2;
4973          a32 = t3;
4974        }
4975
4976        angle = _atan2(-c, a33);
4977        rotationY = angle * _RAD2DEG;
4978
4979        if (angle) {
4980          cos = Math.cos(-angle);
4981          sin = Math.sin(-angle);
4982          t1 = a * cos - a13 * sin;
4983          t2 = b * cos - a23 * sin;
4984          t3 = c * cos - a33 * sin;
4985          a43 = d * sin + a43 * cos;
4986          a = t1;
4987          b = t2;
4988          c = t3;
4989        }
4990
4991        angle = _atan2(b, a);
4992        rotation = angle * _RAD2DEG;
4993
4994        if (angle) {
4995          cos = Math.cos(angle);
4996          sin = Math.sin(angle);
4997          t1 = a * cos + b * sin;
4998          t2 = a12 * cos + a22 * sin;
4999          b = b * cos - a * sin;
5000          a22 = a22 * cos - a12 * sin;
5001          a = t1;
5002          a12 = t2;
5003        }
5004
5005        if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) {
5006          rotationX = rotation = 0;
5007          rotationY = 180 - rotationY;
5008        }
5009
5010        scaleX = _round(Math.sqrt(a * a + b * b + c * c));
5011        scaleY = _round(Math.sqrt(a22 * a22 + a32 * a32));
5012        angle = _atan2(a12, a22);
5013        skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0;
5014        perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;
5015      }
5016
5017      if (cache.svg) {
5018        t1 = target.getAttribute("transform");
5019        cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp));
5020        t1 && target.setAttribute("transform", t1);
5021      }
5022    }
5023
5024    if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {
5025      if (invertedScaleX) {
5026        scaleX *= -1;
5027        skewX += rotation <= 0 ? 180 : -180;
5028        rotation += rotation <= 0 ? 180 : -180;
5029      } else {
5030        scaleY *= -1;
5031        skewX += skewX <= 0 ? 180 : -180;
5032      }
5033    }
5034
5035    uncache = uncache || cache.uncache;
5036    cache.x = x - ((cache.xPercent = x && (!uncache && cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px;
5037    cache.y = y - ((cache.yPercent = y && (!uncache && cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px;
5038    cache.z = z + px;
5039    cache.scaleX = _round(scaleX);
5040    cache.scaleY = _round(scaleY);
5041    cache.rotation = _round(rotation) + deg;
5042    cache.rotationX = _round(rotationX) + deg;
5043    cache.rotationY = _round(rotationY) + deg;
5044    cache.skewX = skewX + deg;
5045    cache.skewY = skewY + deg;
5046    cache.transformPerspective = perspective + px;
5047
5048    if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || !uncache && cache.zOrigin || 0) {
5049      style[_transformOriginProp] = _firstTwoOnly(origin);
5050    }
5051
5052    cache.xOffset = cache.yOffset = 0;
5053    cache.force3D = _config.force3D;
5054    cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms;
5055    cache.uncache = 0;
5056    return cache;
5057  },
5058      _firstTwoOnly = function _firstTwoOnly(value) {
5059    return (value = value.split(" "))[0] + " " + value[1];
5060  },
5061      _addPxTranslate = function _addPxTranslate(target, start, value) {
5062    var unit = getUnit(start);
5063    return _round(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit;
5064  },
5065      _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) {
5066    cache.z = "0px";
5067    cache.rotationY = cache.rotationX = "0deg";
5068    cache.force3D = 0;
5069
5070    _renderCSSTransforms(ratio, cache);
5071  },
5072      _zeroDeg = "0deg",
5073      _zeroPx = "0px",
5074      _endParenthesis = ") ",
5075      _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) {
5076    var _ref = cache || this,
5077        xPercent = _ref.xPercent,
5078        yPercent = _ref.yPercent,
5079        x = _ref.x,
5080        y = _ref.y,
5081        z = _ref.z,
5082        rotation = _ref.rotation,
5083        rotationY = _ref.rotationY,
5084        rotationX = _ref.rotationX,
5085        skewX = _ref.skewX,
5086        skewY = _ref.skewY,
5087        scaleX = _ref.scaleX,
5088        scaleY = _ref.scaleY,
5089        transformPerspective = _ref.transformPerspective,
5090        force3D = _ref.force3D,
5091        target = _ref.target,
5092        zOrigin = _ref.zOrigin,
5093        transforms = "",
5094        use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true;
5095
5096    if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) {
5097      var angle = parseFloat(rotationY) * _DEG2RAD,
5098          a13 = Math.sin(angle),
5099          a33 = Math.cos(angle),
5100          cos;
5101
5102      angle = parseFloat(rotationX) * _DEG2RAD;
5103      cos = Math.cos(angle);
5104      x = _addPxTranslate(target, x, a13 * cos * -zOrigin);
5105      y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin);
5106      z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin);
5107    }
5108
5109    if (transformPerspective !== _zeroPx) {
5110      transforms += "perspective(" + transformPerspective + _endParenthesis;
5111    }
5112
5113    if (xPercent || yPercent) {
5114      transforms += "translate(" + xPercent + "%, " + yPercent + "%) ";
5115    }
5116
5117    if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) {
5118      transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis;
5119    }
5120
5121    if (rotation !== _zeroDeg) {
5122      transforms += "rotate(" + rotation + _endParenthesis;
5123    }
5124
5125    if (rotationY !== _zeroDeg) {
5126      transforms += "rotateY(" + rotationY + _endParenthesis;
5127    }
5128
5129    if (rotationX !== _zeroDeg) {
5130      transforms += "rotateX(" + rotationX + _endParenthesis;
5131    }
5132
5133    if (skewX !== _zeroDeg || skewY !== _zeroDeg) {
5134      transforms += "skew(" + skewX + ", " + skewY + _endParenthesis;
5135    }
5136
5137    if (scaleX !== 1 || scaleY !== 1) {
5138      transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis;
5139    }
5140
5141    target.style[_transformProp] = transforms || "translate(0, 0)";
5142  },
5143      _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) {
5144    var _ref2 = cache || this,
5145        xPercent = _ref2.xPercent,
5146        yPercent = _ref2.yPercent,
5147        x = _ref2.x,
5148        y = _ref2.y,
5149        rotation = _ref2.rotation,
5150        skewX = _ref2.skewX,
5151        skewY = _ref2.skewY,
5152        scaleX = _ref2.scaleX,
5153        scaleY = _ref2.scaleY,
5154        target = _ref2.target,
5155        xOrigin = _ref2.xOrigin,
5156        yOrigin = _ref2.yOrigin,
5157        xOffset = _ref2.xOffset,
5158        yOffset = _ref2.yOffset,
5159        forceCSS = _ref2.forceCSS,
5160        tx = parseFloat(x),
5161        ty = parseFloat(y),
5162        a11,
5163        a21,
5164        a12,
5165        a22,
5166        temp;
5167
5168    rotation = parseFloat(rotation);
5169    skewX = parseFloat(skewX);
5170    skewY = parseFloat(skewY);
5171
5172    if (skewY) {
5173      skewY = parseFloat(skewY);
5174      skewX += skewY;
5175      rotation += skewY;
5176    }
5177
5178    if (rotation || skewX) {
5179      rotation *= _DEG2RAD;
5180      skewX *= _DEG2RAD;
5181      a11 = Math.cos(rotation) * scaleX;
5182      a21 = Math.sin(rotation) * scaleX;
5183      a12 = Math.sin(rotation - skewX) * -scaleY;
5184      a22 = Math.cos(rotation - skewX) * scaleY;
5185
5186      if (skewX) {
5187        skewY *= _DEG2RAD;
5188        temp = Math.tan(skewX - skewY);
5189        temp = Math.sqrt(1 + temp * temp);
5190        a12 *= temp;
5191        a22 *= temp;
5192
5193        if (skewY) {
5194          temp = Math.tan(skewY);
5195          temp = Math.sqrt(1 + temp * temp);
5196          a11 *= temp;
5197          a21 *= temp;
5198        }
5199      }
5200
5201      a11 = _round(a11);
5202      a21 = _round(a21);
5203      a12 = _round(a12);
5204      a22 = _round(a22);
5205    } else {
5206      a11 = scaleX;
5207      a22 = scaleY;
5208      a21 = a12 = 0;
5209    }
5210
5211    if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) {
5212      tx = _convertToUnit(target, "x", x, "px");
5213      ty = _convertToUnit(target, "y", y, "px");
5214    }
5215
5216    if (xOrigin || yOrigin || xOffset || yOffset) {
5217      tx = _round(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset);
5218      ty = _round(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset);
5219    }
5220
5221    if (xPercent || yPercent) {
5222      temp = target.getBBox();
5223      tx = _round(tx + xPercent / 100 * temp.width);
5224      ty = _round(ty + yPercent / 100 * temp.height);
5225    }
5226
5227    temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")";
5228    target.setAttribute("transform", temp);
5229    forceCSS && (target.style[_transformProp] = temp);
5230  },
5231      _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) {
5232    var cap = 360,
5233        isString = _isString(endValue),
5234        endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1),
5235        change = endNum - startNum,
5236        finalValue = startNum + change + "deg",
5237        direction,
5238        pt;
5239
5240    if (isString) {
5241      direction = endValue.split("_")[1];
5242
5243      if (direction === "short") {
5244        change %= cap;
5245
5246        if (change !== change % (cap / 2)) {
5247          change += change < 0 ? cap : -cap;
5248        }
5249      }
5250
5251      if (direction === "cw" && change < 0) {
5252        change = (change + cap * _bigNum$1) % cap - ~~(change / cap) * cap;
5253      } else if (direction === "ccw" && change > 0) {
5254        change = (change - cap * _bigNum$1) % cap - ~~(change / cap) * cap;
5255      }
5256    }
5257
5258    plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd);
5259    pt.e = finalValue;
5260    pt.u = "deg";
5261
5262    plugin._props.push(property);
5263
5264    return pt;
5265  },
5266      _assign = function _assign(target, source) {
5267    for (var p in source) {
5268      target[p] = source[p];
5269    }
5270
5271    return target;
5272  },
5273      _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) {
5274    var startCache = _assign({}, target._gsap),
5275        exclude = "perspective,force3D,transformOrigin,svgOrigin",
5276        style = target.style,
5277        endCache,
5278        p,
5279        startValue,
5280        endValue,
5281        startNum,
5282        endNum,
5283        startUnit,
5284        endUnit;
5285
5286    if (startCache.svg) {
5287      startValue = target.getAttribute("transform");
5288      target.setAttribute("transform", "");
5289      style[_transformProp] = transforms;
5290      endCache = _parseTransform(target, 1);
5291
5292      _removeProperty(target, _transformProp);
5293
5294      target.setAttribute("transform", startValue);
5295    } else {
5296      startValue = getComputedStyle(target)[_transformProp];
5297      style[_transformProp] = transforms;
5298      endCache = _parseTransform(target, 1);
5299      style[_transformProp] = startValue;
5300    }
5301
5302    for (p in _transformProps) {
5303      startValue = startCache[p];
5304      endValue = endCache[p];
5305
5306      if (startValue !== endValue && exclude.indexOf(p) < 0) {
5307        startUnit = getUnit(startValue);
5308        endUnit = getUnit(endValue);
5309        startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue);
5310        endNum = parseFloat(endValue);
5311        plugin._pt = new PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp);
5312        plugin._pt.u = endUnit || 0;
5313
5314        plugin._props.push(p);
5315      }
5316    }
5317
5318    _assign(endCache, startCache);
5319  };
5320
5321  _forEachName("padding,margin,Width,Radius", function (name, index) {
5322    var t = "Top",
5323        r = "Right",
5324        b = "Bottom",
5325        l = "Left",
5326        props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) {
5327      return index < 2 ? name + side : "border" + side + name;
5328    });
5329
5330    _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) {
5331      var a, vars;
5332
5333      if (arguments.length < 4) {
5334        a = props.map(function (prop) {
5335          return _get(plugin, prop, property);
5336        });
5337        vars = a.join(" ");
5338        return vars.split(a[0]).length === 5 ? a[0] : vars;
5339      }
5340
5341      a = (endValue + "").split(" ");
5342      vars = {};
5343      props.forEach(function (prop, i) {
5344        return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0];
5345      });
5346      plugin.init(target, vars, tween);
5347    };
5348  });
5349
5350  var CSSPlugin = {
5351    name: "css",
5352    register: _initCore,
5353    targetTest: function targetTest(target) {
5354      return target.style && target.nodeType;
5355    },
5356    init: function init(target, vars, tween, index, targets) {
5357      var props = this._props,
5358          style = target.style,
5359          startAt = tween.vars.startAt,
5360          startValue,
5361          endValue,
5362          endNum,
5363          startNum,
5364          type,
5365          specialProp,
5366          p,
5367          startUnit,
5368          endUnit,
5369          relative,
5370          isTransformRelated,
5371          transformPropTween,
5372          cache,
5373          smooth,
5374          hasPriority,
5375          inlineProps
vendor: 8,025 bytes, lines 5375-5562
5375;
5376      _pluginInitted || _initCore();
5377      this.styles = this.styles || _getStyleSaver(target);
5378      inlineProps = this.styles.props;
5379      this.tween = tween;
5380
5381      for (p in vars) {
5382        if (p === "autoRound") {
5383          continue;
5384        }
5385
5386        endValue = vars[p];
5387
5388        if (_plugins[p] && _checkPlugin(p, vars, tween, index, target, targets)) {
5389          continue;
5390        }
5391
5392        type = typeof endValue;
5393        specialProp = _specialProps[p];
5394
5395        if (type === "function") {
5396          endValue = endValue.call(tween, index, target, targets);
5397          type = typeof endValue;
5398        }
5399
5400        if (type === "string" && ~endValue.indexOf("random(")) {
5401          endValue = _replaceRandom(endValue);
5402        }
5403
5404        if (specialProp) {
5405          specialProp(this, target, p, endValue, tween) && (hasPriority = 1);
5406        } else if (p.substr(0, 2) === "--") {
5407          startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim();
5408          endValue += "";
5409          _colorExp.lastIndex = 0;
5410
5411          if (!_colorExp.test(startValue)) {
5412            startUnit = getUnit(startValue);
5413            endUnit = getUnit(endValue);
5414          }
5415
5416          endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit);
5417          this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p);
5418          props.push(p);
5419          inlineProps.push(p, 0, style[p]);
5420        } else if (type !== "undefined") {
5421          if (startAt && p in startAt) {
5422            startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p];
5423            _isString(startValue) && ~startValue.indexOf("random(") && (startValue = _replaceRandom(startValue));
5424            getUnit(startValue + "") || startValue === "auto" || (startValue += _config.units[p] || getUnit(_get(target, p)) || "");
5425            (startValue + "").charAt(1) === "=" && (startValue = _get(target, p));
5426          } else {
5427            startValue = _get(target, p);
5428          }
5429
5430          startNum = parseFloat(startValue);
5431          relative = type === "string" && endValue.charAt(1) === "=" && endValue.substr(0, 2);
5432          relative && (endValue = endValue.substr(2));
5433          endNum = parseFloat(endValue);
5434
5435          if (p in _propertyAliases) {
5436            if (p === "autoAlpha") {
5437              if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) {
5438                startNum = 0;
5439              }
5440
5441              inlineProps.push("visibility", 0, style.visibility);
5442
5443              _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum);
5444            }
5445
5446            if (p !== "scale" && p !== "transform") {
5447              p = _propertyAliases[p];
5448              ~p.indexOf(",") && (p = p.split(",")[0]);
5449            }
5450          }
5451
5452          isTransformRelated = p in _transformProps;
5453
5454          if (isTransformRelated) {
5455            this.styles.save(p);
5456
5457            if (!transformPropTween) {
5458              cache = target._gsap;
5459              cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform);
5460              smooth = vars.smoothOrigin !== false && cache.smooth;
5461              transformPropTween = this._pt = new PropTween(this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1);
5462              transformPropTween.dep = 1;
5463            }
5464
5465            if (p === "scale") {
5466              this._pt = new PropTween(this._pt, cache, "scaleY", cache.scaleY, (relative ? _parseRelative(cache.scaleY, relative + endNum) : endNum) - cache.scaleY || 0, _renderCSSProp);
5467              this._pt.u = 0;
5468              props.push("scaleY", p);
5469              p += "X";
5470            } else if (p === "transformOrigin") {
5471              inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]);
5472              endValue = _convertKeywordsToPercentages(endValue);
5473
5474              if (cache.svg) {
5475                _applySVGOrigin(target, endValue, 0, smooth, 0, this);
5476              } else {
5477                endUnit = parseFloat(endValue.split(" ")[2]) || 0;
5478                endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit);
5479
5480                _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue));
5481              }
5482
5483              continue;
5484            } else if (p === "svgOrigin") {
5485              _applySVGOrigin(target, endValue, 1, smooth, 0, this);
5486
5487              continue;
5488            } else if (p in _rotationalProperties) {
5489              _addRotationalPropTween(this, cache, p, startNum, relative ? _parseRelative(startNum, relative + endValue) : endValue);
5490
5491              continue;
5492            } else if (p === "smoothOrigin") {
5493              _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue);
5494
5495              continue;
5496            } else if (p === "force3D") {
5497              cache[p] = endValue;
5498              continue;
5499            } else if (p === "transform") {
5500              _addRawTransformPTs(this, endValue, target);
5501
5502              continue;
5503            }
5504          } else if (!(p in style)) {
5505            p = _checkPropPrefix(p) || p;
5506          }
5507
5508          if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) {
5509            startUnit = (startValue + "").substr((startNum + "").length);
5510            endNum || (endNum = 0);
5511            endUnit = getUnit(endValue) || (p in _config.units ? _config.units[p] : startUnit);
5512            startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit));
5513            this._pt = new PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, (relative ? _parseRelative(startNum, relative + endNum) : endNum) - startNum, !isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp);
5514            this._pt.u = endUnit || 0;
5515
5516            if (startUnit !== endUnit && endUnit !== "%") {
5517              this._pt.b = startValue;
5518              this._pt.r = _renderCSSPropWithBeginning;
5519            }
5520          } else if (!(p in style)) {
5521            if (p in target) {
5522              this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets);
5523            } else if (p !== "parseTransform") {
5524              _missingPlugin(p, endValue);
5525
5526              continue;
5527            }
5528          } else {
5529            _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue);
5530          }
5531
5532          isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : inlineProps.push(p, 1, startValue || target[p]));
5533          props.push(p);
5534        }
5535      }
5536
5537      hasPriority && _sortPropTweensByPriority(this);
5538    },
5539    render: function render(ratio, data) {
5540      if (data.tween._time || !_reverting$1()) {
5541        var pt = data._pt;
5542
5543        while (pt) {
5544          pt.r(ratio, pt.d);
5545          pt = pt._next;
5546        }
5547      } else {
5548        data.styles.revert();
5549      }
5550    },
5551    get: _get,
5552    aliases: _propertyAliases,
5553    getSetter: function getSetter(target, property, plugin) {
5554      var p = _propertyAliases[property];
5555      p && p.indexOf(",") < 0 && (property = p);
5556      return property in _transformProps && property !== _transformOriginProp && (target._gsap.x || _get(target, "x")) ? plugin && _recentSetterPlugin === plugin ? property === "scale" ? _setterScale : _setterTransform : (_recentSetterPlugin = plugin || {}) && (property === "scale" ? _setterScaleWithRender : _setterTransformWithRender) : target.style && !_isUndefined(target.style[property]) ? _setterCSSStyle : ~property.indexOf("-") ? _setterCSSProp : _getSetter(target, property);
5557    },
5558    core: {
5559      _removeProperty: _removeProperty,
5560      _getMatrix: _getMatrix
5561    }
5562  };
5563  gsap.utils.checkPrefix = _checkPropPrefix;
5564  gsap.core.getStyleSaver = _getStyleSaver;
5565
5566  (function (positionAndScale, rotation, others, aliases) {
5567    var all = _forEachName(positionAndScale + "," + rotation + "," + others, function (name) {
5568      _transformProps[name] = 1;
5569    });
5570
5571    _forEachName(rotation, function (name) {
5572      _config.units[name] = "deg";
5573      _rotationalProperties[name] = 1;
5574    });
5575
5576    _propertyAliases[all[13]] = positionAndScale + "," + rotation;
5577
5578    _forEachName(aliases, function (name) {
5579      var split = name.split(":");
5580      _propertyAliases[split[1]] = all[split[0]];
5581    });
5582  })("x,y,z,scale,scaleX,scaleY,xPercent,yPercent", "rotation,rotationX,rotationY,skewX,skewY", "transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective", "0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY");
5583
5584  _forEachName("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) {
5585    _config.units[name] = "px";
5586  });
5587
5588  gsap.registerPlugin(CSSPlugin);
5589
5590  var gsapWithCSS = gsap.registerPlugin(CSSPlugin) || gsap,
5591      TweenMaxWithCSS = gsapWithCSS.core.Tween;
5592
5593  exports.Back = Back;
5594  exports.Bounce = Bounce;
5595  exports.CSSPlugin = CSSPlugin;
5596  exports.Circ = Circ;
5597  exports.Cubic = Cubic;
5598  exports.Elastic = Elastic;
5599  exports.Expo = Expo;
5600  exports.Linear = Linear;
5601  exports.Power0 = Power0;
5602  exports.Power1 = Power1;
5603  exports.Power2 = Power2;
5604  exports.Power3 = Power3;
5605  exports.Power4 = Power4;
5606  exports.Quad = Quad;
5607  exports.Quart = Quart;
5608  exports.Quint = Quint;
5609  exports.Sine = Sine;
5610  exports.SteppedEase = SteppedEase;
5611  exports.Strong = Strong;
5612  exports.TimelineLite = Timeline;
5613  exports.TimelineMax = Timeline;
5614  exports.TweenLite = Tween;
5615  exports.TweenMax = TweenMaxWithCSS;
5616  exports.default = gsapWithCSS;
5617  exports.gsap = gsapWithCSS;
5618
5619  if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;}
5620
5621})));
5622"use strict";
5623
5624function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
5625function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
5626function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
5627function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
5628function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
5629function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
5630(function (global, factory) {
5631  (typeof exports === "undefined" ? "undefined" : _typeof(exports)) === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Lenis = factory());
5632})(void 0, function () {
5633  'use strict';
5634
5635  var version = "1.1.9";
5636
5637  // Clamp a value between a minimum and maximum value
5638  function clamp(min, input, max) {
5639    return Math.max(min, Math.min(input, max));
5640  }
5641
5642  // Linearly interpolate between two values using an amount (0 <= t <= 1)
5643  function lerp(x, y, t) {
5644    return (1 - t) * x + t * y;
5645  }
5646
5647  // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
5648  function damp(x, y, lambda, dt) {
5649    return lerp(x, y, 1 - Math.exp(-lambda * dt));
5650  }
5651
5652  // Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor
5653  // https://anguscroll.com/just/just-modulo
5654  function modulo(n, d) {
5655    return (n % d + d) % d;
5656  }
5657  var Animate = /*#__PURE__*/function () {
5658    function Animate() {
5659      _classCallCheck(this, Animate);
5660      this.isRunning = false;
5661      this.value = 0;
5662      this.from = 0;
5663      this.to = 0;
5664      this.duration = 0;
5665      this.currentTime = 0;
5666    }
5667    _createClass(Animate, [{
5668      key: "advance",
5669      value: function advance(deltaTime) {
5670        var _a;
5671        if (!this.isRunning) return;
5672        var completed = false;
5673        if (this.duration && this.easing) {
5674          this.currentTime += deltaTime;
5675          var linearProgress = clamp(0, this.currentTime / this.duration, 1);
5676          completed = linearProgress >= 1;
5677          var easedProgress = completed ? 1 : this.easing(linearProgress);
5678          this.value = this.from + (this.to - this.from) * easedProgress;
5679        } else if (this.lerp) {
5680          this.value = damp(this.value, this.to, this.lerp * 60, deltaTime);
5681          if (Math.round(this.value) === this.to) {
5682            this.value = this.to;
5683            completed = true;
5684          }
5685        } else {
5686          this.value = this.to;
5687          completed = true;
5688        }
5689        if (completed) {
5690          this.stop();
5691        }
5692        (_a = this.onUpdate) === null || _a === void 0 ? void 0 : _a.call(this, this.value, completed);
5693      }
5694    }, {
5695      key: "stop",
5696      value: function stop() {
5697        this.isRunning = false;
5698      }
5699    }, {
5700      key: "fromTo",
5701      value: function fromTo(from, to, _ref) {
5702        var lerp = _ref.lerp,
5703          duration = _ref.duration,
5704          easing = _ref.easing,
5705          onStart = _ref.onStart,
5706          onUpdate = _ref.onUpdate;
5707        this.from = this.value = from;
5708        this.to = to;
5709        this.lerp = lerp;
5710        this.duration = duration;
5711        this.easing = easing;
5712        this.currentTime = 0;
5713        this.isRunning = true;
5714        onStart === null || onStart === void 0 ? void 0 : onStart();
5715        this.onUpdate = onUpdate;
5716      }
5717    }]);
5718    return Animate;
5719  }();
5720  function debounce(callback, delay) {
5721    var timer;
5722    return function () {
5723      var args = arguments;
5724      var context = this;
5725      clearTimeout(timer);
5726      timer = setTimeout(function () {
5727        callback.apply(context, args);
5728      }, delay);
5729    };
5730  }
5731  var Dimensions = /*#__PURE__*/function () {
5732    function Dimensions() {
5733      var _this = this;
5734      var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
5735        wrapper = _ref2.wrapper,
5736        content = _ref2.content,
5737        _ref2$autoResize = _ref2.autoResize,
5738        autoResize = _ref2$autoResize === void 0 ? true : _ref2$autoResize,
5739        _ref2$debounce = _ref2.debounce,
5740        debounceValue = _ref2$debounce === void 0 ? 250 : _ref2$debounce;
5741      _classCallCheck(this, Dimensions);
5742      this.width = 0;
5743      this.height = 0;
5744      this.scrollWidth = 0;
5745      this.scrollHeight = 0;
5746      this.resize = function () {
5747        _this.onWrapperResize();
5748        _this.onContentResize();
5749      };
5750      this.onWrapperResize = function () {
5751        if (_this.wrapper === window) {
5752          _this.width = window.innerWidth;
5753          _this.height = window.innerHeight;
5754        } else if (_this.wrapper instanceof HTMLElement) {
5755          _this.width = _this.wrapper.clientWidth;
5756          _this.height = _this.wrapper.clientHeight;
5757        }
5758      };
5759      this.onContentResize = function () {
5760        if (_this.wrapper === window) {
5761          _this.scrollHeight = _this.content.scrollHeight;
5762          _this.scrollWidth = _this.content.scrollWidth;
5763        } else if (_this.wrapper instanceof HTMLElement) {
5764          _this.scrollHeight = _this.wrapper.scrollHeight;
5765          _this.scrollWidth = _this.wrapper.scrollWidth;
5766        }
5767      };
5768      this.wrapper = wrapper;
5769      this.content = content;
5770      if (autoResize) {
5771        this.debouncedResize = debounce(this.resize, debounceValue);
5772        if (this.wrapper === window) {
5773          window.addEventListener('resize', this.debouncedResize, false);
5774        } else {
5775          this.wrapperResizeObserver = new ResizeObserver(this.debouncedResize);
5776          this.wrapperResizeObserver.observe(this.wrapper);
5777        }
5778        this.contentResizeObserver = new ResizeObserver(this.debouncedResize);
5779        this.contentResizeObserver.observe(this.content);
5780      }
5781      this.resize();
5782    }
5783    _createClass(Dimensions, [{
5784      key: "destroy",
5785      value: function destroy() {
5786        var _a, _b;
5787        (_a = this.wrapperResizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
5788        (_b = this.contentResizeObserver) === null || _b === void 0 ? void 0 : _b.disconnect();
5789        window.removeEventListener('resize', this.debouncedResize, false);
5790      }
5791    }, {
5792      key: "limit",
5793      get: function get() {
5794        return {
5795          x: this.scrollWidth - this.width,
5796          y: this.scrollHeight - this.height
5797        };
5798      }
5799    }]);
5800    return Dimensions;
5801  }();
5802  var Emitter = /*#__PURE__*/function () {
5803    function Emitter() {
5804      _classCallCheck(this, Emitter);
5805      this.events = {};
5806    }
5807    _createClass(Emitter, [{
5808      key: "emit",
5809      value: function emit(event) {
5810        var callbacks = this.events[event] || [];
5811        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
5812          args[_key - 1] = arguments[_key];
5813        }
5814        for (var i = 0, length = callbacks.length; i < length; i++) {
5815          callbacks[i].apply(callbacks, args);
5816        }
5817      }
5818    }, {
5819      key: "on",
5820      value: function on(event, callback) {
5821        var _this2 = this;
5822        var _a;
5823        ((_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.push(callback)) || (this.events[event] = [callback]);
5824        return function () {
5825          var _a;
5826          _this2.events[event] = (_a = _this2.events[event]) === null || _a === void 0 ? void 0 : _a.filter(function (i) {
5827            return callback !== i;
5828          });
5829        };
5830      }
5831    }, {
5832      key: "off",
5833      value: function off(event, callback) {
5834        var _a;
5835        this.events[event] = (_a = this.events[event]) === null || _a === void 0 ? void 0 : _a.filter(function (i) {
5836          return callback !== i;
5837        });
5838      }
5839    }, {
5840      key: "destroy",
5841      value: function destroy() {
5842        this.events = {};
5843      }
5844    }]);
5845    return Emitter;
5846  }();
5847  var LINE_HEIGHT = 100 / 6;
5848  var VirtualScroll = /*#__PURE__*/function () {
5849    function VirtualScroll(element, _ref3) {
5850      var _this3 = this;
5851      var _ref3$wheelMultiplier = _ref3.wheelMultiplier,
5852        wheelMultiplier = _ref3$wheelMultiplier === void 0 ? 1 : _ref3$wheelMultiplier,
5853        _ref3$touchMultiplier = _ref3.touchMultiplier,
5854        touchMultiplier = _ref3$touchMultiplier === void 0 ? 1 : _ref3$touchMultiplier;
5855      _classCallCheck(this, VirtualScroll);
5856      this.lastDelta = {
5857        x: 0,
5858        y: 0
5859      };
5860      this.windowWidth = 0;
5861      this.windowHeight = 0;
5862      this.onTouchStart = function (event) {
5863        var _ref4 = event.targetTouches ? event.targetTouches[0] : event,
5864          clientX = _ref4.clientX,
5865          clientY = _ref4.clientY;
5866        _this3.touchStart.x = clientX;
5867        _this3.touchStart.y = clientY;
5868        _this3.lastDelta = {
5869          x: 0,
5870          y: 0
5871        };
5872        _this3.emitter.emit('scroll', {
5873          deltaX: 0,
5874          deltaY: 0,
5875          event: event
5876        });
5877      };
5878      this.onTouchMove = function (event) {
5879        var _a, _b, _c, _d;
5880        var _ref5 = event.targetTouches ? event.targetTouches[0] : event,
5881          clientX = _ref5.clientX,
5882          clientY = _ref5.clientY;
5883        var deltaX = -(clientX - ((_b = (_a = _this3.touchStart) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0)) * _this3.touchMultiplier;
5884        var deltaY = -(clientY - ((_d = (_c = _this3.touchStart) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0)) * _this3.touchMultiplier;
5885        _this3.touchStart.x = clientX;
5886        _this3.touchStart.y = clientY;
5887        _this3.lastDelta = {
5888          x: deltaX,
5889          y: deltaY
5890        };
5891        _this3.emitter.emit('scroll', {
5892          deltaX: deltaX,
5893          deltaY: deltaY,
5894          event: event
5895        });
5896      };
5897      this.onTouchEnd = function (event) {
5898        _this3.emitter.emit('scroll', {
5899          deltaX: _this3.lastDelta.x,
5900          deltaY: _this3.lastDelta.y,
5901          event: event
5902        });
5903      };
5904      this.onWheel = function (event) {
5905        var deltaX = event.deltaX,
5906          deltaY = event.deltaY,
5907          deltaMode = event.deltaMode;
5908        var multiplierX = deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? _this3.windowWidth : 1;
5909        var multiplierY = deltaMode === 1 ? LINE_HEIGHT : deltaMode === 2 ? _this3.windowHeight : 1;
5910        deltaX *= multiplierX;
5911        deltaY *= multiplierY;
5912        deltaX *= _this3.wheelMultiplier;
5913        deltaY *= _this3.wheelMultiplier;
5914        _this3.emitter.emit('scroll', {
5915          deltaX: deltaX,
5916          deltaY: deltaY,
5917          event: event
5918        });
5919      };
5920      this.onWindowResize = function () {
5921        _this3.windowWidth = window.innerWidth;
5922        _this3.windowHeight = window.innerHeight;
5923      };
5924      this.element = element;
5925      this.wheelMultiplier = wheelMultiplier;
5926      this.touchMultiplier = touchMultiplier;
5927      this.touchStart = {
5928        x: null,
5929        y: null
5930      };
5931      this.emitter = new Emitter();
5932      window.addEventListener('resize', this.onWindowResize, false);
5933      this.onWindowResize();
5934      this.element.addEventListener('wheel', this.onWheel, {
5935        passive: false
5936      });
5937      this.element.addEventListener('touchstart', this.onTouchStart, {
5938        passive: false
5939      });
5940      this.element.addEventListener('touchmove', this.onTouchMove, {
5941        passive: false
5942      });
5943      this.element.addEventListener('touchend', this.onTouchEnd, {
5944        passive: false
5945      });
5946    }
5947    _createClass(VirtualScroll, [{
5948      key: "on",
5949      value: function on(event, callback) {
5950        return this.emitter.on(event, callback);
5951      }
5952    }, {
5953      key: "destroy",
5954      value: function destroy() {
5955        this.emitter.destroy();
5956        window.removeEventListener('resize', this.onWindowResize, false);
5957        this.element.removeEventListener('wheel', this.onWheel);
5958        this.element.removeEventListener('touchstart', this.onTouchStart);
5959        this.element.removeEventListener('touchmove', this.onTouchMove);
5960        this.element.removeEventListener('touchend', this.onTouchEnd);
5961      }
5962    }]);
5963    return VirtualScroll;
5964  }();
5965  var Lenis = /*#__PURE__*/function () {
5966    function Lenis() {
5967      var _this4 = this;
5968      var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
5969        _ref6$wrapper = _ref6.wrapper,
5970        wrapper = _ref6$wrapper === void 0 ? window : _ref6$wrapper,
5971        _ref6$content = _ref6.content,
5972        content = _ref6$content === void 0 ? document.documentElement : _ref6$content,
5973        _ref6$wheelEventsTarg = _ref6.wheelEventsTarget,
5974        wheelEventsTarget = _ref6$wheelEventsTarg === void 0 ? wrapper : _ref6$wheelEventsTarg,
5975        _ref6$eventsTarget = _ref6.eventsTarget,
5976        eventsTarget = _ref6$eventsTarget === void 0 ? wheelEventsTarget : _ref6$eventsTarget,
5977        _ref6$smoothWheel = _ref6.smoothWheel,
5978        smoothWheel = _ref6$smoothWheel === void 0 ? true : _ref6$smoothWheel,
5979        _ref6$syncTouch = _ref6.syncTouch,
5980        syncTouch = _ref6$syncTouch === void 0 ? false : _ref6$syncTouch,
5981        _ref6$syncTouchLerp = _ref6.syncTouchLerp,
5982        syncTouchLerp = _ref6$syncTouchLerp === void 0 ? 0.075 : _ref6$syncTouchLerp,
5983        _ref6$touchInertiaMul = _ref6.touchInertiaMultiplier,
5984        touchInertiaMultiplier = _ref6$touchInertiaMul === void 0 ? 35 : _ref6$touchInertiaMul,
5985        duration = _ref6.duration,
5986        _ref6$easing = _ref6.easing,
5987        easing = _ref6$easing === void 0 ? function (t) {
5988          return Math.min(1, 1.001 - Math.pow(2, -10 * t));
5989        } : _ref6$easing,
5990        _ref6$lerp = _ref6.lerp,
5991        lerp = _ref6$lerp === void 0 ? 0.1 : _ref6$lerp,
5992        _ref6$infinite = _ref6.infinite,
5993        infinite = _ref6$infinite === void 0 ? false : _ref6$infinite,
5994        _ref6$orientation = _ref6.orientation,
5995        orientation = _ref6$orientation === void 0 ? 'vertical' : _ref6$orientation,
5996        _ref6$gestureOrientat = _ref6.gestureOrientation,
5997        gestureOrientation = _ref6$gestureOrientat === void 0 ? 'vertical' : _ref6$gestureOrientat,
5998        _ref6$touchMultiplier = _ref6.touchMultiplier,
5999        touchMultiplier = _ref6$touchMultiplier === void 0 ? 1 : _ref6$touchMultiplier,
6000        _ref6$wheelMultiplier = _ref6.wheelMultiplier,
6001        wheelMultiplier = _ref6$wheelMultiplier === void 0 ? 1 : _ref6$wheelMultiplier,
6002        _ref6$autoResize = _ref6.autoResize,
6003        autoResize = _ref6$autoResize === void 0 ? true : _ref6$autoResize,
6004        prevent = _ref6.prevent,
6005        virtualScroll = _ref6.virtualScroll,
6006        _ref6$__experimental_ = _ref6.__experimental__naiveDimensions,
6007        __experimental__naiveDimensions = _ref6$__experimental_ === void 0 ? false : _ref6$__experimental_;
6008      _classCallCheck(this, Lenis);
6009      this.__isScrolling = false;
6010      this.__isStopped = false;
6011      this.__isLocked = false;
6012      this.userData = {};
6013      this.lastVelocity = 0;
6014      this.velocity = 0;
6015      this.direction = 0;
6016      this.onPointerDown = function (event) {
6017        if (event.button === 1) {
6018          _this4.reset();
6019        }
6020      };
6021      this.onVirtualScroll = function (data) {
6022        if (typeof _this4.options.virtualScroll === 'function' && _this4.options.virtualScroll(data) === false) return;
6023        var deltaX = data.deltaX,
6024          deltaY = data.deltaY,
6025          event = data.event;
6026        _this4.emitter.emit('virtual-scroll', {
6027          deltaX: deltaX,
6028          deltaY: deltaY,
6029          event: event
6030        });
6031        if (event.ctrlKey) return;
6032        var isTouch = event.type.includes('touch');
6033        var isWheel = event.type.includes('wheel');
6034        _this4.isTouching = event.type === 'touchstart' || event.type === 'touchmove';
6035        var isTapToStop = _this4.options.syncTouch && isTouch && event.type === 'touchstart' && !_this4.isStopped && !_this4.isLocked;
6036        if (isTapToStop) {
6037          _this4.reset();
6038          return;
6039        }
6040        var isClick = deltaX === 0 && deltaY === 0;
6041        var isUnknownGesture = _this4.options.gestureOrientation === 'vertical' && deltaY === 0 || _this4.options.gestureOrientation === 'horizontal' && deltaX === 0;
6042        if (isClick || isUnknownGesture) {
6043          return;
6044        }
6045        var composedPath = event.composedPath();
6046        composedPath = composedPath.slice(0, composedPath.indexOf(_this4.rootElement));
6047        var prevent = _this4.options.prevent;
6048        if (!!composedPath.find(function (node) {
6049          var _a, _b, _c, _d, _e;
6050          return node instanceof Element && (typeof prevent === 'function' && (prevent === null || prevent === void 0 ? void 0 : prevent(node)) || ((_a = node.hasAttribute) === null || _a === void 0 ? void 0 : _a.call(node, 'data-lenis-prevent')) || isTouch && ((_b = node.hasAttribute) === null || _b === void 0 ? void 0 : _b.call(node, 'data-lenis-prevent-touch')) || isWheel && ((_c = node.hasAttribute) === null || _c === void 0 ? void 0 : _c.call(node, 'data-lenis-prevent-wheel')) || ((_d = node.classList) === null || _d === void 0 ? void 0 : _d.contains('lenis')) && !((_e = node.classList) === null || _e === void 0 ? void 0 : _e.contains('lenis-stopped')));
6051        })) return;
6052        if (_this4.isStopped || _this4.isLocked) {
6053          event.preventDefault();
6054          return;
6055        }
6056        var isSmooth = _this4.options.syncTouch && isTouch || _this4.options.smoothWheel && isWheel;
6057        if (!isSmooth) {
6058          _this4.isScrolling = 'native';
6059          _this4.animate.stop();
6060          return;
6061        }
6062        event.preventDefault();
6063        var delta = deltaY;
6064        if (_this4.options.gestureOrientation === 'both') {
6065          delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX;
6066        } else if (_this4.options.gestureOrientation === 'horizontal') {
6067          delta = deltaX;
6068        }
6069        var syncTouch = isTouch && _this4.options.syncTouch;
6070        var isTouchEnd = isTouch && event.type === 'touchend';
6071        var hasTouchInertia = isTouchEnd && Math.abs(delta) > 5;
6072        if (hasTouchInertia) {
6073          delta = _this4.velocity * _this4.options.touchInertiaMultiplier;
6074        }
6075        _this4.scrollTo(_this4.targetScroll + delta, Object.assign({
6076          programmatic: false
6077        }, syncTouch ? {
6078          lerp: hasTouchInertia ? _this4.options.syncTouchLerp : 1
6079        } : {
6080          lerp: _this4.options.lerp,
6081          duration: _this4.options.duration,
6082          easing: _this4.options.easing
6083        }));
6084      };
6085      this.onNativeScroll = function () {
6086        clearTimeout(_this4.__resetVelocityTimeout);
6087        delete _this4.__resetVelocityTimeout;
6088        if (_this4.__preventNextNativeScrollEvent) {
6089          delete _this4.__preventNextNativeScrollEvent;
6090          return;
6091        }
6092        if (_this4.isScrolling === false || _this4.isScrolling === 'native') {
6093          var lastScroll = _this4.animatedScroll;
6094          _this4.animatedScroll = _this4.targetScroll = _this4.actualScroll;
6095          _this4.lastVelocity = _this4.velocity;
6096          _this4.velocity = _this4.animatedScroll - lastScroll;
6097          _this4.direction = Math.sign(_this4.animatedScroll - lastScroll);
6098          _this4.isScrolling = 'native';
6099          _this4.emit();
6100          if (_this4.velocity !== 0) {
6101            _this4.__resetVelocityTimeout = setTimeout(function () {
6102              _this4.lastVelocity = _this4.velocity;
6103              _this4.velocity = 0;
6104              _this4.isScrolling = false;
6105              _this4.emit();
6106            }, 400);
6107          }
6108        }
6109      };
6110      window.lenisVersion = version;
6111      if (!wrapper || wrapper === document.documentElement || wrapper === document.body) {
6112        wrapper = window;
6113      }
6114      this.options = {
6115        wrapper: wrapper,
6116        content: content,
6117        wheelEventsTarget: wheelEventsTarget,
6118        eventsTarget: eventsTarget,
6119        smoothWheel: smoothWheel,
6120        syncTouch: syncTouch,
6121        syncTouchLerp: syncTouchLerp,
6122        touchInertiaMultiplier: touchInertiaMultiplier,
6123        duration: duration,
6124        easing: easing,
6125        lerp: lerp,
6126        infinite: infinite,
6127        gestureOrientation: gestureOrientation,
6128        orientation: orientation,
6129        touchMultiplier: touchMultiplier,
6130        wheelMultiplier: wheelMultiplier,
6131        autoResize: autoResize,
6132        prevent: prevent,
6133        virtualScroll: virtualScroll,
6134        __experimental__naiveDimensions: __experimental__naiveDimensions
6135      };
6136      this.animate = new Animate();
6137      this.emitter = new Emitter();
6138      this.dimensions = new Dimensions({
6139        wrapper: wrapper,
6140        content: content,
6141        autoResize: autoResize
6142      });
6143      this.updateClassName();
6144      this.userData = {};
6145      this.time = 0;
6146      this.velocity = this.lastVelocity = 0;
6147      this.isLocked = false;
6148      this.isStopped = false;
6149      this.isScrolling = false;
6150      this.targetScroll = this.animatedScroll = this.actualScroll;
6151      this.options.wrapper.addEventListener('scroll', this.onNativeScroll, false);
6152      this.options.wrapper.addEventListener('pointerdown', this.onPointerDown, false);
6153      this.virtualScroll = new VirtualScroll(eventsTarget, {
6154        touchMultiplier: touchMultiplier,
6155        wheelMultiplier: wheelMultiplier
6156      });
6157      this.virtualScroll.on('scroll', this.onVirtualScroll);
6158    }
6159    _createClass(Lenis, [{
6160      key: "destroy",
6161      value: function destroy() {
6162        this.emitter.destroy();
6163        this.options.wrapper.removeEventListener('scroll', this.onNativeScroll, false);
6164        this.options.wrapper.removeEventListener('pointerdown', this.onPointerDown, false);
6165        this.virtualScroll.destroy();
6166        this.dimensions.destroy();
6167        this.cleanUpClassName();
6168      }
6169    }, {
6170      key: "on",
6171      value: function on(event, callback) {
6172        return this.emitter.on(event, callback);
6173      }
6174    }, {
6175      key: "off",
6176      value: function off(event, callback) {
6177        return this.emitter.off(event, callback);
6178      }
6179    }, {
6180      key: "setScroll",
6181      value: function setScroll(scroll) {
6182        if (this.isHorizontal) {
6183          this.rootElement.scrollLeft = scroll;
6184        } else {
6185          this.rootElement.scrollTop = scroll;
6186        }
6187      }
6188    }, {
6189      key: "resize",
6190      value: function resize() {
6191        this.dimensions.resize();
6192      }
6193    }, {
6194      key: "emit",
6195      value: function emit() {
6196        this.emitter.emit('scroll', this);
6197      }
6198    }, {
6199      key: "reset",
6200      value: function reset() {
6201        this.isLocked = false;
6202        this.isScrolling = false;
6203        this.animatedScroll = this.targetScroll = this.actualScroll;
6204        this.lastVelocity = this.velocity = 0;
6205        this.animate.stop();
6206      }
6207    }, {
6208      key: "start",
6209      value: function start() {
6210        if (!this.isStopped) return;
6211        this.isStopped = false;
6212        this.reset();
6213      }
6214    }, {
6215      key: "stop",
6216      value: function stop() {
6217        if (this.isStopped) return;
6218        this.isStopped = true;
6219        this.animate.stop();
6220        this.reset();
6221      }
6222    }, {
6223      key: "raf",
6224      value: function raf(time) {
6225        var deltaTime = time - (this.time || time);
6226        this.time = time;
6227        this.animate.advance(deltaTime * 0.001);
6228      }
6229    }, {
6230      key: "scrollTo",
6231      value: function scrollTo(target) {
6232        var _this5 = this;
6233        var _ref7 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
6234          _ref7$offset = _ref7.offset,
6235          offset = _ref7$offset === void 0 ? 0 : _ref7$offset,
6236          _ref7$immediate = _ref7.immediate,
6237          immediate = _ref7$immediate === void 0 ? false : _ref7$immediate,
6238          _ref7$lock = _ref7.lock,
6239          lock = _ref7$lock === void 0 ? false : _ref7$lock,
6240          _ref7$duration = _ref7.duration,
6241          duration = _ref7$duration === void 0 ? this.options.duration : _ref7$duration,
6242          _ref7$easing = _ref7.easing,
6243          easing = _ref7$easing === void 0 ? this.options.easing : _ref7$easing,
6244          _ref7$lerp = _ref7.lerp,
6245          lerp = _ref7$lerp === void 0 ? this.options.lerp : _ref7$lerp,
6246          _onStart = _ref7.onStart,
6247          onComplete = _ref7.onComplete,
6248          _ref7$force = _ref7.force,
6249          force = _ref7$force === void 0 ? false : _ref7$force,
6250          _ref7$programmatic = _ref7.programmatic,
6251          programmatic = _ref7$programmatic === void 0 ? true : _ref7$programmatic,
6252          _ref7$userData = _ref7.userData,
6253          userData = _ref7$userData === void 0 ? {} : _ref7$userData;
6254        if ((this.isStopped || this.isLocked) && !force) return;
6255        if (typeof target === 'string' && ['top', 'left', 'start'].includes(target)) {
6256          target = 0;
6257        } else if (typeof target === 'string' && ['bottom', 'right', 'end'].includes(target)) {
6258          target = this.limit;
6259        } else {
6260          var node;
6261          if (typeof target === 'string') {
6262            node = document.querySelector(target);
6263          } else if (target instanceof HTMLElement && (target === null || target === void 0 ? void 0 : target.nodeType)) {
6264            node = target;
6265          }
6266          if (node) {
6267            if (this.options.wrapper !== window) {
6268              var wrapperRect = this.rootElement.getBoundingClientRect();
6269              offset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top;
6270            }
6271            var rect = node.getBoundingClientRect();
6272            target = (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll;
6273          }
6274        }
6275        if (typeof target !== 'number') return;
6276        target += offset;
6277        target = Math.round(target);
6278        if (this.options.infinite) {
6279          if (programmatic) {
6280            this.targetScroll = this.animatedScroll = this.scroll;
6281          }
6282        } else {
6283          target = clamp(0, target, this.limit);
6284        }
6285        if (target === this.targetScroll) return;
6286        this.userData = userData;
6287        if (immediate) {
6288          this.animatedScroll = this.targetScroll = target;
6289          this.setScroll(this.scroll);
6290          this.reset();
6291          this.preventNextNativeScrollEvent();
6292          this.emit();
6293          onComplete === null || onComplete === void 0 ? void 0 : onComplete(this);
6294          this.userData = {};
6295          return;
6296        }
6297        if (!programmatic) {
6298          this.targetScroll = target;
6299        }
6300        this.animate.fromTo(this.animatedScroll, target, {
6301          duration: duration,
6302          easing: easing,
6303          lerp: lerp,
6304          onStart: function onStart() {
6305            if (lock) _this5.isLocked = true;
6306            _this5.isScrolling = 'smooth';
6307            _onStart === null || _onStart === void 0 ? void 0 : _onStart(_this5);
6308          },
6309          onUpdate: function onUpdate(value, completed) {
6310            _this5.isScrolling = 'smooth';
6311            _this5.lastVelocity = _this5.velocity;
6312            _this5.velocity = value - _this5.animatedScroll;
6313            _this5.direction = Math.sign(_this5.velocity);
6314            _this5.animatedScroll = value;
6315            _this5.setScroll(_this5.scroll);
6316            if (programmatic) {
6317              _this5.targetScroll = value;
6318            }
6319            if (!completed) _this5.emit();
6320            if (completed) {
6321              _this5.reset();
6322              _this5.emit();
6323              onComplete === null || onComplete === void 0 ? void 0 : onComplete(_this5);
6324              _this5.userData = {};
6325              _this5.preventNextNativeScrollEvent();
6326            }
6327          }
6328        });
6329      }
6330    }, {
6331      key: "preventNextNativeScrollEvent",
6332      value: function preventNextNativeScrollEvent() {
6333        var _this6 = this;
6334        this.__preventNextNativeScrollEvent = true;
6335        requestAnimationFrame(function () {
6336          delete _this6.__preventNextNativeScrollEvent;
6337        });
6338      }
6339    }, {
6340      key: "rootElement",
6341      get: function get() {
6342        return this.options.wrapper === window ? document.documentElement : this.options.wrapper;
6343      }
6344    }, {
6345      key: "limit",
6346      get: function get() {
6347        if (this.options.__experimental__naiveDimensions) {
6348          if (this.isHorizontal) {
6349            return this.rootElement.scrollWidth - this.rootElement.clientWidth;
6350          } else {
6351            return this.rootElement.scrollHeight - this.rootElement.clientHeight;
6352          }
6353        } else {
6354          return this.dimensions.limit[this.isHorizontal ? 'x' : 'y'];
6355        }
6356      }
6357    }, {
6358      key: "isHorizontal",
6359      get: function get() {
6360        return this.options.orientation === 'horizontal';
6361      }
6362    }, {
6363      key: "actualScroll",
6364      get: function get() {
6365        return this.isHorizontal ? this.rootElement.scrollLeft : this.rootElement.scrollTop;
6366      }
6367    }, {
6368      key: "scroll",
6369      get: function get() {
6370        return this.options.infinite ? modulo(this.animatedScroll, this.limit) : this.animatedScroll;
6371      }
6372    }, {
6373      key: "progress",
6374      get: function get() {
6375        return this.limit === 0 ? 1 : this.scroll / this.limit;
6376      }
6377    }, {
6378      key: "isScrolling",
6379      get: function get() {
6380        return this.__isScrolling;
6381      },
6382      set: function set(value) {
6383        if (this.__isScrolling !== value) {
6384          this.__isScrolling = value;
6385          this.updateClassName();
6386        }
6387      }
6388    }, {
6389      key: "isStopped",
6390      get: function get() {
6391        return this.__isStopped;
6392      },
6393      set: function set(value) {
6394        if (this.__isStopped !== value) {
6395          this.__isStopped = value;
6396          this.updateClassName();
6397        }
6398      }
6399    }, {
6400      key: "isLocked",
6401      get: function get() {
6402        return this.__isLocked;
6403      },
6404      set: function set(value) {
6405        if (this.__isLocked !== value) {
6406          this.__isLocked = value;
6407          this.updateClassName();
6408        }
6409      }
6410    }, {
6411      key: "isSmooth",
6412      get: function get() {
6413        return this.isScrolling === 'smooth';
6414      }
6415    }, {
6416      key: "className",
6417      get: function get() {
6418        var className = 'lenis';
6419        if (this.isStopped) className += ' lenis-stopped';
6420        if (this.isLocked) className += ' lenis-locked';
6421        if (this.isScrolling) className += ' lenis-scrolling';
6422        if (this.isScrolling === 'smooth') className += ' lenis-smooth';
6423        return className;
6424      }
6425    }, {
6426      key: "updateClassName",
6427      value: function updateClassName() {
6428        this.cleanUpClassName();
6429        this.rootElement.className = "".concat(this.rootElement.className, " ").concat(this.className).trim();
6430      }
6431    }, {
6432      key: "cleanUpClassName",
6433      value: function cleanUpClassName() {
6434        this.rootElement.className = this.rootElement.className.replace(/lenis(-\w+)?/g, '').trim();
6435      }
6436    }]);
6437    return Lenis;
6438  }();
6439  return Lenis;
6440});
6441(function(window, $) {
6442  "use strict";
6443
6444  var counter = 0,
6445    $headCache = $('head'),
6446    oldBigText = window.BigText,
6447    oldjQueryMethod = $.fn.bigtext,
6448    BigText = {
6449      DEBUG_MODE: false,
6450      DEFAULT_MIN_FONT_SIZE_PX: null,
6451      DEFAULT_MAX_FONT_SIZE_PX: 1056,
6452      GLOBAL_STYLE_ID: 'bigtext-style',
6453      STYLE_ID: 'bigtext-id',
6454      LINE_CLASS_PREFIX: 'bigtext-line',
6455      EXEMPT_CLASS: 'bigtext-exempt',
6456      noConflict: function(restore)
6457      {
6458        if(restore) {
6459          $.fn.bigtext = oldjQueryMethod;
6460          window.BigText = oldBigText;
6461        }
6462        return BigText;
6463      },
6464      supports: {
6465        wholeNumberFontSizeOnly: (function() {
6466          if( !( 'getComputedStyle' in window ) ) {
6467            return true;
6468          }
6469          var test = $('<div/>').css({
6470              position: 'absolute',
6471              'font-size': '14.1px'
6472            }).insertBefore( $('script').eq(0) ),
6473            computedStyle = window.getComputedStyle( test[0], null );
6474
6475          var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px';
6476          test.remove();
6477          return ret;
6478        })()
6479      },
6480      init: function() {
6481        if(!$('#'+BigText.GLOBAL_STYLE_ID).length) {
6482          $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }',
6483                                          '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }']));
6484        }
6485      },
6486      bindResize: function(eventName, resizeFunction) {
6487        var timeoutId;
6488        $(window).off(eventName).on(eventName, function() {
6489          if( timeoutId ) {
6490            clearTimeout( timeoutId );
6491          }
6492          timeoutId = setTimeout( resizeFunction, 100 );
6493        });
6494      },
6495      getStyleId: function(id)
6496      {
6497        return BigText.STYLE_ID + '-' + id;
6498      },
6499      generateStyleTag: function(id, css)
6500      {
6501        return $('<style>' + css.join('\n') + '</style>').attr('id', id);
6502      },
6503      clearCss: function(id)
6504      {
6505        var styleId = BigText.getStyleId(id);
6506        $('#' + styleId).remove();
6507      },
6508      generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes)
6509      {
6510        var css = [];
6511
6512        BigText.clearCss(id);
6513
6514        for(var j=0, k=linesFontSizes.length; j<k; j++) {
6515          css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' +
6516            (minFontSizes[j] ? ' white-space: normal;' : '') +
6517            (linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') +
6518            (lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') +
6519            '}');
6520        }
6521
6522        return BigText.generateStyleTag(BigText.getStyleId(id), css);
6523      },
6524      jQueryMethod: function(options)
6525      {
6526        BigText.init();
6527
6528        options = $.extend({
6529          minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX,
6530          maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX,
6531          childSelector: '',
6532          resize: true
6533        }, options || {});
6534
6535        this.each(function()
6536        {
6537          var $t = $(this).addClass('bigtext'),
6538            maxWidth = $t.width(),
6539            id = $t.attr('id'),
6540            $children = options.childSelector ? $t.find( options.childSelector ) : $t.children();
6541
6542          if(!id) {
6543            id = 'bigtext-id' + (counter++);
6544            $t.attr('id', id);
6545          }
6546
6547          if(options.resize) {
6548            BigText.bindResize('resize.bigtext-event-' + id, function()
6549            {
6550              // TODO only call this if the width has changed.
6551              BigText.jQueryMethod.call($('#' + id), options);
6552            });
6553          }
6554
6555          BigText.clearCss(id);
6556
6557          $children.addClass(function(lineNumber, className)
6558          {
6559            // remove existing line classes.
6560            return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''),
6561                BigText.LINE_CLASS_PREFIX + lineNumber].join(' ');
6562          });
6563
6564          var sizes = BigText.calculateSizes($t, $children, maxWidth, options.maxfontsize, options.minfontsize);
6565          $headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes));
6566        });
6567
6568        return this.trigger('bigtext:complete');
6569      },
6570      testLineDimensions: function($line, maxWidth, property, size, interval, units, previousWidth)
6571      {
6572        var width;
6573        previousWidth = typeof previousWidth === 'number' ? previousWidth : 0;
6574        $line.css(property, size + units);
6575
6576        width = $line.width();
6577
6578        if(width >= maxWidth) {
6579    // console.log(width, ' previous: ' + previousWidth, property + ' at ' + interval, 'prior: ' + (parseFloat(size) - interval), 'new:' + parseFloat(size));
6580          $line.css(property, '');
6581
6582          if(width === maxWidth) {
6583            return {
6584              match: 'exact',
6585              size: parseFloat((parseFloat(size) - 0.1).toFixed(3))
6586            };
6587          }
6588
6589          // Since this is an estimate, we calculate how far over the width we went with the new value.
6590          // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value.
6591          // Otherwise, we revert to the underestimate.
6592          var under = maxWidth - previousWidth,
6593            over = width - maxWidth;
6594
6595          return {
6596            match: 'estimate',
6597            size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3))
6598          };
6599        }
6600
6601        return width;
6602      },
6603      calculateSizes: function($t, $children, maxWidth, maxFontSize, minFontSize)
6604      {
6605        var $c = $t.clone(true)
6606          .addClass('bigtext-cloned')
6607          .css({
6608            fontFamily: $t.css('font-family'),
6609            textTransform: $t.css('text-transform'),
6610            wordSpacing: $t.css('word-spacing'),
6611            letterSpacing: $t.css('letter-spacing'),
6612            position: 'absolute',
6613            left: BigText.DEBUG_MODE ? 0 : -9999,
6614            top: BigText.DEBUG_MODE ? 0 : -9999
6615          })
6616          .appendTo(document.body);
6617
6618        // font-size isn't the only thing we can modify, we can also mess with:
6619        // word-spacing and letter-spacing. WebKit does not respect subpixel
6620        // letter-spacing, word-spacing, or font-size.
6621        // TODO try -webkit-transform: scale() as a workaround.
6622        var fontSizes = [],
6623          wordSpacings = [],
6624          minFontSizes = [],
6625          ratios = [];
6626
6627        $children.css('float', 'left').each(function() {
6628          var $line = $(this),
6629            // TODO replace 8, 4 with a proportional size to the calculated font-size.
6630            intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1],
6631            lineMax,
6632            newFontSize;
6633
6634          if($line.hasClass(BigText.EXEMPT_CLASS)) {
6635            fontSizes.push(null);
6636            ratios.push(null);
6637            minFontSizes.push(false);
6638            return;
6639          }
6640
6641          // TODO we can cache this ratio?
6642          var autoGuessSubtraction = 32, // font size in px
6643            currentFontSize = parseFloat($line.css('font-size')),
6644            ratio = ( $line.width() / currentFontSize ).toFixed(6);
6645
6646          newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction;
6647
6648          outer: for(var m=0, n=intervals.length; m<n; m++) {
6649            inner: for(var j=1, k=10; j<=k; j++) {
6650              if(newFontSize + j*intervals[m] > maxFontSize) {
6651                newFontSize = maxFontSize;
6652                break outer;
6653              }
6654
6655              lineMax = BigText.testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax);
6656              if(typeof lineMax !== 'number') {
6657                newFontSize = lineMax.size;
6658
6659                if(lineMax.match === 'exact') {
6660                  break outer;
6661                }
6662                break inner;
6663              }
6664            }
6665          }
6666
6667          ratios.push(maxWidth / newFontSize);
6668
6669          if(newFontSize > maxFontSize) {
6670            fontSizes.push(maxFontSize);
6671            minFontSizes.push(false);
6672          } else if(!!minFontSize && newFontSize < minFontSize) {
6673            fontSizes.push(minFontSize);
6674            minFontSizes.push(true);
6675          } else {
6676            fontSizes.push(newFontSize);
6677            minFontSizes.push(false);
6678          }
6679        }).each(function(lineNumber) {
6680          var $line = $(this),
6681            wordSpacing = 0,
6682            interval = 1,
6683            maxWordSpacing;
6684
6685          if($line.hasClass(BigText.EXEMPT_CLASS)) {
6686            wordSpacings.push(null);
6687            return;
6688          }
6689
6690          // must re-use font-size, even though it was removed above.
6691          $line.css('font-size', fontSizes[lineNumber] + 'px');
6692
6693          for(var m=1, n=3; m<n; m+=interval) {
6694            maxWordSpacing = BigText.testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px', maxWordSpacing);
6695            if(typeof maxWordSpacing !== 'number') {
6696              wordSpacing = maxWordSpacing.size;
6697              break;
6698            }
6699          }
6700
6701          $line.css('font-size', '');
6702          wordSpacings.push(wordSpacing);
6703        }).removeAttr('style');
6704
6705        if( !BigText.DEBUG_MODE ) {
6706          $c.remove();
6707        } else {
6708          $c.css({
6709            'background-color': 'rgba(255,255,255,.4)'
6710          });
6711        }
6712
6713        return {
6714          fontSizes: fontSizes,
6715          wordSpacings: wordSpacings,
6716          ratios: ratios,
6717          minFontSizes: minFontSizes
6718        };
6719      }
6720    };
6721
6722  $.fn.bigtext = BigText.jQueryMethod;
6723  window.BigText = BigText;
6724
6725})(this, jQuery);
vendor: 16,093 bytes, lines 6726-7383
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
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: 75,264 bytes, lines 7386-10291
7386
7387      return;
7388    }
7389    // add elem if no selector
7390    if ( !selector ) {
7391      ffElems.push( elem );
7392      return;
7393    }
7394    // filter & find items if we have a selector
7395    // filter
7396    if ( matchesSelector( elem, selector ) ) {
7397      ffElems.push( elem );
7398    }
7399    // find children
7400    var childElems = elem.querySelectorAll( selector );
7401    // concat childElems to filterFound array
7402    for ( var i=0; i < childElems.length; i++ ) {
7403      ffElems.push( childElems[i] );
7404    }
7405  });
7406
7407  return ffElems;
7408};
7409
7410// ----- debounceMethod ----- //
7411
7412utils.debounceMethod = function( _class, methodName, threshold ) {
7413  threshold = threshold || 100;
7414  // original method
7415  var method = _class.prototype[ methodName ];
7416  var timeoutName = methodName + 'Timeout';
7417
7418  _class.prototype[ methodName ] = function() {
7419    var timeout = this[ timeoutName ];
7420    clearTimeout( timeout );
7421
7422    var args = arguments;
7423    var _this = this;
7424    this[ timeoutName ] = setTimeout( function() {
7425      method.apply( _this, args );
7426      delete _this[ timeoutName ];
7427    }, threshold );
7428  };
7429};
7430
7431// ----- docReady ----- //
7432
7433utils.docReady = function( callback ) {
7434  var readyState = document.readyState;
7435  if ( readyState == 'complete' || readyState == 'interactive' ) {
7436    // do async to allow for other scripts to run. metafizzy/flickity#441
7437    setTimeout( callback );
7438  } else {
7439    document.addEventListener( 'DOMContentLoaded', callback );
7440  }
7441};
7442
7443// ----- htmlInit ----- //
7444
7445// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
7446utils.toDashed = function( str ) {
7447  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
7448    return $1 + '-' + $2;
7449  }).toLowerCase();
7450};
7451
7452var console = window.console;
7453/**
7454 * allow user to initialize classes via [data-namespace] or .js-namespace class
7455 * htmlInit( Widget, 'widgetName' )
7456 * options are parsed from data-namespace-options
7457 */
7458utils.htmlInit = function( WidgetClass, namespace ) {
7459  utils.docReady( function() {
7460    var dashedNamespace = utils.toDashed( namespace );
7461    var dataAttr = 'data-' + dashedNamespace;
7462    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
7463    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
7464    var elems = utils.makeArray( dataAttrElems )
7465      .concat( utils.makeArray( jsDashElems ) );
7466    var dataOptionsAttr = dataAttr + '-options';
7467    var jQuery = window.jQuery;
7468
7469    elems.forEach( function( elem ) {
7470      var attr = elem.getAttribute( dataAttr ) ||
7471        elem.getAttribute( dataOptionsAttr );
7472      var options;
7473      try {
7474        options = attr && JSON.parse( attr );
7475      } catch ( error ) {
7476        // log error, do not initialize
7477        if ( console ) {
7478          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
7479          ': ' + error );
7480        }
7481        return;
7482      }
7483      // initialize
7484      var instance = new WidgetClass( elem, options );
7485      // make available via $().data('namespace')
7486      if ( jQuery ) {
7487        jQuery.data( elem, namespace, instance );
7488      }
7489    });
7490
7491  });
7492};
7493
7494// -----  ----- //
7495
7496return utils;
7497
7498}));
7499
7500/**
7501 * Outlayer Item
7502 */
7503
7504( function( window, factory ) {
7505  // universal module definition
7506  /* jshint strict: false */ /* globals define, module, require */
7507  if ( typeof define == 'function' && define.amd ) {
7508    // AMD - RequireJS
7509    define( 'outlayer/item',[
7510        'ev-emitter/ev-emitter',
7511        'get-size/get-size'
7512      ],
7513      factory
7514    );
7515  } else if ( typeof module == 'object' && module.exports ) {
7516    // CommonJS - Browserify, Webpack
7517    module.exports = factory(
7518      require('ev-emitter'),
7519      require('get-size')
7520    );
7521  } else {
7522    // browser global
7523    window.Outlayer = {};
7524    window.Outlayer.Item = factory(
7525      window.EvEmitter,
7526      window.getSize
7527    );
7528  }
7529
7530}( window, function factory( EvEmitter, getSize ) {
7531'use strict';
7532
7533// ----- helpers ----- //
7534
7535function isEmptyObj( obj ) {
7536  for ( var prop in obj ) {
7537    return false;
7538  }
7539  prop = null;
7540  return true;
7541}
7542
7543// -------------------------- CSS3 support -------------------------- //
7544
7545
7546var docElemStyle = document.documentElement.style;
7547
7548var transitionProperty = typeof docElemStyle.transition == 'string' ?
7549  'transition' : 'WebkitTransition';
7550var transformProperty = typeof docElemStyle.transform == 'string' ?
7551  'transform' : 'WebkitTransform';
7552
7553var transitionEndEvent = {
7554  WebkitTransition: 'webkitTransitionEnd',
7555  transition: 'transitionend'
7556}[ transitionProperty ];
7557
7558// cache all vendor properties that could have vendor prefix
7559var vendorProperties = {
7560  transform: transformProperty,
7561  transition: transitionProperty,
7562  transitionDuration: transitionProperty + 'Duration',
7563  transitionProperty: transitionProperty + 'Property',
7564  transitionDelay: transitionProperty + 'Delay'
7565};
7566
7567// -------------------------- Item -------------------------- //
7568
7569function Item( element, layout ) {
7570  if ( !element ) {
7571    return;
7572  }
7573
7574  this.element = element;
7575  // parent layout class, i.e. Masonry, Isotope, or Packery
7576  this.layout = layout;
7577  this.position = {
7578    x: 0,
7579    y: 0
7580  };
7581
7582  this._create();
7583}
7584
7585// inherit EvEmitter
7586var proto = Item.prototype = Object.create( EvEmitter.prototype );
7587proto.constructor = Item;
7588
7589proto._create = function() {
7590  // transition objects
7591  this._transn = {
7592    ingProperties: {},
7593    clean: {},
7594    onEnd: {}
7595  };
7596
7597  this.css({
7598    position: 'absolute'
7599  });
7600};
7601
7602// trigger specified handler for event type
7603proto.handleEvent = function( event ) {
7604  var method = 'on' + event.type;
7605  if ( this[ method ] ) {
7606    this[ method ]( event );
7607  }
7608};
7609
7610proto.getSize = function() {
7611  this.size = getSize( this.element );
7612};
7613
7614/**
7615 * apply CSS styles to element
7616 * @param {Object} style
7617 */
7618proto.css = function( style ) {
7619  var elemStyle = this.element.style;
7620
7621  for ( var prop in style ) {
7622    // use vendor property if available
7623    var supportedProp = vendorProperties[ prop ] || prop;
7624    elemStyle[ supportedProp ] = style[ prop ];
7625  }
7626};
7627
7628 // measure position, and sets it
7629proto.getPosition = function() {
7630  var style = getComputedStyle( this.element );
7631  var isOriginLeft = this.layout._getOption('originLeft');
7632  var isOriginTop = this.layout._getOption('originTop');
7633  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
7634  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
7635  var x = parseFloat( xValue );
7636  var y = parseFloat( yValue );
7637  // convert percent to pixels
7638  var layoutSize = this.layout.size;
7639  if ( xValue.indexOf('%') != -1 ) {
7640    x = ( x / 100 ) * layoutSize.width;
7641  }
7642  if ( yValue.indexOf('%') != -1 ) {
7643    y = ( y / 100 ) * layoutSize.height;
7644  }
7645  // clean up 'auto' or other non-integer values
7646  x = isNaN( x ) ? 0 : x;
7647  y = isNaN( y ) ? 0 : y;
7648  // remove padding from measurement
7649  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
7650  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
7651
7652  this.position.x = x;
7653  this.position.y = y;
7654};
7655
7656// set settled position, apply padding
7657proto.layoutPosition = function() {
7658  var layoutSize = this.layout.size;
7659  var style = {};
7660  var isOriginLeft = this.layout._getOption('originLeft');
7661  var isOriginTop = this.layout._getOption('originTop');
7662
7663  // x
7664  var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight';
7665  var xProperty = isOriginLeft ? 'left' : 'right';
7666  var xResetProperty = isOriginLeft ? 'right' : 'left';
7667
7668  var x = this.position.x + layoutSize[ xPadding ];
7669  // set in percentage or pixels
7670  style[ xProperty ] = this.getXValue( x );
7671  // reset other property
7672  style[ xResetProperty ] = '';
7673
7674  // y
7675  var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom';
7676  var yProperty = isOriginTop ? 'top' : 'bottom';
7677  var yResetProperty = isOriginTop ? 'bottom' : 'top';
7678
7679  var y = this.position.y + layoutSize[ yPadding ];
7680  // set in percentage or pixels
7681  style[ yProperty ] = this.getYValue( y );
7682  // reset other property
7683  style[ yResetProperty ] = '';
7684
7685  this.css( style );
7686  this.emitEvent( 'layout', [ this ] );
7687};
7688
7689proto.getXValue = function( x ) {
7690  var isHorizontal = this.layout._getOption('horizontal');
7691  return this.layout.options.percentPosition && !isHorizontal ?
7692    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
7693};
7694
7695proto.getYValue = function( y ) {
7696  var isHorizontal = this.layout._getOption('horizontal');
7697  return this.layout.options.percentPosition && isHorizontal ?
7698    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
7699};
7700
7701proto._transitionTo = function( x, y ) {
7702  this.getPosition();
7703  // get current x & y from top/left
7704  var curX = this.position.x;
7705  var curY = this.position.y;
7706
7707  var didNotMove = x == this.position.x && y == this.position.y;
7708
7709  // save end position
7710  this.setPosition( x, y );
7711
7712  // if did not move and not transitioning, just go to layout
7713  if ( didNotMove && !this.isTransitioning ) {
7714    this.layoutPosition();
7715    return;
7716  }
7717
7718  var transX = x - curX;
7719  var transY = y - curY;
7720  var transitionStyle = {};
7721  transitionStyle.transform = this.getTranslate( transX, transY );
7722
7723  this.transition({
7724    to: transitionStyle,
7725    onTransitionEnd: {
7726      transform: this.layoutPosition
7727    },
7728    isCleaning: true
7729  });
7730};
7731
7732proto.getTranslate = function( x, y ) {
7733  // flip cooridinates if origin on right or bottom
7734  var isOriginLeft = this.layout._getOption('originLeft');
7735  var isOriginTop = this.layout._getOption('originTop');
7736  x = isOriginLeft ? x : -x;
7737  y = isOriginTop ? y : -y;
7738  return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
7739};
7740
7741// non transition + transform support
7742proto.goTo = function( x, y ) {
7743  this.setPosition( x, y );
7744  this.layoutPosition();
7745};
7746
7747proto.moveTo = proto._transitionTo;
7748
7749proto.setPosition = function( x, y ) {
7750  this.position.x = parseFloat( x );
7751  this.position.y = parseFloat( y );
7752};
7753
7754// ----- transition ----- //
7755
7756/**
7757 * @param {Object} style - CSS
7758 * @param {Function} onTransitionEnd
7759 */
7760
7761// non transition, just trigger callback
7762proto._nonTransition = function( args ) {
7763  this.css( args.to );
7764  if ( args.isCleaning ) {
7765    this._removeStyles( args.to );
7766  }
7767  for ( var prop in args.onTransitionEnd ) {
7768    args.onTransitionEnd[ prop ].call( this );
7769  }
7770};
7771
7772/**
7773 * proper transition
7774 * @param {Object} args - arguments
7775 *   @param {Object} to - style to transition to
7776 *   @param {Object} from - style to start transition from
7777 *   @param {Boolean} isCleaning - removes transition styles after transition
7778 *   @param {Function} onTransitionEnd - callback
7779 */
7780proto.transition = function( args ) {
7781  // redirect to nonTransition if no transition duration
7782  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
7783    this._nonTransition( args );
7784    return;
7785  }
7786
7787  var _transition = this._transn;
7788  // keep track of onTransitionEnd callback by css property
7789  for ( var prop in args.onTransitionEnd ) {
7790    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
7791  }
7792  // keep track of properties that are transitioning
7793  for ( prop in args.to ) {
7794    _transition.ingProperties[ prop ] = true;
7795    // keep track of properties to clean up when transition is done
7796    if ( args.isCleaning ) {
7797      _transition.clean[ prop ] = true;
7798    }
7799  }
7800
7801  // set from styles
7802  if ( args.from ) {
7803    this.css( args.from );
7804    // force redraw. http://blog.alexmaccaw.com/css-transitions
7805    var h = this.element.offsetHeight;
7806    // hack for JSHint to hush about unused var
7807    h = null;
7808  }
7809  // enable transition
7810  this.enableTransition( args.to );
7811  // set styles that are transitioning
7812  this.css( args.to );
7813
7814  this.isTransitioning = true;
7815
7816};
7817
7818// dash before all cap letters, including first for
7819// WebkitTransform => -webkit-transform
7820function toDashedAll( str ) {
7821  return str.replace( /([A-Z])/g, function( $1 ) {
7822    return '-' + $1.toLowerCase();
7823  });
7824}
7825
7826var transitionProps = 'opacity,' + toDashedAll( transformProperty );
7827
7828proto.enableTransition = function(/* style */) {
7829  // HACK changing transitionProperty during a transition
7830  // will cause transition to jump
7831  if ( this.isTransitioning ) {
7832    return;
7833  }
7834
7835  // make `transition: foo, bar, baz` from style object
7836  // HACK un-comment this when enableTransition can work
7837  // while a transition is happening
7838  // var transitionValues = [];
7839  // for ( var prop in style ) {
7840  //   // dash-ify camelCased properties like WebkitTransition
7841  //   prop = vendorProperties[ prop ] || prop;
7842  //   transitionValues.push( toDashedAll( prop ) );
7843  // }
7844  // munge number to millisecond, to match stagger
7845  var duration = this.layout.options.transitionDuration;
7846  duration = typeof duration == 'number' ? duration + 'ms' : duration;
7847  // enable transition styles
7848  this.css({
7849    transitionProperty: transitionProps,
7850    transitionDuration: duration,
7851    transitionDelay: this.staggerDelay || 0
7852  });
7853  // listen for transition end event
7854  this.element.addEventListener( transitionEndEvent, this, false );
7855};
7856
7857// ----- events ----- //
7858
7859proto.onwebkitTransitionEnd = function( event ) {
7860  this.ontransitionend( event );
7861};
7862
7863proto.onotransitionend = function( event ) {
7864  this.ontransitionend( event );
7865};
7866
7867// properties that I munge to make my life easier
7868var dashedVendorProperties = {
7869  '-webkit-transform': 'transform'
7870};
7871
7872proto.ontransitionend = function( event ) {
7873  // disregard bubbled events from children
7874  if ( event.target !== this.element ) {
7875    return;
7876  }
7877  var _transition = this._transn;
7878  // get property name of transitioned property, convert to prefix-free
7879  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
7880
7881  // remove property that has completed transitioning
7882  delete _transition.ingProperties[ propertyName ];
7883  // check if any properties are still transitioning
7884  if ( isEmptyObj( _transition.ingProperties ) ) {
7885    // all properties have completed transitioning
7886    this.disableTransition();
7887  }
7888  // clean style
7889  if ( propertyName in _transition.clean ) {
7890    // clean up style
7891    this.element.style[ event.propertyName ] = '';
7892    delete _transition.clean[ propertyName ];
7893  }
7894  // trigger onTransitionEnd callback
7895  if ( propertyName in _transition.onEnd ) {
7896    var onTransitionEnd = _transition.onEnd[ propertyName ];
7897    onTransitionEnd.call( this );
7898    delete _transition.onEnd[ propertyName ];
7899  }
7900
7901  this.emitEvent( 'transitionEnd', [ this ] );
7902};
7903
7904proto.disableTransition = function() {
7905  this.removeTransitionStyles();
7906  this.element.removeEventListener( transitionEndEvent, this, false );
7907  this.isTransitioning = false;
7908};
7909
7910/**
7911 * removes style property from element
7912 * @param {Object} style
7913**/
7914proto._removeStyles = function( style ) {
7915  // clean up transition styles
7916  var cleanStyle = {};
7917  for ( var prop in style ) {
7918    cleanStyle[ prop ] = '';
7919  }
7920  this.css( cleanStyle );
7921};
7922
7923var cleanTransitionStyle = {
7924  transitionProperty: '',
7925  transitionDuration: '',
7926  transitionDelay: ''
7927};
7928
7929proto.removeTransitionStyles = function() {
7930  // remove transition
7931  this.css( cleanTransitionStyle );
7932};
7933
7934// ----- stagger ----- //
7935
7936proto.stagger = function( delay ) {
7937  delay = isNaN( delay ) ? 0 : delay;
7938  this.staggerDelay = delay + 'ms';
7939};
7940
7941// ----- show/hide/remove ----- //
7942
7943// remove element from DOM
7944proto.removeElem = function() {
7945  this.element.parentNode.removeChild( this.element );
7946  // remove display: none
7947  this.css({ display: '' });
7948  this.emitEvent( 'remove', [ this ] );
7949};
7950
7951proto.remove = function() {
7952  // just remove element if no transition support or no transition
7953  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
7954    this.removeElem();
7955    return;
7956  }
7957
7958  // start transition
7959  this.once( 'transitionEnd', function() {
7960    this.removeElem();
7961  });
7962  this.hide();
7963};
7964
7965proto.reveal = function() {
7966  delete this.isHidden;
7967  // remove display: none
7968  this.css({ display: '' });
7969
7970  var options = this.layout.options;
7971
7972  var onTransitionEnd = {};
7973  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
7974  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
7975
7976  this.transition({
7977    from: options.hiddenStyle,
7978    to: options.visibleStyle,
7979    isCleaning: true,
7980    onTransitionEnd: onTransitionEnd
7981  });
7982};
7983
7984proto.onRevealTransitionEnd = function() {
7985  // check if still visible
7986  // during transition, item may have been hidden
7987  if ( !this.isHidden ) {
7988    this.emitEvent('reveal');
7989  }
7990};
7991
7992/**
7993 * get style property use for hide/reveal transition end
7994 * @param {String} styleProperty - hiddenStyle/visibleStyle
7995 * @returns {String}
7996 */
7997proto.getHideRevealTransitionEndProperty = function( styleProperty ) {
7998  var optionStyle = this.layout.options[ styleProperty ];
7999  // use opacity
8000  if ( optionStyle.opacity ) {
8001    return 'opacity';
8002  }
8003  // get first property
8004  for ( var prop in optionStyle ) {
8005    return prop;
8006  }
8007};
8008
8009proto.hide = function() {
8010  // set flag
8011  this.isHidden = true;
8012  // remove display: none
8013  this.css({ display: '' });
8014
8015  var options = this.layout.options;
8016
8017  var onTransitionEnd = {};
8018  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
8019  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
8020
8021  this.transition({
8022    from: options.visibleStyle,
8023    to: options.hiddenStyle,
8024    // keep hidden stuff hidden
8025    isCleaning: true,
8026    onTransitionEnd: onTransitionEnd
8027  });
8028};
8029
8030proto.onHideTransitionEnd = function() {
8031  // check if still hidden
8032  // during transition, item may have been un-hidden
8033  if ( this.isHidden ) {
8034    this.css({ display: 'none' });
8035    this.emitEvent('hide');
8036  }
8037};
8038
8039proto.destroy = function() {
8040  this.css({
8041    position: '',
8042    left: '',
8043    right: '',
8044    top: '',
8045    bottom: '',
8046    transition: '',
8047    transform: ''
8048  });
8049};
8050
8051return Item;
8052
8053}));
8054
8055/*!
8056 * Outlayer v2.1.1
8057 * the brains and guts of a layout library
8058 * MIT license
8059 */
8060
8061( function( window, factory ) {
8062  'use strict';
8063  // universal module definition
8064  /* jshint strict: false */ /* globals define, module, require */
8065  if ( typeof define == 'function' && define.amd ) {
8066    // AMD - RequireJS
8067    define( 'outlayer/outlayer',[
8068        'ev-emitter/ev-emitter',
8069        'get-size/get-size',
8070        'fizzy-ui-utils/utils',
8071        './item'
8072      ],
8073      function( EvEmitter, getSize, utils, Item ) {
8074        return factory( window, EvEmitter, getSize, utils, Item);
8075      }
8076    );
8077  } else if ( typeof module == 'object' && module.exports ) {
8078    // CommonJS - Browserify, Webpack
8079    module.exports = factory(
8080      window,
8081      require('ev-emitter'),
8082      require('get-size'),
8083      require('fizzy-ui-utils'),
8084      require('./item')
8085    );
8086  } else {
8087    // browser global
8088    window.Outlayer = factory(
8089      window,
8090      window.EvEmitter,
8091      window.getSize,
8092      window.fizzyUIUtils,
8093      window.Outlayer.Item
8094    );
8095  }
8096
8097}( window, function factory( window, EvEmitter, getSize, utils, Item ) {
8098'use strict';
8099
8100// ----- vars ----- //
8101
8102var console = window.console;
8103var jQuery = window.jQuery;
8104var noop = function() {};
8105
8106// -------------------------- Outlayer -------------------------- //
8107
8108// globally unique identifiers
8109var GUID = 0;
8110// internal store of all Outlayer intances
8111var instances = {};
8112
8113
8114/**
8115 * @param {Element, String} element
8116 * @param {Object} options
8117 * @constructor
8118 */
8119function Outlayer( element, options ) {
8120  var queryElement = utils.getQueryElement( element );
8121  if ( !queryElement ) {
8122    if ( console ) {
8123      console.error( 'Bad element for ' + this.constructor.namespace +
8124        ': ' + ( queryElement || element ) );
8125    }
8126    return;
8127  }
8128  this.element = queryElement;
8129  // add jQuery
8130  if ( jQuery ) {
8131    this.$element = jQuery( this.element );
8132  }
8133
8134  // options
8135  this.options = utils.extend( {}, this.constructor.defaults );
8136  this.option( options );
8137
8138  // add id for Outlayer.getFromElement
8139  var id = ++GUID;
8140  this.element.outlayerGUID = id; // expando
8141  instances[ id ] = this; // associate via id
8142
8143  // kick it off
8144  this._create();
8145
8146  var isInitLayout = this._getOption('initLayout');
8147  if ( isInitLayout ) {
8148    this.layout();
8149  }
8150}
8151
8152// settings are for internal use only
8153Outlayer.namespace = 'outlayer';
8154Outlayer.Item = Item;
8155
8156// default options
8157Outlayer.defaults = {
8158  containerStyle: {
8159    position: 'relative'
8160  },
8161  initLayout: true,
8162  originLeft: true,
8163  originTop: true,
8164  resize: true,
8165  resizeContainer: true,
8166  // item options
8167  transitionDuration: '0.4s',
8168  hiddenStyle: {
8169    opacity: 0,
8170    transform: 'scale(0.001)'
8171  },
8172  visibleStyle: {
8173    opacity: 1,
8174    transform: 'scale(1)'
8175  }
8176};
8177
8178var proto = Outlayer.prototype;
8179// inherit EvEmitter
8180utils.extend( proto, EvEmitter.prototype );
8181
8182/**
8183 * set options
8184 * @param {Object} opts
8185 */
8186proto.option = function( opts ) {
8187  utils.extend( this.options, opts );
8188};
8189
8190/**
8191 * get backwards compatible option value, check old name
8192 */
8193proto._getOption = function( option ) {
8194  var oldOption = this.constructor.compatOptions[ option ];
8195  return oldOption && this.options[ oldOption ] !== undefined ?
8196    this.options[ oldOption ] : this.options[ option ];
8197};
8198
8199Outlayer.compatOptions = {
8200  // currentName: oldName
8201  initLayout: 'isInitLayout',
8202  horizontal: 'isHorizontal',
8203  layoutInstant: 'isLayoutInstant',
8204  originLeft: 'isOriginLeft',
8205  originTop: 'isOriginTop',
8206  resize: 'isResizeBound',
8207  resizeContainer: 'isResizingContainer'
8208};
8209
8210proto._create = function() {
8211  // get items from children
8212  this.reloadItems();
8213  // elements that affect layout, but are not laid out
8214  this.stamps = [];
8215  this.stamp( this.options.stamp );
8216  // set container style
8217  utils.extend( this.element.style, this.options.containerStyle );
8218
8219  // bind resize method
8220  var canBindResize = this._getOption('resize');
8221  if ( canBindResize ) {
8222    this.bindResize();
8223  }
8224};
8225
8226// goes through all children again and gets bricks in proper order
8227proto.reloadItems = function() {
8228  // collection of item elements
8229  this.items = this._itemize( this.element.children );
8230};
8231
8232
8233/**
8234 * turn elements into Outlayer.Items to be used in layout
8235 * @param {Array or NodeList or HTMLElement} elems
8236 * @returns {Array} items - collection of new Outlayer Items
8237 */
8238proto._itemize = function( elems ) {
8239
8240  var itemElems = this._filterFindItemElements( elems );
8241  var Item = this.constructor.Item;
8242
8243  // create new Outlayer Items for collection
8244  var items = [];
8245  for ( var i=0; i < itemElems.length; i++ ) {
8246    var elem = itemElems[i];
8247    var item = new Item( elem, this );
8248    items.push( item );
8249  }
8250
8251  return items;
8252};
8253
8254/**
8255 * get item elements to be used in layout
8256 * @param {Array or NodeList or HTMLElement} elems
8257 * @returns {Array} items - item elements
8258 */
8259proto._filterFindItemElements = function( elems ) {
8260  return utils.filterFindElements( elems, this.options.itemSelector );
8261};
8262
8263/**
8264 * getter method for getting item elements
8265 * @returns {Array} elems - collection of item elements
8266 */
8267proto.getItemElements = function() {
8268  return this.items.map( function( item ) {
8269    return item.element;
8270  });
8271};
8272
8273// ----- init & layout ----- //
8274
8275/**
8276 * lays out all items
8277 */
8278proto.layout = function() {
8279  this._resetLayout();
8280  this._manageStamps();
8281
8282  // don't animate first layout
8283  var layoutInstant = this._getOption('layoutInstant');
8284  var isInstant = layoutInstant !== undefined ?
8285    layoutInstant : !this._isLayoutInited;
8286  this.layoutItems( this.items, isInstant );
8287
8288  // flag for initalized
8289  this._isLayoutInited = true;
8290};
8291
8292// _init is alias for layout
8293proto._init = proto.layout;
8294
8295/**
8296 * logic before any new layout
8297 */
8298proto._resetLayout = function() {
8299  this.getSize();
8300};
8301
8302
8303proto.getSize = function() {
8304  this.size = getSize( this.element );
8305};
8306
8307/**
8308 * get measurement from option, for columnWidth, rowHeight, gutter
8309 * if option is String -> get element from selector string, & get size of element
8310 * if option is Element -> get size of element
8311 * else use option as a number
8312 *
8313 * @param {String} measurement
8314 * @param {String} size - width or height
8315 * @private
8316 */
8317proto._getMeasurement = function( measurement, size ) {
8318  var option = this.options[ measurement ];
8319  var elem;
8320  if ( !option ) {
8321    // default to 0
8322    this[ measurement ] = 0;
8323  } else {
8324    // use option as an element
8325    if ( typeof option == 'string' ) {
8326      elem = this.element.querySelector( option );
8327    } else if ( option instanceof HTMLElement ) {
8328      elem = option;
8329    }
8330    // use size of element, if element
8331    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
8332  }
8333};
8334
8335/**
8336 * layout a collection of item elements
8337 * @api public
8338 */
8339proto.layoutItems = function( items, isInstant ) {
8340  items = this._getItemsForLayout( items );
8341
8342  this._layoutItems( items, isInstant );
8343
8344  this._postLayout();
8345};
8346
8347/**
8348 * get the items to be laid out
8349 * you may want to skip over some items
8350 * @param {Array} items
8351 * @returns {Array} items
8352 */
8353proto._getItemsForLayout = function( items ) {
8354  return items.filter( function( item ) {
8355    return !item.isIgnored;
8356  });
8357};
8358
8359/**
8360 * layout items
8361 * @param {Array} items
8362 * @param {Boolean} isInstant
8363 */
8364proto._layoutItems = function( items, isInstant ) {
8365  this._emitCompleteOnItems( 'layout', items );
8366
8367  if ( !items || !items.length ) {
8368    // no items, emit event with empty array
8369    return;
8370  }
8371
8372  var queue = [];
8373
8374  items.forEach( function( item ) {
8375    // get x/y object from method
8376    var position = this._getItemLayoutPosition( item );
8377    // enqueue
8378    position.item = item;
8379    position.isInstant = isInstant || item.isLayoutInstant;
8380    queue.push( position );
8381  }, this );
8382
8383  this._processLayoutQueue( queue );
8384};
8385
8386/**
8387 * get item layout position
8388 * @param {Outlayer.Item} item
8389 * @returns {Object} x and y position
8390 */
8391proto._getItemLayoutPosition = function( /* item */ ) {
8392  return {
8393    x: 0,
8394    y: 0
8395  };
8396};
8397
8398/**
8399 * iterate over array and position each item
8400 * Reason being - separating this logic prevents 'layout invalidation'
8401 * thx @paul_irish
8402 * @param {Array} queue
8403 */
8404proto._processLayoutQueue = function( queue ) {
8405  this.updateStagger();
8406  queue.forEach( function( obj, i ) {
8407    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i );
8408  }, this );
8409};
8410
8411// set stagger from option in milliseconds number
8412proto.updateStagger = function() {
8413  var stagger = this.options.stagger;
8414  if ( stagger === null || stagger === undefined ) {
8415    this.stagger = 0;
8416    return;
8417  }
8418  this.stagger = getMilliseconds( stagger );
8419  return this.stagger;
8420};
8421
8422/**
8423 * Sets position of item in DOM
8424 * @param {Outlayer.Item} item
8425 * @param {Number} x - horizontal position
8426 * @param {Number} y - vertical position
8427 * @param {Boolean} isInstant - disables transitions
8428 */
8429proto._positionItem = function( item, x, y, isInstant, i ) {
8430  if ( isInstant ) {
8431    // if not transition, just set CSS
8432    item.goTo( x, y );
8433  } else {
8434    item.stagger( i * this.stagger );
8435    item.moveTo( x, y );
8436  }
8437};
8438
8439/**
8440 * Any logic you want to do after each layout,
8441 * i.e. size the container
8442 */
8443proto._postLayout = function() {
8444  this.resizeContainer();
8445};
8446
8447proto.resizeContainer = function() {
8448  var isResizingContainer = this._getOption('resizeContainer');
8449  if ( !isResizingContainer ) {
8450    return;
8451  }
8452  var size = this._getContainerSize();
8453  if ( size ) {
8454    this._setContainerMeasure( size.width, true );
8455    this._setContainerMeasure( size.height, false );
8456  }
8457};
8458
8459/**
8460 * Sets width or height of container if returned
8461 * @returns {Object} size
8462 *   @param {Number} width
8463 *   @param {Number} height
8464 */
8465proto._getContainerSize = noop;
8466
8467/**
8468 * @param {Number} measure - size of width or height
8469 * @param {Boolean} isWidth
8470 */
8471proto._setContainerMeasure = function( measure, isWidth ) {
8472  if ( measure === undefined ) {
8473    return;
8474  }
8475
8476  var elemSize = this.size;
8477  // add padding and border width if border box
8478  if ( elemSize.isBorderBox ) {
8479    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
8480      elemSize.borderLeftWidth + elemSize.borderRightWidth :
8481      elemSize.paddingBottom + elemSize.paddingTop +
8482      elemSize.borderTopWidth + elemSize.borderBottomWidth;
8483  }
8484
8485  measure = Math.max( measure, 0 );
8486  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
8487};
8488
8489/**
8490 * emit eventComplete on a collection of items events
8491 * @param {String} eventName
8492 * @param {Array} items - Outlayer.Items
8493 */
8494proto._emitCompleteOnItems = function( eventName, items ) {
8495  var _this = this;
8496  function onComplete() {
8497    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
8498  }
8499
8500  var count = items.length;
8501  if ( !items || !count ) {
8502    onComplete();
8503    return;
8504  }
8505
8506  var doneCount = 0;
8507  function tick() {
8508    doneCount++;
8509    if ( doneCount == count ) {
8510      onComplete();
8511    }
8512  }
8513
8514  // bind callback
8515  items.forEach( function( item ) {
8516    item.once( eventName, tick );
8517  });
8518};
8519
8520/**
8521 * emits events via EvEmitter and jQuery events
8522 * @param {String} type - name of event
8523 * @param {Event} event - original event
8524 * @param {Array} args - extra arguments
8525 */
8526proto.dispatchEvent = function( type, event, args ) {
8527  // add original event to arguments
8528  var emitArgs = event ? [ event ].concat( args ) : args;
8529  this.emitEvent( type, emitArgs );
8530
8531  if ( jQuery ) {
8532    // set this.$element
8533    this.$element = this.$element || jQuery( this.element );
8534    if ( event ) {
8535      // create jQuery event
8536      var $event = jQuery.Event( event );
8537      $event.type = type;
8538      this.$element.trigger( $event, args );
8539    } else {
8540      // just trigger with type if no event available
8541      this.$element.trigger( type, args );
8542    }
8543  }
8544};
8545
8546// -------------------------- ignore & stamps -------------------------- //
8547
8548
8549/**
8550 * keep item in collection, but do not lay it out
8551 * ignored items do not get skipped in layout
8552 * @param {Element} elem
8553 */
8554proto.ignore = function( elem ) {
8555  var item = this.getItem( elem );
8556  if ( item ) {
8557    item.isIgnored = true;
8558  }
8559};
8560
8561/**
8562 * return item to layout collection
8563 * @param {Element} elem
8564 */
8565proto.unignore = function( elem ) {
8566  var item = this.getItem( elem );
8567  if ( item ) {
8568    delete item.isIgnored;
8569  }
8570};
8571
8572/**
8573 * adds elements to stamps
8574 * @param {NodeList, Array, Element, or String} elems
8575 */
8576proto.stamp = function( elems ) {
8577  elems = this._find( elems );
8578  if ( !elems ) {
8579    return;
8580  }
8581
8582  this.stamps = this.stamps.concat( elems );
8583  // ignore
8584  elems.forEach( this.ignore, this );
8585};
8586
8587/**
8588 * removes elements to stamps
8589 * @param {NodeList, Array, or Element} elems
8590 */
8591proto.unstamp = function( elems ) {
8592  elems = this._find( elems );
8593  if ( !elems ){
8594    return;
8595  }
8596
8597  elems.forEach( function( elem ) {
8598    // filter out removed stamp elements
8599    utils.removeFrom( this.stamps, elem );
8600    this.unignore( elem );
8601  }, this );
8602};
8603
8604/**
8605 * finds child elements
8606 * @param {NodeList, Array, Element, or String} elems
8607 * @returns {Array} elems
8608 */
8609proto._find = function( elems ) {
8610  if ( !elems ) {
8611    return;
8612  }
8613  // if string, use argument as selector string
8614  if ( typeof elems == 'string' ) {
8615    elems = this.element.querySelectorAll( elems );
8616  }
8617  elems = utils.makeArray( elems );
8618  return elems;
8619};
8620
8621proto._manageStamps = function() {
8622  if ( !this.stamps || !this.stamps.length ) {
8623    return;
8624  }
8625
8626  this._getBoundingRect();
8627
8628  this.stamps.forEach( this._manageStamp, this );
8629};
8630
8631// update boundingLeft / Top
8632proto._getBoundingRect = function() {
8633  // get bounding rect for container element
8634  var boundingRect = this.element.getBoundingClientRect();
8635  var size = this.size;
8636  this._boundingRect = {
8637    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
8638    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
8639    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
8640    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
8641  };
8642};
8643
8644/**
8645 * @param {Element} stamp
8646**/
8647proto._manageStamp = noop;
8648
8649/**
8650 * get x/y position of element relative to container element
8651 * @param {Element} elem
8652 * @returns {Object} offset - has left, top, right, bottom
8653 */
8654proto._getElementOffset = function( elem ) {
8655  var boundingRect = elem.getBoundingClientRect();
8656  var thisRect = this._boundingRect;
8657  var size = getSize( elem );
8658  var offset = {
8659    left: boundingRect.left - thisRect.left - size.marginLeft,
8660    top: boundingRect.top - thisRect.top - size.marginTop,
8661    right: thisRect.right - boundingRect.right - size.marginRight,
8662    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
8663  };
8664  return offset;
8665};
8666
8667// -------------------------- resize -------------------------- //
8668
8669// enable event handlers for listeners
8670// i.e. resize -> onresize
8671proto.handleEvent = utils.handleEvent;
8672
8673/**
8674 * Bind layout to window resizing
8675 */
8676proto.bindResize = function() {
8677  window.addEventListener( 'resize', this );
8678  this.isResizeBound = true;
8679};
8680
8681/**
8682 * Unbind layout to window resizing
8683 */
8684proto.unbindResize = function() {
8685  window.removeEventListener( 'resize', this );
8686  this.isResizeBound = false;
8687};
8688
8689proto.onresize = function() {
8690  this.resize();
8691};
8692
8693utils.debounceMethod( Outlayer, 'onresize', 100 );
8694
8695proto.resize = function() {
8696  // don't trigger if size did not change
8697  // or if resize was unbound. See #9
8698  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
8699    return;
8700  }
8701
8702  this.layout();
8703};
8704
8705/**
8706 * check if layout is needed post layout
8707 * @returns Boolean
8708 */
8709proto.needsResizeLayout = function() {
8710  var size = getSize( this.element );
8711  // check that this.size and size are there
8712  // IE8 triggers resize on body size change, so they might not be
8713  var hasSizes = this.size && size;
8714  return hasSizes && size.innerWidth !== this.size.innerWidth;
8715};
8716
8717// -------------------------- methods -------------------------- //
8718
8719/**
8720 * add items to Outlayer instance
8721 * @param {Array or NodeList or Element} elems
8722 * @returns {Array} items - Outlayer.Items
8723**/
8724proto.addItems = function( elems ) {
8725  var items = this._itemize( elems );
8726  // add items to collection
8727  if ( items.length ) {
8728    this.items = this.items.concat( items );
8729  }
8730  return items;
8731};
8732
8733/**
8734 * Layout newly-appended item elements
8735 * @param {Array or NodeList or Element} elems
8736 */
8737proto.appended = function( elems ) {
8738  var items = this.addItems( elems );
8739  if ( !items.length ) {
8740    return;
8741  }
8742  // layout and reveal just the new items
8743  this.layoutItems( items, true );
8744  this.reveal( items );
8745};
8746
8747/**
8748 * Layout prepended elements
8749 * @param {Array or NodeList or Element} elems
8750 */
8751proto.prepended = function( elems ) {
8752  var items = this._itemize( elems );
8753  if ( !items.length ) {
8754    return;
8755  }
8756  // add items to beginning of collection
8757  var previousItems = this.items.slice(0);
8758  this.items = items.concat( previousItems );
8759  // start new layout
8760  this._resetLayout();
8761  this._manageStamps();
8762  // layout new stuff without transition
8763  this.layoutItems( items, true );
8764  this.reveal( items );
8765  // layout previous items
8766  this.layoutItems( previousItems );
8767};
8768
8769/**
8770 * reveal a collection of items
8771 * @param {Array of Outlayer.Items} items
8772 */
8773proto.reveal = function( items ) {
8774  this._emitCompleteOnItems( 'reveal', items );
8775  if ( !items || !items.length ) {
8776    return;
8777  }
8778  var stagger = this.updateStagger();
8779  items.forEach( function( item, i ) {
8780    item.stagger( i * stagger );
8781    item.reveal();
8782  });
8783};
8784
8785/**
8786 * hide a collection of items
8787 * @param {Array of Outlayer.Items} items
8788 */
8789proto.hide = function( items ) {
8790  this._emitCompleteOnItems( 'hide', items );
8791  if ( !items || !items.length ) {
8792    return;
8793  }
8794  var stagger = this.updateStagger();
8795  items.forEach( function( item, i ) {
8796    item.stagger( i * stagger );
8797    item.hide();
8798  });
8799};
8800
8801/**
8802 * reveal item elements
8803 * @param {Array}, {Element}, {NodeList} items
8804 */
8805proto.revealItemElements = function( elems ) {
8806  var items = this.getItems( elems );
8807  this.reveal( items );
8808};
8809
8810/**
8811 * hide item elements
8812 * @param {Array}, {Element}, {NodeList} items
8813 */
8814proto.hideItemElements = function( elems ) {
8815  var items = this.getItems( elems );
8816  this.hide( items );
8817};
8818
8819/**
8820 * get Outlayer.Item, given an Element
8821 * @param {Element} elem
8822 * @param {Function} callback
8823 * @returns {Outlayer.Item} item
8824 */
8825proto.getItem = function( elem ) {
8826  // loop through items to get the one that matches
8827  for ( var i=0; i < this.items.length; i++ ) {
8828    var item = this.items[i];
8829    if ( item.element == elem ) {
8830      // return item
8831      return item;
8832    }
8833  }
8834};
8835
8836/**
8837 * get collection of Outlayer.Items, given Elements
8838 * @param {Array} elems
8839 * @returns {Array} items - Outlayer.Items
8840 */
8841proto.getItems = function( elems ) {
8842  elems = utils.makeArray( elems );
8843  var items = [];
8844  elems.forEach( function( elem ) {
8845    var item = this.getItem( elem );
8846    if ( item ) {
8847      items.push( item );
8848    }
8849  }, this );
8850
8851  return items;
8852};
8853
8854/**
8855 * remove element(s) from instance and DOM
8856 * @param {Array or NodeList or Element} elems
8857 */
8858proto.remove = function( elems ) {
8859  var removeItems = this.getItems( elems );
8860
8861  this._emitCompleteOnItems( 'remove', removeItems );
8862
8863  // bail if no items to remove
8864  if ( !removeItems || !removeItems.length ) {
8865    return;
8866  }
8867
8868  removeItems.forEach( function( item ) {
8869    item.remove();
8870    // remove item from collection
8871    utils.removeFrom( this.items, item );
8872  }, this );
8873};
8874
8875// ----- destroy ----- //
8876
8877// remove and disable Outlayer instance
8878proto.destroy = function() {
8879  // clean up dynamic styles
8880  var style = this.element.style;
8881  style.height = '';
8882  style.position = '';
8883  style.width = '';
8884  // destroy items
8885  this.items.forEach( function( item ) {
8886    item.destroy();
8887  });
8888
8889  this.unbindResize();
8890
8891  var id = this.element.outlayerGUID;
8892  delete instances[ id ]; // remove reference to instance by id
8893  delete this.element.outlayerGUID;
8894  // remove data for jQuery
8895  if ( jQuery ) {
8896    jQuery.removeData( this.element, this.constructor.namespace );
8897  }
8898
8899};
8900
8901// -------------------------- data -------------------------- //
8902
8903/**
8904 * get Outlayer instance from element
8905 * @param {Element} elem
8906 * @returns {Outlayer}
8907 */
8908Outlayer.data = function( elem ) {
8909  elem = utils.getQueryElement( elem );
8910  var id = elem && elem.outlayerGUID;
8911  return id && instances[ id ];
8912};
8913
8914
8915// -------------------------- create Outlayer class -------------------------- //
8916
8917/**
8918 * create a layout class
8919 * @param {String} namespace
8920 */
8921Outlayer.create = function( namespace, options ) {
8922  // sub-class Outlayer
8923  var Layout = subclass( Outlayer );
8924  // apply new options and compatOptions
8925  Layout.defaults = utils.extend( {}, Outlayer.defaults );
8926  utils.extend( Layout.defaults, options );
8927  Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions  );
8928
8929  Layout.namespace = namespace;
8930
8931  Layout.data = Outlayer.data;
8932
8933  // sub-class Item
8934  Layout.Item = subclass( Item );
8935
8936  // -------------------------- declarative -------------------------- //
8937
8938  utils.htmlInit( Layout, namespace );
8939
8940  // -------------------------- jQuery bridge -------------------------- //
8941
8942  // make into jQuery plugin
8943  if ( jQuery && jQuery.bridget ) {
8944    jQuery.bridget( namespace, Layout );
8945  }
8946
8947  return Layout;
8948};
8949
8950function subclass( Parent ) {
8951  function SubClass() {
8952    Parent.apply( this, arguments );
8953  }
8954
8955  SubClass.prototype = Object.create( Parent.prototype );
8956  SubClass.prototype.constructor = SubClass;
8957
8958  return SubClass;
8959}
8960
8961// ----- helpers ----- //
8962
8963// how many milliseconds are in each unit
8964var msUnits = {
8965  ms: 1,
8966  s: 1000
8967};
8968
8969// munge time-like parameter into millisecond number
8970// '0.4s' -> 40
8971function getMilliseconds( time ) {
8972  if ( typeof time == 'number' ) {
8973    return time;
8974  }
8975  var matches = time.match( /(^\d*\.?\d*)(\w*)/ );
8976  var num = matches && matches[1];
8977  var unit = matches && matches[2];
8978  if ( !num.length ) {
8979    return 0;
8980  }
8981  num = parseFloat( num );
8982  var mult = msUnits[ unit ] || 1;
8983  return num * mult;
8984}
8985
8986// ----- fin ----- //
8987
8988// back in global
8989Outlayer.Item = Item;
8990
8991return Outlayer;
8992
8993}));
8994
8995/**
8996 * Isotope Item
8997**/
8998
8999( function( window, factory ) {
9000  // universal module definition
9001  /* jshint strict: false */ /*globals define, module, require */
9002  if ( typeof define == 'function' && define.amd ) {
9003    // AMD
9004    define( 'isotope-layout/js/item',[
9005        'outlayer/outlayer'
9006      ],
9007      factory );
9008  } else if ( typeof module == 'object' && module.exports ) {
9009    // CommonJS
9010    module.exports = factory(
9011      require('outlayer')
9012    );
9013  } else {
9014    // browser global
9015    window.Isotope = window.Isotope || {};
9016    window.Isotope.Item = factory(
9017      window.Outlayer
9018    );
9019  }
9020
9021}( window, function factory( Outlayer ) {
9022'use strict';
9023
9024// -------------------------- Item -------------------------- //
9025
9026// sub-class Outlayer Item
9027function Item() {
9028  Outlayer.Item.apply( this, arguments );
9029}
9030
9031var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
9032
9033var _create = proto._create;
9034proto._create = function() {
9035  // assign id, used for original-order sorting
9036  this.id = this.layout.itemGUID++;
9037  _create.call( this );
9038  this.sortData = {};
9039};
9040
9041proto.updateSortData = function() {
9042  if ( this.isIgnored ) {
9043    return;
9044  }
9045  // default sorters
9046  this.sortData.id = this.id;
9047  // for backward compatibility
9048  this.sortData['original-order'] = this.id;
9049  this.sortData.random = Math.random();
9050  // go thru getSortData obj and apply the sorters
9051  var getSortData = this.layout.options.getSortData;
9052  var sorters = this.layout._sorters;
9053  for ( var key in getSortData ) {
9054    var sorter = sorters[ key ];
9055    this.sortData[ key ] = sorter( this.element, this );
9056  }
9057};
9058
9059var _destroy = proto.destroy;
9060proto.destroy = function() {
9061  // call super
9062  _destroy.apply( this, arguments );
9063  // reset display, #741
9064  this.css({
9065    display: ''
9066  });
9067};
9068
9069return Item;
9070
9071}));
9072
9073/**
9074 * Isotope LayoutMode
9075 */
9076
9077( function( window, factory ) {
9078  // universal module definition
9079  /* jshint strict: false */ /*globals define, module, require */
9080  if ( typeof define == 'function' && define.amd ) {
9081    // AMD
9082    define( 'isotope-layout/js/layout-mode',[
9083        'get-size/get-size',
9084        'outlayer/outlayer'
9085      ],
9086      factory );
9087  } else if ( typeof module == 'object' && module.exports ) {
9088    // CommonJS
9089    module.exports = factory(
9090      require('get-size'),
9091      require('outlayer')
9092    );
9093  } else {
9094    // browser global
9095    window.Isotope = window.Isotope || {};
9096    window.Isotope.LayoutMode = factory(
9097      window.getSize,
9098      window.Outlayer
9099    );
9100  }
9101
9102}( window, function factory( getSize, Outlayer ) {
9103  'use strict';
9104
9105  // layout mode class
9106  function LayoutMode( isotope ) {
9107    this.isotope = isotope;
9108    // link properties
9109    if ( isotope ) {
9110      this.options = isotope.options[ this.namespace ];
9111      this.element = isotope.element;
9112      this.items = isotope.filteredItems;
9113      this.size = isotope.size;
9114    }
9115  }
9116
9117  var proto = LayoutMode.prototype;
9118
9119  /**
9120   * some methods should just defer to default Outlayer method
9121   * and reference the Isotope instance as `this`
9122  **/
9123  var facadeMethods = [
9124    '_resetLayout',
9125    '_getItemLayoutPosition',
9126    '_manageStamp',
9127    '_getContainerSize',
9128    '_getElementOffset',
9129    'needsResizeLayout',
9130    '_getOption'
9131  ];
9132
9133  facadeMethods.forEach( function( methodName ) {
9134    proto[ methodName ] = function() {
9135      return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
9136    };
9137  });
9138
9139  // -----  ----- //
9140
9141  // for horizontal layout modes, check vertical size
9142  proto.needsVerticalResizeLayout = function() {
9143    // don't trigger if size did not change
9144    var size = getSize( this.isotope.element );
9145    // check that this.size and size are there
9146    // IE8 triggers resize on body size change, so they might not be
9147    var hasSizes = this.isotope.size && size;
9148    return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
9149  };
9150
9151  // ----- measurements ----- //
9152
9153  proto._getMeasurement = function() {
9154    this.isotope._getMeasurement.apply( this, arguments );
9155  };
9156
9157  proto.getColumnWidth = function() {
9158    this.getSegmentSize( 'column', 'Width' );
9159  };
9160
9161  proto.getRowHeight = function() {
9162    this.getSegmentSize( 'row', 'Height' );
9163  };
9164
9165  /**
9166   * get columnWidth or rowHeight
9167   * segment: 'column' or 'row'
9168   * size 'Width' or 'Height'
9169  **/
9170  proto.getSegmentSize = function( segment, size ) {
9171    var segmentName = segment + size;
9172    var outerSize = 'outer' + size;
9173    // columnWidth / outerWidth // rowHeight / outerHeight
9174    this._getMeasurement( segmentName, outerSize );
9175    // got rowHeight or columnWidth, we can chill
9176    if ( this[ segmentName ] ) {
9177      return;
9178    }
9179    // fall back to item of first element
9180    var firstItemSize = this.getFirstItemSize();
9181    this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
9182      // or size of container
9183      this.isotope.size[ 'inner' + size ];
9184  };
9185
9186  proto.getFirstItemSize = function() {
9187    var firstItem = this.isotope.filteredItems[0];
9188    return firstItem && firstItem.element && getSize( firstItem.element );
9189  };
9190
9191  // ----- methods that should reference isotope ----- //
9192
9193  proto.layout = function() {
9194    this.isotope.layout.apply( this.isotope, arguments );
9195  };
9196
9197  proto.getSize = function() {
9198    this.isotope.getSize();
9199    this.size = this.isotope.size;
9200  };
9201
9202  // -------------------------- create -------------------------- //
9203
9204  LayoutMode.modes = {};
9205
9206  LayoutMode.create = function( namespace, options ) {
9207
9208    function Mode() {
9209      LayoutMode.apply( this, arguments );
9210    }
9211
9212    Mode.prototype = Object.create( proto );
9213    Mode.prototype.constructor = Mode;
9214
9215    // default options
9216    if ( options ) {
9217      Mode.options = options;
9218    }
9219
9220    Mode.prototype.namespace = namespace;
9221    // register in Isotope
9222    LayoutMode.modes[ namespace ] = Mode;
9223
9224    return Mode;
9225  };
9226
9227  return LayoutMode;
9228
9229}));
9230
9231/*!
9232 * Masonry v4.2.1
9233 * Cascading grid layout library
9234 * https://masonry.desandro.com
9235 * MIT License
9236 * by David DeSandro
9237 */
9238
9239( function( window, factory ) {
9240  // universal module definition
9241  /* jshint strict: false */ /*globals define, module, require */
9242  if ( typeof define == 'function' && define.amd ) {
9243    // AMD
9244    define( 'masonry-layout/masonry',[
9245        'outlayer/outlayer',
9246        'get-size/get-size'
9247      ],
9248      factory );
9249  } else if ( typeof module == 'object' && module.exports ) {
9250    // CommonJS
9251    module.exports = factory(
9252      require('outlayer'),
9253      require('get-size')
9254    );
9255  } else {
9256    // browser global
9257    window.Masonry = factory(
9258      window.Outlayer,
9259      window.getSize
9260    );
9261  }
9262
9263}( window, function factory( Outlayer, getSize ) {
9264
9265
9266
9267// -------------------------- masonryDefinition -------------------------- //
9268
9269  // create an Outlayer layout class
9270  var Masonry = Outlayer.create('masonry');
9271  // isFitWidth -> fitWidth
9272  Masonry.compatOptions.fitWidth = 'isFitWidth';
9273
9274  var proto = Masonry.prototype;
9275
9276  proto._resetLayout = function() {
9277    this.getSize();
9278    this._getMeasurement( 'columnWidth', 'outerWidth' );
9279    this._getMeasurement( 'gutter', 'outerWidth' );
9280    this.measureColumns();
9281
9282    // reset column Y
9283    this.colYs = [];
9284    for ( var i=0; i < this.cols; i++ ) {
9285      this.colYs.push( 0 );
9286    }
9287
9288    this.maxY = 0;
9289    this.horizontalColIndex = 0;
9290  };
9291
9292  proto.measureColumns = function() {
9293    this.getContainerWidth();
9294    // if columnWidth is 0, default to outerWidth of first item
9295    if ( !this.columnWidth ) {
9296      var firstItem = this.items[0];
9297      var firstItemElem = firstItem && firstItem.element;
9298      // columnWidth fall back to item of first element
9299      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
9300        // if first elem has no width, default to size of container
9301        this.containerWidth;
9302    }
9303
9304    var columnWidth = this.columnWidth += this.gutter;
9305
9306    // calculate columns
9307    var containerWidth = this.containerWidth + this.gutter;
9308    var cols = containerWidth / columnWidth;
9309    // fix rounding errors, typically with gutters
9310    var excess = columnWidth - containerWidth % columnWidth;
9311    // if overshoot is less than a pixel, round up, otherwise floor it
9312    var mathMethod = excess && excess < 1 ? 'round' : 'floor';
9313    cols = Math[ mathMethod ]( cols );
9314    this.cols = Math.max( cols, 1 );
9315  };
9316
9317  proto.getContainerWidth = function() {
9318    // container is parent if fit width
9319    var isFitWidth = this._getOption('fitWidth');
9320    var container = isFitWidth ? this.element.parentNode : this.element;
9321    // check that this.size and size are there
9322    // IE8 triggers resize on body size change, so they might not be
9323    var size = getSize( container );
9324    this.containerWidth = size && size.innerWidth;
9325  };
9326
9327  proto._getItemLayoutPosition = function( item ) {
9328    item.getSize();
9329    // how many columns does this brick span
9330    var remainder = item.size.outerWidth % this.columnWidth;
9331    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
9332    // round if off by 1 pixel, otherwise use ceil
9333    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
9334    colSpan = Math.min( colSpan, this.cols );
9335    // use horizontal or top column position
9336    var colPosMethod = this.options.horizontalOrder ?
9337      '_getHorizontalColPosition' : '_getTopColPosition';
9338    var colPosition = this[ colPosMethod ]( colSpan, item );
9339    // position the brick
9340    var position = {
9341      x: this.columnWidth * colPosition.col,
9342      y: colPosition.y
9343    };
9344    // apply setHeight to necessary columns
9345    var setHeight = colPosition.y + item.size.outerHeight;
9346    var setMax = colSpan + colPosition.col;
9347    for ( var i = colPosition.col; i < setMax; i++ ) {
9348      this.colYs[i] = setHeight;
9349    }
9350
9351    return position;
9352  };
9353
9354  proto._getTopColPosition = function( colSpan ) {
9355    var colGroup = this._getTopColGroup( colSpan );
9356    // get the minimum Y value from the columns
9357    var minimumY = Math.min.apply( Math, colGroup );
9358
9359    return {
9360      col: colGroup.indexOf( minimumY ),
9361      y: minimumY,
9362    };
9363  };
9364
9365  /**
9366   * @param {Number} colSpan - number of columns the element spans
9367   * @returns {Array} colGroup
9368   */
9369  proto._getTopColGroup = function( colSpan ) {
9370    if ( colSpan < 2 ) {
9371      // if brick spans only one column, use all the column Ys
9372      return this.colYs;
9373    }
9374
9375    var colGroup = [];
9376    // how many different places could this brick fit horizontally
9377    var groupCount = this.cols + 1 - colSpan;
9378    // for each group potential horizontal position
9379    for ( var i = 0; i < groupCount; i++ ) {
9380      colGroup[i] = this._getColGroupY( i, colSpan );
9381    }
9382    return colGroup;
9383  };
9384
9385  proto._getColGroupY = function( col, colSpan ) {
9386    if ( colSpan < 2 ) {
9387      return this.colYs[ col ];
9388    }
9389    // make an array of colY values for that one group
9390    var groupColYs = this.colYs.slice( col, col + colSpan );
9391    // and get the max value of the array
9392    return Math.max.apply( Math, groupColYs );
9393  };
9394
9395  // get column position based on horizontal index. #873
9396  proto._getHorizontalColPosition = function( colSpan, item ) {
9397    var col = this.horizontalColIndex % this.cols;
9398    var isOver = colSpan > 1 && col + colSpan > this.cols;
9399    // shift to next row if item can't fit on current row
9400    col = isOver ? 0 : col;
9401    // don't let zero-size items take up space
9402    var hasSize = item.size.outerWidth && item.size.outerHeight;
9403    this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex;
9404
9405    return {
9406      col: col,
9407      y: this._getColGroupY( col, colSpan ),
9408    };
9409  };
9410
9411  proto._manageStamp = function( stamp ) {
9412    var stampSize = getSize( stamp );
9413    var offset = this._getElementOffset( stamp );
9414    // get the columns that this stamp affects
9415    var isOriginLeft = this._getOption('originLeft');
9416    var firstX = isOriginLeft ? offset.left : offset.right;
9417    var lastX = firstX + stampSize.outerWidth;
9418    var firstCol = Math.floor( firstX / this.columnWidth );
9419    firstCol = Math.max( 0, firstCol );
9420    var lastCol = Math.floor( lastX / this.columnWidth );
9421    // lastCol should not go over if multiple of columnWidth #425
9422    lastCol -= lastX % this.columnWidth ? 0 : 1;
9423    lastCol = Math.min( this.cols - 1, lastCol );
9424    // set colYs to bottom of the stamp
9425
9426    var isOriginTop = this._getOption('originTop');
9427    var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) +
9428      stampSize.outerHeight;
9429    for ( var i = firstCol; i <= lastCol; i++ ) {
9430      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
9431    }
9432  };
9433
9434  proto._getContainerSize = function() {
9435    this.maxY = Math.max.apply( Math, this.colYs );
9436    var size = {
9437      height: this.maxY
9438    };
9439
9440    if ( this._getOption('fitWidth') ) {
9441      size.width = this._getContainerFitWidth();
9442    }
9443
9444    return size;
9445  };
9446
9447  proto._getContainerFitWidth = function() {
9448    var unusedCols = 0;
9449    // count unused columns
9450    var i = this.cols;
9451    while ( --i ) {
9452      if ( this.colYs[i] !== 0 ) {
9453        break;
9454      }
9455      unusedCols++;
9456    }
9457    // fit container to columns that have been used
9458    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
9459  };
9460
9461  proto.needsResizeLayout = function() {
9462    var previousWidth = this.containerWidth;
9463    this.getContainerWidth();
9464    return previousWidth != this.containerWidth;
9465  };
9466
9467  return Masonry;
9468
9469}));
9470
9471/*!
9472 * Masonry layout mode
9473 * sub-classes Masonry
9474 * https://masonry.desandro.com
9475 */
9476
9477( function( window, factory ) {
9478  // universal module definition
9479  /* jshint strict: false */ /*globals define, module, require */
9480  if ( typeof define == 'function' && define.amd ) {
9481    // AMD
9482    define( 'isotope-layout/js/layout-modes/masonry',[
9483        '../layout-mode',
9484        'masonry-layout/masonry'
9485      ],
9486      factory );
9487  } else if ( typeof module == 'object' && module.exports ) {
9488    // CommonJS
9489    module.exports = factory(
9490      require('../layout-mode'),
9491      require('masonry-layout')
9492    );
9493  } else {
9494    // browser global
9495    factory(
9496      window.Isotope.LayoutMode,
9497      window.Masonry
9498    );
9499  }
9500
9501}( window, function factory( LayoutMode, Masonry ) {
9502'use strict';
9503
9504// -------------------------- masonryDefinition -------------------------- //
9505
9506  // create an Outlayer layout class
9507  var MasonryMode = LayoutMode.create('masonry');
9508
9509  var proto = MasonryMode.prototype;
9510
9511  var keepModeMethods = {
9512    _getElementOffset: true,
9513    layout: true,
9514    _getMeasurement: true
9515  };
9516
9517  // inherit Masonry prototype
9518  for ( var method in Masonry.prototype ) {
9519    // do not inherit mode methods
9520    if ( !keepModeMethods[ method ] ) {
9521      proto[ method ] = Masonry.prototype[ method ];
9522    }
9523  }
9524
9525  var measureColumns = proto.measureColumns;
9526  proto.measureColumns = function() {
9527    // set items, used if measuring first item
9528    this.items = this.isotope.filteredItems;
9529    measureColumns.call( this );
9530  };
9531
9532  // point to mode options for fitWidth
9533  var _getOption = proto._getOption;
9534  proto._getOption = function( option ) {
9535    if ( option == 'fitWidth' ) {
9536      return this.options.isFitWidth !== undefined ?
9537        this.options.isFitWidth : this.options.fitWidth;
9538    }
9539    return _getOption.apply( this.isotope, arguments );
9540  };
9541
9542  return MasonryMode;
9543
9544}));
9545
9546/**
9547 * fitRows layout mode
9548 */
9549
9550( function( window, factory ) {
9551  // universal module definition
9552  /* jshint strict: false */ /*globals define, module, require */
9553  if ( typeof define == 'function' && define.amd ) {
9554    // AMD
9555    define( 'isotope-layout/js/layout-modes/fit-rows',[
9556        '../layout-mode'
9557      ],
9558      factory );
9559  } else if ( typeof exports == 'object' ) {
9560    // CommonJS
9561    module.exports = factory(
9562      require('../layout-mode')
9563    );
9564  } else {
9565    // browser global
9566    factory(
9567      window.Isotope.LayoutMode
9568    );
9569  }
9570
9571}( window, function factory( LayoutMode ) {
9572'use strict';
9573
9574var FitRows = LayoutMode.create('fitRows');
9575
9576var proto = FitRows.prototype;
9577
9578proto._resetLayout = function() {
9579  this.x = 0;
9580  this.y = 0;
9581  this.maxY = 0;
9582  this._getMeasurement( 'gutter', 'outerWidth' );
9583};
9584
9585proto._getItemLayoutPosition = function( item ) {
9586  item.getSize();
9587
9588  var itemWidth = item.size.outerWidth + this.gutter;
9589  // if this element cannot fit in the current row
9590  var containerWidth = this.isotope.size.innerWidth + this.gutter;
9591  if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
9592    this.x = 0;
9593    this.y = this.maxY;
9594  }
9595
9596  var position = {
9597    x: this.x,
9598    y: this.y
9599  };
9600
9601  this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
9602  this.x += itemWidth;
9603
9604  return position;
9605};
9606
9607proto._getContainerSize = function() {
9608  return { height: this.maxY };
9609};
9610
9611return FitRows;
9612
9613}));
9614
9615/**
9616 * vertical layout mode
9617 */
9618
9619( function( window, factory ) {
9620  // universal module definition
9621  /* jshint strict: false */ /*globals define, module, require */
9622  if ( typeof define == 'function' && define.amd ) {
9623    // AMD
9624    define( 'isotope-layout/js/layout-modes/vertical',[
9625        '../layout-mode'
9626      ],
9627      factory );
9628  } else if ( typeof module == 'object' && module.exports ) {
9629    // CommonJS
9630    module.exports = factory(
9631      require('../layout-mode')
9632    );
9633  } else {
9634    // browser global
9635    factory(
9636      window.Isotope.LayoutMode
9637    );
9638  }
9639
9640}( window, function factory( LayoutMode ) {
9641'use strict';
9642
9643var Vertical = LayoutMode.create( 'vertical', {
9644  horizontalAlignment: 0
9645});
9646
9647var proto = Vertical.prototype;
9648
9649proto._resetLayout = function() {
9650  this.y = 0;
9651};
9652
9653proto._getItemLayoutPosition = function( item ) {
9654  item.getSize();
9655  var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
9656    this.options.horizontalAlignment;
9657  var y = this.y;
9658  this.y += item.size.outerHeight;
9659  return { x: x, y: y };
9660};
9661
9662proto._getContainerSize = function() {
9663  return { height: this.y };
9664};
9665
9666return Vertical;
9667
9668}));
9669
9670/*!
9671 * Isotope v3.0.6
9672 *
9673 * Licensed GPLv3 for open source use
9674 * or Isotope Commercial License for commercial use
9675 *
9676 * https://isotope.metafizzy.co
9677 * Copyright 2010-2018 Metafizzy
9678 */
9679
9680( function( window, factory ) {
9681  // universal module definition
9682  /* jshint strict: false */ /*globals define, module, require */
9683  if ( typeof define == 'function' && define.amd ) {
9684    // AMD
9685    define( [
9686        'outlayer/outlayer',
9687        'get-size/get-size',
9688        'desandro-matches-selector/matches-selector',
9689        'fizzy-ui-utils/utils',
9690        'isotope-layout/js/item',
9691        'isotope-layout/js/layout-mode',
9692        // include default layout modes
9693        'isotope-layout/js/layout-modes/masonry',
9694        'isotope-layout/js/layout-modes/fit-rows',
9695        'isotope-layout/js/layout-modes/vertical'
9696      ],
9697      function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
9698        return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
9699      });
9700  } else if ( typeof module == 'object' && module.exports ) {
9701    // CommonJS
9702    module.exports = factory(
9703      window,
9704      require('outlayer'),
9705      require('get-size'),
9706      require('desandro-matches-selector'),
9707      require('fizzy-ui-utils'),
9708      require('isotope-layout/js/item'),
9709      require('isotope-layout/js/layout-mode'),
9710      // include default layout modes
9711      require('isotope-layout/js/layout-modes/masonry'),
9712      require('isotope-layout/js/layout-modes/fit-rows'),
9713      require('isotope-layout/js/layout-modes/vertical')
9714    );
9715  } else {
9716    // browser global
9717    window.Isotope = factory(
9718      window,
9719      window.Outlayer,
9720      window.getSize,
9721      window.matchesSelector,
9722      window.fizzyUIUtils,
9723      window.Isotope.Item,
9724      window.Isotope.LayoutMode
9725    );
9726  }
9727
9728}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
9729  Item, LayoutMode ) {
9730
9731
9732
9733// -------------------------- vars -------------------------- //
9734
9735var jQuery = window.jQuery;
9736
9737// -------------------------- helpers -------------------------- //
9738
9739var trim = String.prototype.trim ?
9740  function( str ) {
9741    return str.trim();
9742  } :
9743  function( str ) {
9744    return str.replace( /^\s+|\s+$/g, '' );
9745  };
9746
9747// -------------------------- isotopeDefinition -------------------------- //
9748
9749  // create an Outlayer layout class
9750  var Isotope = Outlayer.create( 'isotope', {
9751    layoutMode: 'masonry',
9752    isJQueryFiltering: true,
9753    sortAscending: true
9754  });
9755
9756  Isotope.Item = Item;
9757  Isotope.LayoutMode = LayoutMode;
9758
9759  var proto = Isotope.prototype;
9760
9761  proto._create = function() {
9762    this.itemGUID = 0;
9763    // functions that sort items
9764    this._sorters = {};
9765    this._getSorters();
9766    // call super
9767    Outlayer.prototype._create.call( this );
9768
9769    // create layout modes
9770    this.modes = {};
9771    // start filteredItems with all items
9772    this.filteredItems = this.items;
9773    // keep of track of sortBys
9774    this.sortHistory = [ 'original-order' ];
9775    // create from registered layout modes
9776    for ( var name in LayoutMode.modes ) {
9777      this._initLayoutMode( name );
9778    }
9779  };
9780
9781  proto.reloadItems = function() {
9782    // reset item ID counter
9783    this.itemGUID = 0;
9784    // call super
9785    Outlayer.prototype.reloadItems.call( this );
9786  };
9787
9788  proto._itemize = function() {
9789    var items = Outlayer.prototype._itemize.apply( this, arguments );
9790    // assign ID for original-order
9791    for ( var i=0; i < items.length; i++ ) {
9792      var item = items[i];
9793      item.id = this.itemGUID++;
9794    }
9795    this._updateItemsSortData( items );
9796    return items;
9797  };
9798
9799
9800  // -------------------------- layout -------------------------- //
9801
9802  proto._initLayoutMode = function( name ) {
9803    var Mode = LayoutMode.modes[ name ];
9804    // set mode options
9805    // HACK extend initial options, back-fill in default options
9806    var initialOpts = this.options[ name ] || {};
9807    this.options[ name ] = Mode.options ?
9808      utils.extend( Mode.options, initialOpts ) : initialOpts;
9809    // init layout mode instance
9810    this.modes[ name ] = new Mode( this );
9811  };
9812
9813
9814  proto.layout = function() {
9815    // if first time doing layout, do all magic
9816    if ( !this._isLayoutInited && this._getOption('initLayout') ) {
9817      this.arrange();
9818      return;
9819    }
9820    this._layout();
9821  };
9822
9823  // private method to be used in layout() & magic()
9824  proto._layout = function() {
9825    // don't animate first layout
9826    var isInstant = this._getIsInstant();
9827    // layout flow
9828    this._resetLayout();
9829    this._manageStamps();
9830    this.layoutItems( this.filteredItems, isInstant );
9831
9832    // flag for initalized
9833    this._isLayoutInited = true;
9834  };
9835
9836  // filter + sort + layout
9837  proto.arrange = function( opts ) {
9838    // set any options pass
9839    this.option( opts );
9840    this._getIsInstant();
9841    // filter, sort, and layout
9842
9843    // filter
9844    var filtered = this._filter( this.items );
9845    this.filteredItems = filtered.matches;
9846
9847    this._bindArrangeComplete();
9848
9849    if ( this._isInstant ) {
9850      this._noTransition( this._hideReveal, [ filtered ] );
9851    } else {
9852      this._hideReveal( filtered );
9853    }
9854
9855    this._sort();
9856    this._layout();
9857  };
9858  // alias to _init for main plugin method
9859  proto._init = proto.arrange;
9860
9861  proto._hideReveal = function( filtered ) {
9862    this.reveal( filtered.needReveal );
9863    this.hide( filtered.needHide );
9864  };
9865
9866  // HACK
9867  // Don't animate/transition first layout
9868  // Or don't animate/transition other layouts
9869  proto._getIsInstant = function() {
9870    var isLayoutInstant = this._getOption('layoutInstant');
9871    var isInstant = isLayoutInstant !== undefined ? isLayoutInstant :
9872      !this._isLayoutInited;
9873    this._isInstant = isInstant;
9874    return isInstant;
9875  };
9876
9877  // listen for layoutComplete, hideComplete and revealComplete
9878  // to trigger arrangeComplete
9879  proto._bindArrangeComplete = function() {
9880    // listen for 3 events to trigger arrangeComplete
9881    var isLayoutComplete, isHideComplete, isRevealComplete;
9882    var _this = this;
9883    function arrangeParallelCallback() {
9884      if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
9885        _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
9886      }
9887    }
9888    this.once( 'layoutComplete', function() {
9889      isLayoutComplete = true;
9890      arrangeParallelCallback();
9891    });
9892    this.once( 'hideComplete', function() {
9893      isHideComplete = true;
9894      arrangeParallelCallback();
9895    });
9896    this.once( 'revealComplete', function() {
9897      isRevealComplete = true;
9898      arrangeParallelCallback();
9899    });
9900  };
9901
9902  // -------------------------- filter -------------------------- //
9903
9904  proto._filter = function( items ) {
9905    var filter = this.options.filter;
9906    filter = filter || '*';
9907    var matches = [];
9908    var hiddenMatched = [];
9909    var visibleUnmatched = [];
9910
9911    var test = this._getFilterTest( filter );
9912
9913    // test each item
9914    for ( var i=0; i < items.length; i++ ) {
9915      var item = items[i];
9916      if ( item.isIgnored ) {
9917        continue;
9918      }
9919      // add item to either matched or unmatched group
9920      var isMatched = test( item );
9921      // item.isFilterMatched = isMatched;
9922      // add to matches if its a match
9923      if ( isMatched ) {
9924        matches.push( item );
9925      }
9926      // add to additional group if item needs to be hidden or revealed
9927      if ( isMatched && item.isHidden ) {
9928        hiddenMatched.push( item );
9929      } else if ( !isMatched && !item.isHidden ) {
9930        visibleUnmatched.push( item );
9931      }
9932    }
9933
9934    // return collections of items to be manipulated
9935    return {
9936      matches: matches,
9937      needReveal: hiddenMatched,
9938      needHide: visibleUnmatched
9939    };
9940  };
9941
9942  // get a jQuery, function, or a matchesSelector test given the filter
9943  proto._getFilterTest = function( filter ) {
9944    if ( jQuery && this.options.isJQueryFiltering ) {
9945      // use jQuery
9946      return function( item ) {
9947        return jQuery( item.element ).is( filter );
9948      };
9949    }
9950    if ( typeof filter == 'function' ) {
9951      // use filter as function
9952      return function( item ) {
9953        return filter( item.element );
9954      };
9955    }
9956    // default, use filter as selector string
9957    return function( item ) {
9958      return matchesSelector( item.element, filter );
9959    };
9960  };
9961
9962  // -------------------------- sorting -------------------------- //
9963
9964  /**
9965   * @params {Array} elems
9966   * @public
9967   */
9968  proto.updateSortData = function( elems ) {
9969    // get items
9970    var items;
9971    if ( elems ) {
9972      elems = utils.makeArray( elems );
9973      items = this.getItems( elems );
9974    } else {
9975      // update all items if no elems provided
9976      items = this.items;
9977    }
9978
9979    this._getSorters();
9980    this._updateItemsSortData( items );
9981  };
9982
9983  proto._getSorters = function() {
9984    var getSortData = this.options.getSortData;
9985    for ( var key in getSortData ) {
9986      var sorter = getSortData[ key ];
9987      this._sorters[ key ] = mungeSorter( sorter );
9988    }
9989  };
9990
9991  /**
9992   * @params {Array} items - of Isotope.Items
9993   * @private
9994   */
9995  proto._updateItemsSortData = function( items ) {
9996    // do not update if no items
9997    var len = items && items.length;
9998
9999    for ( var i=0; len && i < len; i++ ) {
10000      var item = items[i];
10001      item.updateSortData();
10002    }
10003  };
10004
10005  // ----- munge sorter ----- //
10006
10007  // encapsulate this, as we just need mungeSorter
10008  // other functions in here are just for munging
10009  var mungeSorter = ( function() {
10010    // add a magic layer to sorters for convienent shorthands
10011    // `.foo-bar` will use the text of .foo-bar querySelector
10012    // `[foo-bar]` will use attribute
10013    // you can also add parser
10014    // `.foo-bar parseInt` will parse that as a number
10015    function mungeSorter( sorter ) {
10016      // if not a string, return function or whatever it is
10017      if ( typeof sorter != 'string' ) {
10018        return sorter;
10019      }
10020      // parse the sorter string
10021      var args = trim( sorter ).split(' ');
10022      var query = args[0];
10023      // check if query looks like [an-attribute]
10024      var attrMatch = query.match( /^\[(.+)\]$/ );
10025      var attr = attrMatch && attrMatch[1];
10026      var getValue = getValueGetter( attr, query );
10027      // use second argument as a parser
10028      var parser = Isotope.sortDataParsers[ args[1] ];
10029      // parse the value, if there was a parser
10030      sorter = parser ? function( elem ) {
10031        return elem && parser( getValue( elem ) );
10032      } :
10033      // otherwise just return value
10034      function( elem ) {
10035        return elem && getValue( elem );
10036      };
10037
10038      return sorter;
10039    }
10040
10041    // get an attribute getter, or get text of the querySelector
10042    function getValueGetter( attr, query ) {
10043      // if query looks like [foo-bar], get attribute
10044      if ( attr ) {
10045        return function getAttribute( elem ) {
10046          return elem.getAttribute( attr );
10047        };
10048      }
10049
10050      // otherwise, assume its a querySelector, and get its text
10051      return function getChildText( elem ) {
10052        var child = elem.querySelector( query );
10053        return child && child.textContent;
10054      };
10055    }
10056
10057    return mungeSorter;
10058  })();
10059
10060  // parsers used in getSortData shortcut strings
10061  Isotope.sortDataParsers = {
10062    'parseInt': function( val ) {
10063      return parseInt( val, 10 );
10064    },
10065    'parseFloat': function( val ) {
10066      return parseFloat( val );
10067    }
10068  };
10069
10070  // ----- sort method ----- //
10071
10072  // sort filteredItem order
10073  proto._sort = function() {
10074    if ( !this.options.sortBy ) {
10075      return;
10076    }
10077    // keep track of sortBy History
10078    var sortBys = utils.makeArray( this.options.sortBy );
10079    if ( !this._getIsSameSortBy( sortBys ) ) {
10080      // concat all sortBy and sortHistory, add to front, oldest goes in last
10081      this.sortHistory = sortBys.concat( this.sortHistory );
10082    }
10083    // sort magic
10084    var itemSorter = getItemSorter( this.sortHistory, this.options.sortAscending );
10085    this.filteredItems.sort( itemSorter );
10086  };
10087
10088  // check if sortBys is same as start of sortHistory
10089  proto._getIsSameSortBy = function( sortBys ) {
10090    for ( var i=0; i < sortBys.length; i++ ) {
10091      if ( sortBys[i] != this.sortHistory[i] ) {
10092        return false;
10093      }
10094    }
10095    return true;
10096  };
10097
10098  // returns a function used for sorting
10099  function getItemSorter( sortBys, sortAsc ) {
10100    return function sorter( itemA, itemB ) {
10101      // cycle through all sortKeys
10102      for ( var i = 0; i < sortBys.length; i++ ) {
10103        var sortBy = sortBys[i];
10104        var a = itemA.sortData[ sortBy ];
10105        var b = itemB.sortData[ sortBy ];
10106        if ( a > b || a < b ) {
10107          // if sortAsc is an object, use the value given the sortBy key
10108          var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
10109          var direction = isAscending ? 1 : -1;
10110          return ( a > b ? 1 : -1 ) * direction;
10111        }
10112      }
10113      return 0;
10114    };
10115  }
10116
10117  // -------------------------- methods -------------------------- //
10118
10119  // get layout mode
10120  proto._mode = function() {
10121    var layoutMode = this.options.layoutMode;
10122    var mode = this.modes[ layoutMode ];
10123    if ( !mode ) {
10124      // TODO console.error
10125      throw new Error( 'No layout mode: ' + layoutMode );
10126    }
10127    // HACK sync mode's options
10128    // any options set after init for layout mode need to be synced
10129    mode.options = this.options[ layoutMode ];
10130    return mode;
10131  };
10132
10133  proto._resetLayout = function() {
10134    // trigger original reset layout
10135    Outlayer.prototype._resetLayout.call( this );
10136    this._mode()._resetLayout();
10137  };
10138
10139  proto._getItemLayoutPosition = function( item  ) {
10140    return this._mode()._getItemLayoutPosition( item );
10141  };
10142
10143  proto._manageStamp = function( stamp ) {
10144    this._mode()._manageStamp( stamp );
10145  };
10146
10147  proto._getContainerSize = function() {
10148    return this._mode()._getContainerSize();
10149  };
10150
10151  proto.needsResizeLayout = function() {
10152    return this._mode().needsResizeLayout();
10153  };
10154
10155  // -------------------------- adding & removing -------------------------- //
10156
10157  // HEADS UP overwrites default Outlayer appended
10158  proto.appended = function( elems ) {
10159    var items = this.addItems( elems );
10160    if ( !items.length ) {
10161      return;
10162    }
10163    // filter, layout, reveal new items
10164    var filteredItems = this._filterRevealAdded( items );
10165    // add to filteredItems
10166    this.filteredItems = this.filteredItems.concat( filteredItems );
10167  };
10168
10169  // HEADS UP overwrites default Outlayer prepended
10170  proto.prepended = function( elems ) {
10171    var items = this._itemize( elems );
10172    if ( !items.length ) {
10173      return;
10174    }
10175    // start new layout
10176    this._resetLayout();
10177    this._manageStamps();
10178    // filter, layout, reveal new items
10179    var filteredItems = this._filterRevealAdded( items );
10180    // layout previous items
10181    this.layoutItems( this.filteredItems );
10182    // add to items and filteredItems
10183    this.filteredItems = filteredItems.concat( this.filteredItems );
10184    this.items = items.concat( this.items );
10185  };
10186
10187  proto._filterRevealAdded = function( items ) {
10188    var filtered = this._filter( items );
10189    this.hide( filtered.needHide );
10190    // reveal all new items
10191    this.reveal( filtered.matches );
10192    // layout new items, no transition
10193    this.layoutItems( filtered.matches, true );
10194    return filtered.matches;
10195  };
10196
10197  /**
10198   * Filter, sort, and layout newly-appended item elements
10199   * @param {Array or NodeList or Element} elems
10200   */
10201  proto.insert = function( elems ) {
10202    var items = this.addItems( elems );
10203    if ( !items.length ) {
10204      return;
10205    }
10206    // append item elements
10207    var i, item;
10208    var len = items.length;
10209    for ( i=0; i < len; i++ ) {
10210      item = items[i];
10211      this.element.appendChild( item.element );
10212    }
10213    // filter new stuff
10214    var filteredInsertItems = this._filter( items ).matches;
10215    // set flag
10216    for ( i=0; i < len; i++ ) {
10217      items[i].isLayoutInstant = true;
10218    }
10219    this.arrange();
10220    // reset flag
10221    for ( i=0; i < len; i++ ) {
10222      delete items[i].isLayoutInstant;
10223    }
10224    this.reveal( filteredInsertItems );
10225  };
10226
10227  var _remove = proto.remove;
10228  proto.remove = function( elems ) {
10229    elems = utils.makeArray( elems );
10230    var removeItems = this.getItems( elems );
10231    // do regular thing
10232    _remove.call( this, elems );
10233    // bail if no items to remove
10234    var len = removeItems && removeItems.length;
10235    // remove elems from filteredItems
10236    for ( var i=0; len && i < len; i++ ) {
10237      var item = removeItems[i];
10238      // remove item from collection
10239      utils.removeFrom( this.filteredItems, item );
10240    }
10241  };
10242
10243  proto.shuffle = function() {
10244    // update random sortData
10245    for ( var i=0; i < this.items.length; i++ ) {
10246      var item = this.items[i];
10247      item.sortData.random = Math.random();
10248    }
10249    this.options.sortBy = 'random';
10250    this._sort();
10251    this._layout();
10252  };
10253
10254  /**
10255   * trigger fn without transition
10256   * kind of hacky to have this in the first place
10257   * @param {Function} fn
10258   * @param {Array} args
10259   * @returns ret
10260   * @private
10261   */
10262  proto._noTransition = function( fn, args ) {
10263    // save transitionDuration before disabling
10264    var transitionDuration = this.options.transitionDuration;
10265    // disable transition
10266    this.options.transitionDuration = 0;
10267    // do it
10268    var returnValue = fn.apply( this, args );
10269    // re-enable transition for reveal
10270    this.options.transitionDuration = transitionDuration;
10271    return returnValue;
10272  };
10273
10274  // ----- helper methods ----- //
10275
10276  /**
10277   * getter method for getting filtered item elements
10278   * @returns {Array} elems - collection of item elements
10279   */
10280  proto.getFilteredItemElements = function() {
10281    return this.filteredItems.map( function( item ) {
10282      return item.element;
10283    });
10284  };
10285
10286  // -----  ----- //
10287
10288  return Isotope;
10289
10290}));
10291
10292/*!
10293 * Packery layout mode PACKAGED v2.0.1
10294 * sub-classes Packery
10295 */
10296
10297/**
10298 * Rect
10299 * low-level utility class for basic geometry
10300 */
10301
10302( function( window, factory ) {
10303  // universal module definition
10304  /* jshint strict: false */ /* globals define, module */
10305  if ( typeof define == 'function' && define.amd ) {
10306    // AMD
10307    define( 'packery/js/rect',factory );
10308  } else if ( typeof module == 'object' && module.exports ) {
10309    // CommonJS
10310    module.exports = factory();
10311  } else {
10312    // browser global
10313    window.Packery = window.Packery || {};
10314    window.Packery.Rect = factory();
10315  }
10316
10317}( window, function factory() {
10318
10319
10320// -------------------------- Rect -------------------------- //
10321
10322function Rect( props ) {
10323  // extend properties from defaults
10324  for ( var prop in Rect.defaults ) {
10325    this[ prop ] = Rect.defaults[ prop ];
10326  }
10327
10328  for ( prop in props ) {
10329    this[ prop ] = props[ prop ];
10330  }
10331
10332}
10333
10334Rect.defaults = {
10335  x: 0,
10336  y: 0,
10337  width: 0,
10338  height: 0
10339};
10340
10341var proto = Rect.prototype;
10342
10343/**
10344 * Determines whether or not this rectangle wholly encloses another rectangle or point.
10345 * @param {Rect} rect
10346 * @returns {Boolean}
10347**/
10348proto.contains = function( rect ) {
10349  // points don't have width or height
10350  var otherWidth = rect.width || 0;
10351  var otherHeight = rect.height || 0;
10352  return this.x <= rect.x &&
10353    this.y <= rect.y &&
10354    this.x + this.width >= rect.x + otherWidth &&
10355    this.y + this.height >= rect.y + otherHeight;
10356};
10357
10358/**
10359 * Determines whether or not the rectangle intersects with another.
10360 * @param {Rect} rect
10361 * @returns {Boolean}
10362**/
10363proto.overlaps = function( rect ) {
10364  var thisRight = this.x + this.width;
10365  var thisBottom = this.y + this.height;
10366  var rectRight = rect.x + rect.width;
10367  var rectBottom = rect.y + rect.height;
10368
10369  // http://stackoverflow.com/a/306332
10370  return this.x < rectRight &&
10371    thisRight > rect.x &&
10372    this.y < rectBottom &&
10373    thisBottom > rect.y;
10374};
10375
10376/**
10377 * @param {Rect} rect - the overlapping rect
10378 * @returns {Array} freeRects - rects representing the area around the rect
10379**/
10380proto.getMaximalFreeRects = function( rect ) {
10381
10382  // if no intersection, return false
10383  if ( !this.overlaps( rect ) ) {
10384    return false;
10385  }
10386
10387  var freeRects = [];
10388  var freeRect;
10389
10390  var thisRight = this.x + this.width;
10391  var thisBottom = this.y + this.height;
10392  var rectRight = rect.x + rect.width;
10393  var rectBottom = rect.y + rect.height;
10394
10395  // top
10396  if ( this.y < rect.y ) {
10397    freeRect = new Rect({
10398      x: this.x,
10399      y: this.y,
10400      width: this.width,
10401      height: rect.y - this.y
10402    });
10403    freeRects.push( freeRect );
10404  }
10405
10406  // right
10407  if ( thisRight > rectRight ) {
10408    freeRect = new Rect({
10409      x: rectRight,
10410      y: this.y,
10411      width: thisRight - rectRight,
10412      height: this.height
10413    });
10414    freeRects.push( freeRect );
10415  }
10416
10417  // bottom
10418  if ( thisBottom > rectBottom ) {
10419    freeRect = new Rect({
10420      x: this.x,
10421      y: rectBottom,
10422      width: this.width,
10423      height: thisBottom - rectBottom
10424    });
10425    freeRects.push( freeRect );
10426  }
10427
10428  // left
10429  if ( this.x < rect.x ) {
10430    freeRect = new Rect({
10431      x: this.x,
10432      y: this.y,
10433      width: rect.x - this.x,
10434      height: this.height
10435    });
10436    freeRects.push( freeRect );
10437  }
10438
10439  return freeRects;
10440};
10441
10442proto.canFit = function( rect ) {
10443  return this.width >= rect.width && this.height >= rect.height;
10444};
10445
10446return Rect;
10447
10448}));
10449
10450/**
10451 * Packer
10452 * bin-packing algorithm
10453 */
10454
10455( function( window, factory ) {
10456  // universal module definition
10457  /* jshint strict: false */ /* globals define, module, require */
10458  if ( typeof define == 'function' && define.amd ) {
10459    // AMD
10460    define( 'packery/js/packer',[ './rect' ], factory );
10461  } else if ( typeof module == 'object' && module.exports ) {
10462    // CommonJS
10463    module.exports = factory(
10464      require('./rect')
10465    );
10466  } else {
10467    // browser global
10468    var Packery = window.Packery = window.Packery || {};
10469    Packery.Packer = factory( Packery.Rect );
10470  }
10471
10472}( window, function factory( Rect ) {
10473
10474
10475// -------------------------- Packer -------------------------- //
10476
10477/**
10478 * @param {Number} width
10479 * @param {Number} height
10480 * @param {String} sortDirection
10481 *   topLeft for vertical, leftTop for horizontal
10482 */
10483function Packer( width, height, sortDirection ) {
10484  this.width = width || 0;
10485  this.height = height || 0;
10486  this.sortDirection = sortDirection || 'downwardLeftToRight';
10487
10488  this.reset();
10489}
10490
10491var proto = Packer.prototype;
10492
10493proto.reset = function() {
10494  this.spaces = [];
10495
10496  var initialSpace = new Rect({
10497    x: 0,
10498    y: 0,
10499    width: this.width,
10500    height: this.height
10501  });
10502
10503  this.spaces.push( initialSpace );
10504  // set sorter
10505  this.sorter = sorters[ this.sortDirection ] || sorters.downwardLeftToRight;
10506};
10507
10508// change x and y of rect to fit with in Packer's available space
10508s
10509proto.pack = function( rect ) {
10510  for ( var i=0; i < this.spaces.length; i++ ) {
10511    var space = this.spaces[i];
10512    if ( space.canFit( rect ) ) {
10513      this.placeInSpace( rect, space );
10514      break;
10515    }
10516  }
10517};
10518
10519proto.columnPack = function( rect ) {
10520  for ( var i=0; i < this.spaces.length; i++ ) {
10521    var space = this.spaces[i];
10522    var canFitInSpaceColumn = space.x <= rect.x &&
10523      space.x + space.width >= rect.x + rect.width &&
10524      space.height >= rect.height - 0.01; // fudge number for rounding error
10525    if ( canFitInSpaceColumn ) {
10526      rect.y = space.y;
10527      this.placed( rect );
10528      break;
10529    }
10530  }
10531};
10532
10533proto.rowPack = function( rect ) {
10534  for ( var i=0; i < this.spaces.length; i++ ) {
10535    var space = this.spaces[i];
10536    var canFitInSpaceRow = space.y <= rect.y &&
10537      space.y + space.height >= rect.y + rect.height &&
10538      space.width >= rect.width - 0.01; // fudge number for rounding error
10539    if ( canFitInSpaceRow ) {
10540      rect.x = space.x;
10541      this.placed( rect );
10542      break;
10543    }
10544  }
10545};
10546
10547proto.placeInSpace = function( rect, space ) {
10548  // place rect in space
10549  rect.x = space.x;
10550  rect.y = space.y;
10551
10552  this.placed( rect );
10553};
10554
10555// update spaces with placed rect
10556proto.placed = function( rect ) {
10557  // update spaces
10558  var revisedSpaces = [];
10559  for ( var i=0; i < this.spaces.length; i++ ) {
10560    var space = this.spaces[i];
10561    var newSpaces = space.getMaximalFreeRects( rect );
10562    // add either the original space or the new spaces to the revised spaces
10563    if ( newSpaces ) {
10564      revisedSpaces.push.apply( revisedSpaces, newSpaces );
10565    } else {
10566      revisedSpaces.push( space );
10567    }
10568  }
10569
10570  this.spaces = revisedSpaces;
10571
10572  this.mergeSortSpaces();
10573};
10574
10575proto.mergeSortSpaces = function() {
10576  // remove redundant spaces
10577  Packer.mergeRects( this.spaces );
10578  this.spaces.sort( this.sorter );
10579};
10580
10581// add a space back
10582proto.addSpace = function( rect ) {
10583  this.spaces.push( rect );
10584  this.mergeSortSpaces();
10585};
10586
10587// -------------------------- utility functions -------------------------- //
10588
10589/**
10590 * Remove redundant rectangle from array of rectangles
10591 * @param {Array} rects: an array of Rects
10592 * @returns {Array} rects: an array of Rects
10593**/
10594Packer.mergeRects = function( rects ) {
10595  var i = 0;
10596  var rect = rects[i];
10597
10598  rectLoop:
10599  while ( rect ) {
10600    var j = 0;
10601    var compareRect = rects[ i + j ];
10602
10603    while ( compareRect ) {
10604      if  ( compareRect == rect ) {
10605        j++; // next
10606      } else if ( compareRect.contains( rect ) ) {
10607        // remove rect
10608        rects.splice( i, 1 );
10609        rect = rects[i]; // set next rect
10610        continue rectLoop; // bail on compareLoop
10611      } else if ( rect.contains( compareRect ) ) {
10612        // remove compareRect
10613        rects.splice( i + j, 1 );
10614      } else {
10615        j++;
10616      }
10617      compareRect = rects[ i + j ]; // set next compareRect
10618    }
10619    i++;
10620    rect = rects[i];
10621  }
10622
10623  return rects;
10624};
10625
10626
10627// -------------------------- sorters -------------------------- //
10628
10629// functions for sorting rects in order
10630var sorters = {
10631  // top down, then left to right
10632  downwardLeftToRight: function( a, b ) {
10633    return a.y - b.y || a.x - b.x;
10634  },
10635  // left to right, then top down
10636  rightwardTopToBottom: function( a, b ) {
10637    return a.x - b.x || a.y - b.y;
10638  }
10639};
10640
10641
10642// --------------------------  -------------------------- //
10643
10644return Packer;
10645
10646}));
10647
10648/**
10649 * Packery Item Element
10650**/
10651
10652( function( window, factory ) {
10653  // universal module definition
10654  /* jshint strict: false */ /* globals define, module, require */
10655  if ( typeof define == 'function' && define.amd ) {
10656    // AMD
10657    define( 'packery/js/item',[
10658        'outlayer/outlayer',
10659        './rect'
10660      ],
10661      factory );
10662  } else if ( typeof module == 'object' && module.exports ) {
10663    // CommonJS
10664    module.exports = factory(
10665      require('outlayer'),
10666      require('./rect')
10667    );
10668  } else {
10669    // browser global
10670    window.Packery.Item = factory(
10671      window.Outlayer,
10672      window.Packery.Rect
10673    );
10674  }
10675
10676}( window, function factory( Outlayer, Rect ) {
10677
10678
10679// -------------------------- Item -------------------------- //
10680
10681var docElemStyle = document.documentElement.style;
10682
10683var transformProperty = typeof docElemStyle.transform == 'string' ?
10684  'transform' : 'WebkitTransform';
10685
10686// sub-class Item
10687var Item = function PackeryItem() {
10688  Outlayer.Item.apply( this, arguments );
10689};
10690
10691var proto = Item.prototype = Object.create( Outlayer.Item.prototype );
10692
10693var __create = proto._create;
10694proto._create = function() {
10695  // call default _create logic
10696  __create.call( this );
10697  this.rect = new Rect();
10698};
10699
10700var _moveTo = proto.moveTo;
10701proto.moveTo = function( x, y ) {
10702  // don't shift 1px while dragging
10703  var dx = Math.abs( this.position.x - x );
10704  var dy = Math.abs( this.position.y - y );
10705
10706  var canHackGoTo = this.layout.dragItemCount && !this.isPlacing &&
10707    !this.isTransitioning && dx < 1 && dy < 1;
10708  if ( canHackGoTo ) {
10709    this.goTo( x, y );
10710    return;
10711  }
10712  _moveTo.apply( this, arguments );
10713};
10714
10715// -------------------------- placing -------------------------- //
10716
10717proto.enablePlacing = function() {
10718  this.removeTransitionStyles();
10719  // remove transform property from transition
10720  if ( this.isTransitioning && transformProperty ) {
10721    this.element.style[ transformProperty ] = 'none';
10722  }
10723  this.isTransitioning = false;
10724  this.getSize();
10725  this.layout._setRectSize( this.element, this.rect );
10726  this.isPlacing = true;
10727};
10728
10729proto.disablePlacing = function() {
10730  this.isPlacing = false;
10731};
10732
10733// -----  ----- //
10734
10735// remove element from DOM
10736proto.removeElem = function() {
10737  this.element.parentNode.removeChild( this.element );
10738  // add space back to packer
10739  this.layout.packer.addSpace( this.rect );
10740  this.emitEvent( 'remove', [ this ] );
10741};
10742
10743// ----- dropPlaceholder ----- //
10744
10745proto.showDropPlaceholder = function() {
10746  var dropPlaceholder = this.dropPlaceholder;
10747  if ( !dropPlaceholder ) {
10748    // create dropPlaceholder
10749    dropPlaceholder = this.dropPlaceholder = document.createElement('div');
10750    dropPlaceholder.className = 'packery-drop-placeholder';
10751    dropPlaceholder.style.position = 'absolute';
10752  }
10753
10754  dropPlaceholder.style.width = this.size.width + 'px';
10755  dropPlaceholder.style.height = this.size.height + 'px';
10756  this.positionDropPlaceholder();
10757  this.layout.element.appendChild( dropPlaceholder );
10758};
10759
10760proto.positionDropPlaceholder = function() {
10761  this.dropPlaceholder.style[ transformProperty ] = 'translate(' +
10762    this.rect.x + 'px, ' + this.rect.y + 'px)';
10763};
10764
10765proto.hideDropPlaceholder = function() {
10766  this.layout.element.removeChild( this.dropPlaceholder );
10767};
10768
10769// -----  ----- //
10770
10771return Item;
10772
10773}));
10774
10775/*!
10776 * Packery v2.0.0
10777 * Gapless, draggable grid layouts
10778 *
10779 * Licensed GPLv3 for open source use
10780 * or Packery Commercial License for commercial use
10781 *
10782 * http://packery.metafizzy.co
10783 * Copyright 2016 Metafizzy
10784 */
10785
10786( function( window, factory ) {
10787  // universal module definition
10788  /* jshint strict: false */ /* globals define, module, require */
10789  if ( typeof define == 'function' && define.amd ) {
10790    // AMD
10791    define( 'packery/js/packery',[
10792        'get-size/get-size',
10793        'outlayer/outlayer',
10794        './rect',
10795        './packer',
10796        './item'
10797      ],
10798      factory );
10799  } else if ( typeof module == 'object' && module.exports ) {
10800    // CommonJS
10801    module.exports = factory(
10802      require('get-size'),
10803      require('outlayer'),
10804      require('./rect'),
10805      require('./packer'),
10806      require('./item')
10807    );
10808  } else {
10809    // browser global
10810    window.Packery = factory(
10811      window.getSize,
10812      window.Outlayer,
10813      window.Packery.Rect,
10814      window.Packery.Packer,
10815      window.Packery.Item
10816    );
10817  }
10818
10819}( window, function factory( getSize, Outlayer, Rect, Packer, Item ) {
10820
10821
10822// ----- Rect ----- //
10823
10824// allow for pixel rounding errors IE8-IE11 & Firefox; #227
10825Rect.prototype.canFit = function( rect ) {
10826  return this.width >= rect.width - 1 && this.height >= rect.height - 1;
10827};
10828
10829// -------------------------- Packery -------------------------- //
10830
10831// create an Outlayer layout class
10832var Packery = Outlayer.create('packery');
10833Packery.Item = Item;
10834
10835var proto = Packery.prototype;
10836
10837proto._create = function() {
10838  // call super
10839  Outlayer.prototype._create.call( this );
10840
10841  // initial properties
10842  this.packer = new Packer();
10843  // packer for drop targets
10844  this.shiftPacker = new Packer();
10845  this.isEnabled = true;
10846
10847  this.dragItemCount = 0;
10848
10849  // create drag handlers
10850  var _this = this;
10851  this.handleDraggabilly = {
10852    dragStart: function() {
10853      _this.itemDragStart( this.element );
10854    },
10855    dragMove: function() {
10856      _this.itemDragMove( this.element, this.position.x, this.position.y );
10857    },
10858    dragEnd: function() {
10859      _this.itemDragEnd( this.element );
10860    }
10861  };
10862
10863  this.handleUIDraggable = {
10864    start: function handleUIDraggableStart( event, ui ) {
10865      // HTML5 may trigger dragstart, dismiss HTML5 dragging
10866      if ( !ui ) {
10867        return;
10868      }
10869      _this.itemDragStart( event.currentTarget );
10870    },
10871    drag: function handleUIDraggableDrag( event, ui ) {
10872      if ( !ui ) {
10873        return;
10874      }
10875      _this.itemDragMove( event.currentTarget, ui.position.left, ui.position.top );
10876    },
10877    stop: function handleUIDraggableStop( event, ui ) {
10878      if ( !ui ) {
10879        return;
10880      }
10881      _this.itemDragEnd( event.currentTarget );
10882    }
10883  };
10884
10885};
10886
10887
10888// ----- init & layout ----- //
10889
10890/**
10891 * logic before any new layout
10892 */
10893proto._resetLayout = function() {
10894  this.getSize();
10895
10896  this._getMeasurements();
10897
10898  // reset packer
10899  var width, height, sortDirection;
10900  // packer settings, if horizontal or vertical
10901  if ( this._getOption('horizontal') ) {
10902    width = Infinity;
10903    height = this.size.innerHeight + this.gutter;
10904    sortDirection = 'rightwardTopToBottom';
10905  } else {
10906    width = this.size.innerWidth + this.gutter;
10907    height = Infinity;
10908    sortDirection = 'downwardLeftToRight';
10909  }
10910
10911  this.packer.width = this.shiftPacker.width = width;
10912  this.packer.height = this.shiftPacker.height = height;
10913  this.packer.sortDirection = this.shiftPacker.sortDirection = sortDirection;
10914
10915  this.packer.reset();
10916
10917  // layout
10918  this.maxY = 0;
10919  this.maxX = 0;
10920};
10921
10922/**
10923 * update columnWidth, rowHeight, & gutter
10924 * @private
10925 */
10926proto._getMeasurements = function() {
10927  this._getMeasurement( 'columnWidth', 'width' );
10928  this._getMeasurement( 'rowHeight', 'height' );
10929  this._getMeasurement( 'gutter', 'width' );
10930};
10931
10932proto._getItemLayoutPosition = function( item ) {
10933  this._setRectSize( item.element, item.rect );
10934  if ( this.isShifting || this.dragItemCount > 0 ) {
10935    var packMethod = this._getPackMethod();
10936    this.packer[ packMethod ]( item.rect );
10937  } else {
10938    this.packer.pack( item.rect );
10939  }
10940
10941  this._setMaxXY( item.rect );
10942  return item.rect;
10943};
10944
10945proto.shiftLayout = function() {
10946  this.isShifting = true;
10947  this.layout();
10948  delete this.isShifting;
10949};
10950
10951proto._getPackMethod = function() {
10952  return this._getOption('horizontal') ? 'rowPack' : 'columnPack';
10953};
10954
10955
10956/**
10957 * set max X and Y value, for size of container
10958 * @param {Packery.Rect} rect
10959 * @private
10960 */
10961proto._setMaxXY = function( rect ) {
10962  this.maxX = Math.max( rect.x + rect.width, this.maxX );
10963  this.maxY = Math.max( rect.y + rect.height, this.maxY );
10964};
10965
10966/**
10967 * set the width and height of a rect, applying columnWidth and rowHeight
10968 * @param {Element} elem
10969 * @param {Packery.Rect} rect
10970 */
10971proto._setRectSize = function( elem, rect ) {
10972  var size = getSize( elem );
10973  var w = size.outerWidth;
10974  var h = size.outerHeight;
10975  // size for columnWidth and rowHeight, if available
10976  // only check if size is non-zero, #177
10977  if ( w || h ) {
10978    w = this._applyGridGutter( w, this.columnWidth );
10979    h = this._applyGridGutter( h, this.rowHeight );
10980  }
10981  // rect must fit in packer
10982  rect.width = Math.min( w, this.packer.width );
10983  rect.height = Math.min( h, this.packer.height );
10984};
10985
10986/**
10987 * fits item to columnWidth/rowHeight and adds gutter
10988 * @param {Number} measurement - item width or height
10989 * @param {Number} gridSize - columnWidth or rowHeight
10990 * @returns measurement
10991 */
10992proto._applyGridGutter = function( measurement, gridSize ) {
10993  // just add gutter if no gridSize
10994  if ( !gridSize ) {
10995    return measurement + this.gutter;
10996  }
10997  gridSize += this.gutter;
10998  // fit item to columnWidth/rowHeight
10999  var remainder = measurement % gridSize;
11000  var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
11001  measurement = Math[ mathMethod ]( measurement / gridSize ) * gridSize;
11002  return measurement;
11003};
11004
11005proto._getContainerSize = function() {
11006  if ( this._getOption('horizontal') ) {
11007    return {
11008      width: this.maxX - this.gutter
11009    };
11010  } else {
11011    return {
11012      height: this.maxY - this.gutter
11013    };
11014  }
11015};
11016
11017
11018// -------------------------- stamp -------------------------- //
11019
11020/**
11021 * makes space for element
11022 * @param {Element} elem
11023 */
11024proto._manageStamp = function( elem ) {
11025
11026  var item = this.getItem( elem );
11027  var rect;
11028  if ( item && item.isPlacing ) {
11029    rect = item.rect;
11030  } else {
11031    var offset = this._getElementOffset( elem );
11032    rect = new Rect({
11033      x: this._getOption('originLeft') ? offset.left : offset.right,
11034      y: this._getOption('originTop') ? offset.top : offset.bottom
11035    });
11036  }
11037
11038  this._setRectSize( elem, rect );
11039  // save its space in the packer
11040  this.packer.placed( rect );
11041  this._setMaxXY( rect );
11042};
11043
11044// -------------------------- methods -------------------------- //
11045
11046function verticalSorter( a, b ) {
11047  return a.position.y - b.position.y || a.position.x - b.position.x;
11048}
11049
11050function horizontalSorter( a, b ) {
11051  return a.position.x - b.position.x || a.position.y - b.position.y;
11052}
11053
11054proto.sortItemsByPosition = function() {
11055  var sorter = this._getOption('horizontal') ? horizontalSorter : verticalSorter;
11056  this.items.sort( sorter );
11057};
11058
11059/**
11060 * Fit item element in its current position
11061 * Packery will position elements around it
11062 * useful for expanding elements
11063 *
11064 * @param {Element} elem
11065 * @param {Number} x - horizontal destination position, optional
11066 * @param {Number} y - vertical destination position, optional
11067 */
11068proto.fit = function( elem, x, y ) {
11069  var item = this.getItem( elem );
11070  if ( !item ) {
11071    return;
11072  }
11073
11074  // stamp item to get it out of layout
11075  this.stamp( item.element );
11076  // set placing flag
11077  item.enablePlacing();
11078  this.updateShiftTargets( item );
11079  // fall back to current position for fitting
11080  x = x === undefined ? item.rect.x: x;
11081  y = y === undefined ? item.rect.y: y;
11082  // position it best at its destination
11083  this.shift( item, x, y );
11084  this._bindFitEvents( item );
11085  item.moveTo( item.rect.x, item.rect.y );
11086  // layout everything else
11087  this.shiftLayout();
11088  // return back to regularly scheduled programming
11089  this.unstamp( item.element );
11090  this.sortItemsByPosition();
11091  item.disablePlacing();
11092};
11093
11094/**
11095 * emit event when item is fit and other items are laid out
11096 * @param {Packery.Item} item
11097 * @private
11098 */
11099proto._bindFitEvents = function( item ) {
11100  var _this = this;
11101  var ticks = 0;
11102  function onLayout() {
11103    ticks++;
11104    if ( ticks != 2 ) {
11105      return;
11106    }
11107    _this.dispatchEvent( 'fitComplete', null, [ item ] );
11108  }
11109  // when item is laid out
11110  item.once( 'layout', onLayout );
11111  // when all items are laid out
11112  this.once( 'layoutComplete', onLayout );
11113};
11114
11115// -------------------------- resize -------------------------- //
11116
11117// debounced, layout on resize
11118proto.resize = function() {
11119  // don't trigger if size did not change
11120  // or if resize was unbound. See #285, outlayer#9
11121  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
11122    return;
11123  }
11124
11125  if ( this.options.shiftPercentResize ) {
11126    this.resizeShiftPercentLayout();
11127  } else {
11128    this.layout();
11129  }
11130};
11131
11132/**
11133 * check if layout is needed post layout
11134 * @returns Boolean
11135 */
11136proto.needsResizeLayout = function() {
11137  var size = getSize( this.element );
11138  var innerSize = this._getOption('horizontal') ? 'innerHeight' : 'innerWidth';
11139  return size[ innerSize ] != this.size[ innerSize ];
11140};
11141
11142proto.resizeShiftPercentLayout = function() {
11143  var items = this._getItemsForLayout( this.items );
11144
11145  var isHorizontal = this._getOption('horizontal');
11146  var coord = isHorizontal ? 'y' : 'x';
11147  var measure = isHorizontal ? 'height' : 'width';
11148  var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';
11149  var innerSize = isHorizontal ? 'innerHeight' : 'innerWidth';
11150
11151  // proportional re-align items
11152  var previousSegment = this[ segmentName ];
11153  previousSegment = previousSegment && previousSegment + this.gutter;
11154
11155  if ( previousSegment ) {
11156    this._getMeasurements();
11157    var currentSegment = this[ segmentName ] + this.gutter;
11158    items.forEach( function( item ) {
11159      var seg = Math.round( item.rect[ coord ] / previousSegment );
11160      item.rect[ coord ] = seg * currentSegment;
11161    });
11162  } else {
11163    var currentSize = getSize( this.element )[ innerSize ] + this.gutter;
11164    var previousSize = this.packer[ measure ];
11165    items.forEach( function( item ) {
11166      item.rect[ coord ] = ( item.rect[ coord ] / previousSize ) * currentSize;
11167    });
11168  }
11169
11170  this.shiftLayout();
11171};
11172
11173// -------------------------- drag -------------------------- //
11174
11175/**
11176 * handle an item drag start event
11177 * @param {Element} elem
11178 */
11179proto.itemDragStart = function( elem ) {
11180  if ( !this.isEnabled ) {
11181    return;
11182  }
11183  this.stamp( elem );
11184  // this.ignore( elem );
11185  var item = this.getItem( elem );
11186  if ( !item ) {
11187    return;
11188  }
11189
11190  item.enablePlacing();
11191  item.showDropPlaceholder();
11192  this.dragItemCount++;
11193  this.updateShiftTargets( item );
11194};
11195
11196proto.updateShiftTargets = function( dropItem ) {
11197  this.shiftPacker.reset();
11198
11199  // pack stamps
11200  this._getBoundingRect();
11201  var isOriginLeft = this._getOption('originLeft');
11202  var isOriginTop = this._getOption('originTop');
11203  this.stamps.forEach( function( stamp ) {
11204    // ignore dragged item
11205    var item = this.getItem( stamp );
11206    if ( item && item.isPlacing ) {
11207      return;
11208    }
11209    var offset = this._getElementOffset( stamp );
11210    var rect = new Rect({
11211      x: isOriginLeft ? offset.left : offset.right,
11212      y: isOriginTop ? offset.top : offset.bottom
11213    });
11214    this._setRectSize( stamp, rect );
11215    // save its space in the packer
11216    this.shiftPacker.placed( rect );
11217  }, this );
11218
11219  // reset shiftTargets
11220  var isHorizontal = this._getOption('horizontal');
11221  var segmentName = isHorizontal ? 'rowHeight' : 'columnWidth';
11222  var measure = isHorizontal ? 'height' : 'width';
11223
11224  this.shiftTargetKeys = [];
11225  this.shiftTargets = [];
11226  var boundsSize;
11227  var segment = this[ segmentName ];
11228  segment = segment && segment + this.gutter;
11229
11230  if ( segment ) {
11231    var segmentSpan = Math.ceil( dropItem.rect[ measure ] / segment );
11232    var segs = Math.floor( ( this.shiftPacker[ measure ] + this.gutter ) / segment );
11233    boundsSize = ( segs - segmentSpan ) * segment;
11234    // add targets on top
11235    for ( var i=0; i < segs; i++ ) {
11236      this._addShiftTarget( i * segment, 0, boundsSize );
11237    }
11238  } else {
11239    boundsSize = ( this.shiftPacker[ measure ] + this.gutter ) - dropItem.rect[ measure ];
11240    this._addShiftTarget( 0, 0, boundsSize );
11241  }
11242
11243  // pack each item to measure where shiftTargets are
11244  var items = this._getItemsForLayout( this.items );
11245  var packMethod = this._getPackMethod();
11246  items.forEach( function( item ) {
11247    var rect = item.rect;
11248    this._setRectSize( item.element, rect );
11249    this.shiftPacker[ packMethod ]( rect );
11250
11251    // add top left corner
11252    this._addShiftTarget( rect.x, rect.y, boundsSize );
11253    // add bottom left / top right corner
11254    var cornerX = isHorizontal ? rect.x + rect.width : rect.x;
11255    var cornerY = isHorizontal ? rect.y : rect.y + rect.height;
11256    this._addShiftTarget( cornerX, cornerY, boundsSize );
11257
11258    if ( segment ) {
11259      // add targets for each column on bottom / row on right
11260      var segSpan = Math.round( rect[ measure ] / segment );
11261      for ( var i=1; i < segSpan; i++ ) {
11262        var segX = isHorizontal ? cornerX : rect.x + segment * i;
11263        var segY = isHorizontal ? rect.y + segment * i : cornerY;
11264        this._addShiftTarget( segX, segY, boundsSize );
11265      }
11266    }
11267  }, this );
11268
11269};
11270
11271proto._addShiftTarget = function( x, y, boundsSize ) {
11272  var checkCoord = this._getOption('horizontal') ? y : x;
11273  if ( checkCoord !== 0 && checkCoord > boundsSize ) {
11274    return;
11275  }
11276  // create string for a key, easier to keep track of what targets
11277  var key = x + ',' + y;
11278  var hasKey = this.shiftTargetKeys.indexOf( key ) != -1;
11279  if ( hasKey ) {
11280    return;
11281  }
11282  this.shiftTargetKeys.push( key );
11283  this.shiftTargets.push({ x: x, y: y });
11284};
11285
11286// -------------------------- drop -------------------------- //
11287
11288proto.shift = function( item, x, y ) {
11289  var shiftPosition;
11290  var minDistance = Infinity;
11291  var position = { x: x, y: y };
11292  this.shiftTargets.forEach( function( target ) {
11293    var distance = getDistance( target, position );
11294    if ( distance < minDistance ) {
11295      shiftPosition = target;
11296      minDistance = distance;
11297    }
11298  });
11299  item.rect.x = shiftPosition.x;
11300  item.rect.y = shiftPosition.y;
11301};
11302
11303function getDistance( a, b ) {
11304  var dx = b.x - a.x;
11305  var dy = b.y - a.y;
11306  return Math.sqrt( dx * dx + dy * dy );
11307}
11308
11309// -------------------------- drag move -------------------------- //
11310
11311var DRAG_THROTTLE_TIME = 120;
11312
11313/**
11314 * handle an item drag move event
11315 * @param {Element} elem
11316 * @param {Number} x - horizontal change in position
11317 * @param {Number} y - vertical change in position
11318 */
11319proto.itemDragMove = function( elem, x, y ) {
11320  var item = this.isEnabled && this.getItem( elem );
11321  if ( !item ) {
11322    return;
11323  }
11324
11325  x -= this.size.paddingLeft;
11326  y -= this.size.paddingTop;
11327
11328  var _this = this;
11329  function onDrag() {
11330    _this.shift( item, x, y );
11331    item.positionDropPlaceholder();
11332    _this.layout();
11333  }
11334
11335  // throttle
11336  var now = new Date();
11337  if ( this._itemDragTime && now - this._itemDragTime < DRAG_THROTTLE_TIME ) {
11338    clearTimeout( this.dragTimeout );
11339    this.dragTimeout = setTimeout( onDrag, DRAG_THROTTLE_TIME );
11340  } else {
11341    onDrag();
11342    this._itemDragTime = now;
11343  }
11344};
11345
11346// -------------------------- drag end -------------------------- //
11347
11348/**
11349 * handle an item drag end event
11350 * @param {Element} elem
11351 */
11352proto.itemDragEnd = function( elem ) {
11353  var item = this.isEnabled && this.getItem( elem );
11354  if ( !item ) {
11355    return;
11356  }
11357
11358  clearTimeout( this.dragTimeout );
11359  item.element.classList.add('is-positioning-post-drag');
11360
11361  var completeCount = 0;
11362  var _this = this;
11363  function onDragEndLayoutComplete() {
11364    completeCount++;
11365    if ( completeCount != 2 ) {
11366      return;
11367    }
11368    // reset drag item
11369    item.element.classList.remove('is-positioning-post-drag');
11370    item.hideDropPlaceholder();
11371    _this.dispatchEvent( 'dragItemPositioned', null, [ item ] );
11372  }
11373
11374  item.once( 'layout', onDragEndLayoutComplete );
11375  this.once( 'layoutComplete', onDragEndLayoutComplete );
11376  item.moveTo( item.rect.x, item.rect.y );
11377  this.layout();
11378  this.dragItemCount = Math.max( 0, this.dragItemCount - 1 );
11379  this.sortItemsByPosition();
11380  item.disablePlacing();
11381  this.unstamp( item.element );
11382};
11383
11384/**
11385 * binds Draggabilly events
11386 * @param {Draggabilly} draggie
11387 */
11388proto.bindDraggabillyEvents = function( draggie ) {
11389  this._bindDraggabillyEvents( draggie, 'on' );
11390};
11391
11392proto.unbindDraggabillyEvents = function( draggie ) {
11393  this._bindDraggabillyEvents( draggie, 'off' );
11394};
11395
11396proto._bindDraggabillyEvents = function( draggie, method ) {
11397  var handlers = this.handleDraggabilly;
11398  draggie[ method ]( 'dragStart', handlers.dragStart );
11399  draggie[ method ]( 'dragMove', handlers.dragMove );
11400  draggie[ method ]( 'dragEnd', handlers.dragEnd );
11401};
11402
11403/**
11404 * binds jQuery UI Draggable events
11405 * @param {jQuery} $elems
11406 */
11407proto.bindUIDraggableEvents = function( $elems ) {
11408  this._bindUIDraggableEvents( $elems, 'on' );
11409};
11410
11411proto.unbindUIDraggableEvents = function( $elems ) {
11412  this._bindUIDraggableEvents( $elems, 'off' );
11413};
11414
11415proto._bindUIDraggableEvents = function( $elems, method ) {
11416  var handlers = this.handleUIDraggable;
11417  $elems
11418    [ method ]( 'dragstart', handlers.start )
11419    [ method ]( 'drag', handlers.drag )
11420    [ method ]( 'dragstop', handlers.stop );
11421};
11422
11423// ----- destroy ----- //
11424
11425var _destroy = proto.destroy;
11426proto.destroy = function() {
11427  _destroy.apply( this, arguments );
11428  // disable flag; prevent drag events from triggering. #72
11429  this.isEnabled = false;
11430};
11431
11432// -----  ----- //
11433
11434Packery.Rect = Rect;
11435Packery.Packer = Packer;
11436
11437return Packery;
11438
11439}));
11440
11441/*!
11442 * Packery layout mode v2.0.1
11443 * sub-classes Packery
11444 */
11445
11446/*jshint browser: true, strict: true, undef: true, unused: true */
11447
11448( function( window, factory ) {
11449
11450  // universal module definition
11451  if ( typeof define == 'function' && define.amd ) {
11452    // AMD
11453    define( [
11454        'isotope-layout/js/layout-mode',
11455        'packery/js/packery'
11456      ],
11457      factory );
11458  } else if ( typeof module == 'object' && module.exports ) {
11459    // CommonJS
11460    module.exports = factory(
11461      require('isotope-layout/js/layout-mode'),
11462      require('packery')
11463    );
11464  } else {
11465    // browser global
11466    factory(
11467      window.Isotope.LayoutMode,
11468      window.Packery
11469    );
11470  }
11471
11472}( window, function factor( LayoutMode, Packery ) {
11473
11474
11475  // create an Outlayer layout class
11476  var PackeryMode = LayoutMode.create('packery');
11477  var proto = PackeryMode.prototype;
11478
11479  var keepModeMethods = {
11480    _getElementOffset: true,
11481    _getMeasurement: true
11482  };
11483
11484  // inherit Packery prototype
11485  for ( var method in Packery.prototype ) {
11486    // do not inherit mode methods
11487    if ( !keepModeMethods[ method ] ) {
11488      proto[ method ] = Packery.prototype[ method ];
11489    }
11490  }
11491
11492  // set packer in _resetLayout
11493  var _resetLayout = proto._resetLayout;
11494  proto._resetLayout = function() {
11495    this.packer = this.packer || new Packery.Packer();
11496    this.shiftPacker = this.shiftPacker || new Packery.Packer();
11497    _resetLayout.apply( this, arguments );
11498  };
11499
11500  var _getItemLayoutPosition = proto._getItemLayoutPosition;
11501  proto._getItemLayoutPosition = function( item ) {
11502    // set packery rect
11503    item.rect = item.rect || new Packery.Rect();
11504    return _getItemLayoutPosition.call( this, item );
11505  };
11506
11507  // needsResizeLayout for vertical or horizontal
11508  var _needsResizeLayout = proto.needsResizeLayout;
11509  proto.needsResizeLayout = function() {
11510    if ( this._getOption('horizontal') ) {
11511      return this.needsVerticalResizeLayout();
11512    } else {
11513      return _needsResizeLayout.call( this );
11514    }
11515  };
11516
11517  // point to mode options for horizontal
11518  var _getOption = proto._getOption;
11519  proto._getOption = function( option ) {
11520    if ( option == 'horizontal' ) {
11521      return this.options.isHorizontal !== undefined ?
11522        this.options.isHorizontal : this.options.horizontal;
11523    }
11524    return _getOption.apply( this.isotope, arguments );
11525  };
11526
11527  return PackeryMode;
11528
11529}));
11530
11531/*!
11532 * cellsByRows layout mode for Isotope
11533 * v1.1.3
11534 * http://isotope.metafizzy.co/layout-modes/cellsbyrow.html
11535 */
11536
11537/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */
11538
11539( function( window, factory ) {
11540  // universal module definition
11541  /* jshint strict: false */ /*globals define, module, require */
11542  if ( typeof define === 'function' && define.amd ) {
11543    // AMD
11544    define( [
11545        'isotope/js/layout-mode'
11546      ],
11547      factory );
11548  } else if ( typeof exports === 'object' ) {
11549    // CommonJS
11550    module.exports = factory(
11551      require('isotope-layout/js/layout-mode')
11552    );
11553  } else {
11554    // browser global
11555    factory(
11556      window.Isotope.LayoutMode
11557    );
11558  }
11559
11560}( window, function factory( LayoutMode ) {
11561  'use strict';
11562
11563  var CellsByRow = LayoutMode.create( 'cellsByRow' );
11564  var proto = CellsByRow.prototype;
11565
11566  proto._resetLayout = function() {
11567    // reset properties
11568    this.itemIndex = 0;
11569    // measurements
11570    this.getColumnWidth();
11571    this.getRowHeight();
11572    // set cols
11573    this.cols = Math.floor( this.isotope.size.innerWidth / this.columnWidth );
11574    this.cols = Math.max( this.cols, 1 );
11575  };
11576
11577  proto._getItemLayoutPosition = function( item ) {
11578    item.getSize();
11579    var col = this.itemIndex % this.cols;
11580    var row = Math.floor( this.itemIndex / this.cols );
11581    // center item within cell
11582    var x = ( col + 0.5 ) * this.columnWidth - item.size.outerWidth / 2;
11583    var y = ( row + 0.5 ) * this.rowHeight - item.size.outerHeight / 2;
11584    this.itemIndex++;
11585    return { x: x, y: y };
11586  };
11587
11588  proto._getContainerSize = function() {
11589    return {
11590      height: Math.ceil( this.itemIndex / this.cols ) * this.rowHeight
11591    };
11592  };
11593
11594  return CellsByRow;
11595
11596}));
11597/*global jQuery: true */
11598
11599/*!
11600   --------------------------------
11601   Infinite Scroll
11602   --------------------------------
11603   + https://github.com/paulirish/infinite-scroll
11604   + version 2.1.0
11605   + Copyright 2011/12 Paul Irish & Luke Shumard
11606   + Licensed under the MIT license
11607
11608   + Documentation: http://infinite-scroll.com/
11609*/
11610
11611// Uses AMD or browser globals to create a jQuery plugin.
11612(function (factory) {
11613	if (typeof define === 'function' && define.amd) {
11614		// AMD. Register as an anonymous module.
11615		define(['jquery'], factory);
11616	} else {
11617		// Browser globals
11618		factory(jQuery);
11619	}
11620}(function ($, undefined) {
11621	'use strict';
11622
11623	$.infinitescroll = function infscr(options, callback, element) {
11624		this.element = $(element);
11625
11626		// Flag the object in the event of a failed creation
11627		if (!this._create(options, callback)) {
11628			this.failed = true;
11629		}
11630	};
11631
11632	$.infinitescroll.defaults = {
11633		loading: {
11634			finished: undefined,
11635			finishedMsg: "<em>Congratulations, you've reached the end of the internet.</em>",
11636			img: 'data:image/gif;base64,R0lGODlh3AATAPQeAPDy+MnQ6LW/4N3h8MzT6rjC4sTM5r/I5NHX7N7j8c7U6tvg8OLl8uXo9Ojr9b3G5MfP6Ovu9tPZ7PT1+vX2+tbb7vf4+8/W69jd7rC73vn5/O/x+K243ai02////wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQECgD/ACwAAAAA3AATAAAF/6AnjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEj0BAScpHLJbDqf0Kh0Sq1ar9isdioItAKGw+MAKYMFhbF63CW438f0mg1R2O8EuXj/aOPtaHx7fn96goR4hmuId4qDdX95c4+RBIGCB4yAjpmQhZN0YGYGXitdZBIVGAsLoq4BBKQDswm1CQRkcG6ytrYKubq8vbfAcMK9v7q7EMO1ycrHvsW6zcTKsczNz8HZw9vG3cjTsMIYqQkCLBwHCgsMDQ4RDAYIqfYSFxDxEfz88/X38Onr16+Bp4ADCco7eC8hQYMAEe57yNCew4IVBU7EGNDiRn8Z831cGLHhSIgdFf9chIeBg7oA7gjaWUWTVQAGE3LqBDCTlc9WOHfm7PkTqNCh54rePDqB6M+lR536hCpUqs2gVZM+xbrTqtGoWqdy1emValeXKzggYBBB5y1acFNZmEvXAoN2cGfJrTv3bl69Ffj2xZt3L1+/fw3XRVw4sGDGcR0fJhxZsF3KtBTThZxZ8mLMgC3fRatCbYMNFCzwLEqLgE4NsDWs/tvqdezZf13Hvk2A9Szdu2X3pg18N+68xXn7rh1c+PLksI/Dhe6cuO3ow3NfV92bdArTqC2Ebd3A8vjf5QWfH6Bg7Nz17c2fj69+fnq+8N2Lty+fuP78/eV2X13neIcCeBRwxorbZrA1ANoCDGrgoG8RTshahQ9iSKEEzUmYIYfNWViUhheCGJyIP5E4oom7WWjgCeBFAJNv1DVV01MAdJhhjdkplWNzO/5oXI846njjVEIqR2OS2B1pE5PVscajkxhMycqLJghQSwT40PgfAl4GqNSXYdZXJn5gSkmmmmJu1aZYb14V51do+pTOCmA40AqVCIhG5IJ9PvYnhIFOxmdqhpaI6GeHCtpooisuutmg+Eg62KOMKuqoTaXgicQWoIYq6qiklmoqFV0UoeqqrLbq6quwxirrrLTWauutJ4QAACH5BAUKABwALAcABADOAAsAAAX/IPd0D2dyRCoUp/k8gpHOKtseR9yiSmGbuBykler9XLAhkbDavXTL5k2oqFqNOxzUZPU5YYZd1XsD72rZpBjbeh52mSNnMSC8lwblKZGwi+0QfIJ8CncnCoCDgoVnBHmKfByGJimPkIwtiAeBkH6ZHJaKmCeVnKKTHIihg5KNq4uoqmEtcRUtEREMBggtEr4QDrjCuRC8h7/BwxENeicSF8DKy82pyNLMOxzWygzFmdvD2L3P0dze4+Xh1Arkyepi7dfFvvTtLQkZBC0T/FX3CRgCMOBHsJ+EHYQY7OinAGECgQsB+Lu3AOK+CewcWjwxQeJBihtNGHSoQOE+iQ3//4XkwBBhRZMcUS6YSXOAwIL8PGqEaSJCiYt9SNoCmnJPAgUVLChdaoFBURN8MAzl2PQphwQLfDFd6lTowglHve6rKpbjhK7/pG5VinZP1qkiz1rl4+tr2LRwWU64cFEihwEtZgbgR1UiHaMVvxpOSwBA37kzGz9e8G+B5MIEKLutOGEsAH2ATQwYfTmuX8aETWdGPZmiZcccNSzeTCA1Sw0bdiitC7LBWgu8jQr8HRzqgpK6gX88QbrB14z/kF+ELpwB8eVQj/JkqdylAudji/+ts3039vEEfK8Vz2dlvxZKG0CmbkKDBvllRd6fCzDvBLKBDSCeffhRJEFebFk1k/Mv9jVIoIJZSeBggwUaNeB+Qk34IE0cXlihcfRxkOAJFFhwGmKlmWDiakZhUJtnLBpnWWcnKaAZcxI0piFGGLBm1mc90kajSCveeBVWKeYEoU2wqeaQi0PetoE+rr14EpVC7oAbAUHqhYExbn2XHHsVqbcVew9tx8+XJKk5AZsqqdlddGpqAKdbAYBn1pcczmSTdWvdmZ17c1b3FZ99vnTdCRFM8OEcAhLwm1NdXnWcBBSMRWmfkWZqVlsmLIiAp/o1gGV2vpS4lalGYsUOqXrddcKCmK61aZ8SjEpUpVFVoCpTj4r661Km7kBHjrDyc1RAIQAAIfkEBQoAGwAsBwAEAM4ACwAABf/gtmUCd4goQQgFKj6PYKi0yrrbc8i4ohQt12EHcal+MNSQiCP8gigdz7iCioaCIvUmZLp8QBzW0EN2vSlCuDtFKaq4RyHzQLEKZNdiQDhRDVooCwkbfm59EAmKi4SGIm+AjIsKjhsqB4mSjT2IOIOUnICeCaB/mZKFNTSRmqVpmJqklSqskq6PfYYCDwYHDC4REQwGCBLGxxIQDsHMwhAIX8bKzcENgSLGF9PU1j3Sy9zX2NrgzQziChLk1BHWxcjf7N046tvN82715czn9Pryz6Ilc4ACj4EBOCZM8KEnAYYADBRKnACAYUMFv1wotIhCEcaJCisqwJFgAUSQGyX/kCSVUUTIdKMwJlyo0oXHlhskwrTJciZHEXsgaqS4s6PJiCAr1uzYU8kBBSgnWFqpoMJMUjGtDmUwkmfVmVypakWhEKvXsS4nhLW5wNjVroJIoc05wSzTr0PtiigpYe4EC2vj4iWrFu5euWIMRBhacaVJhYQBEFjA9jHjyQ0xEABwGceGAZYjY0YBOrRLCxUp29QM+bRkx5s7ZyYgVbTqwwti2ybJ+vLtDYpycyZbYOlptxdx0kV+V7lC5iJAyyRrwYKxAdiz82ng0/jnAdMJFz0cPi104Ec1Vj9/M6F173vKL/feXv156dw11tlqeMMnv4V5Ap53GmjQQH97nFfg+IFiucfgRX5Z8KAgbUlQ4IULIlghhhdOSB6AgX0IVn8eReghen3NRIBsRgnH4l4LuEidZBjwRpt6NM5WGwoW0KSjCwX6yJSMab2GwwAPDXfaBCtWpluRTQqC5JM5oUZAjUNS+VeOLWpJEQ7VYQANW0INJSZVDFSnZphjSikfmzE5N4EEbQI1QJmnWXCmHulRp2edwDXF43txukenJwvI9xyg9Q26Z3MzGUcBYFEChZh6DVTq34AU8Iflh51Sd+CnKFYQ6mmZkhqfBKfSxZWqA9DZanWjxmhrWwi0qtCrt/43K6WqVjjpmhIqgEGvculaGKklKstAACEAACH5BAUKABwALAcABADOAAsAAAX/ICdyQmaMYyAUqPgIBiHPxNpy79kqRXH8wAPsRmDdXpAWgWdEIYm2llCHqjVHU+jjJkwqBTecwItShMXkEfNWSh8e1NGAcLgpDGlRgk7EJ/6Ae3VKfoF/fDuFhohVeDeCfXkcCQqDVQcQhn+VNDOYmpSWaoqBlUSfmowjEA+iEAEGDRGztAwGCDcXEA60tXEiCrq8vREMEBLIyRLCxMWSH
11636MzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/Cpk3ABwSLQkYAQwT/P309vcI7OvXr94jBQMJ/nskkGA/BQBRLNDncAIAiDcG6LsxAWOLiQzmeURBKWSLCQbv/1F0eDGinJUKR47YY1IEgQASKk7Yc7ACRwZm7mHweRJoz59BJUogisKCUaFMR0x4SlJBVBFTk8pZivTR0K73rN5wqlXEAq5Fy3IYgHbEzQ0nLy4QSoCjXLoom96VOJEeCosK5n4kkFfqXjl94wa+l1gvAcGICbewAOAxY8l/Ky/QhAGz4cUkGxu2HNozhwMGBnCUqUdBg9UuW9eUynqSwLHIBujePef1ZGQZXcM+OFuEBeBhi3OYgLyqcuaxbT9vLkf4SeqyWxSQpKGB2gQpm1KdWbu72rPRzR9Ne2Nu9Kzr/1Jqj0yD/fvqP4aXOt5sW/5qsXXVcv1Nsp8IBUAmgswGF3llGgeU1YVXXKTN1FlhWFXW3gIE+DVChApysACHHo7Q4A35lLichh+ROBmLKAzgYmYEYDAhCgxKGOOMn4WR4kkDaoBBOxJtdNKQxFmg5JIWIBnQc07GaORfUY4AEkdV6jHlCEISSZ5yTXpp1pbGZbkWmcuZmQCaE6iJ0FhjMaDjTMsgZaNEHFRAQVp3bqXnZED1qYcECOz5V6BhSWCoVJQIKuKQi2KFKEkEFAqoAo7uYSmO3jk61wUUMKmknJ4SGimBmAa0qVQBhAAAIfkEBQoAGwAsBwAEAM4ACwAABf/gJm5FmRlEqhJC+bywgK5pO4rHI0D3pii22+Mg6/0Ej96weCMAk7cDkXf7lZTTnrMl7eaYoy10JN0ZFdco0XAuvKI6qkgVFJXYNwjkIBcNBgR8TQoGfRsJCRuCYYQQiI+ICosiCoGOkIiKfSl8mJkHZ4U9kZMbKaI3pKGXmJKrngmug4WwkhA0lrCBWgYFCCMQFwoQDRHGxwwGCBLMzRLEx8iGzMMO0cYNeCMKzBDW19lnF9DXDIY/48Xg093f0Q3s1dcR8OLe8+Y91OTv5wrj7o7B+7VNQqABIoRVCMBggsOHE36kSoCBIcSH3EbFangxogJYFi8CkJhqQciLJEf/LDDJEeJIBT0GsOwYUYJGBS0fjpQAMidGmyVP6sx4Y6VQhzs9VUwkwqaCCh0tmKoFtSMDmBOf9phg4SrVrROuasRQAaxXpVUhdsU6IsECZlvX3kwLUWzRt0BHOLTbNlbZG3vZinArge5Dvn7wbqtQkSYAAgtKmnSsYKVKo2AfW048uaPmG386i4Q8EQMBAIAnfB7xBxBqvapJ9zX9WgRS2YMpnvYMGdPK3aMjt/3dUcNI4blpj7iwkMFWDXDvSmgAlijrt9RTR78+PS6z1uAJZIe93Q8g5zcsWCi/4Y+C8bah5zUv3vv89uft30QP23punGCx5954oBBwnwYaNCDY/wYrsYeggnM9B2Fpf8GG2CEUVWhbWAtGouEGDy7Y4IEJVrbSiXghqGKIo7z1IVcXIkKWWR361QOLWWnIhwERpLaaCCee5iMBGJQmJGyPFTnbkfHVZGRtIGrg5HALEJAZbu39BuUEUmq1JJQIPtZilY5hGeSWsSk52G9XqsmgljdIcABytq13HyIM6RcUA+r1qZ4EBF3WHWB29tBgAzRhEGhig8KmqKFv8SeCeo+mgsF7YFXa1qWSbkDpom/mqR1PmHCqJ3fwNRVXjC7S6CZhFVCQ2lWvZiirhQq42SACt25IK2hv8TprriUV1usGgeka7LFcNmCldMLi6qZMgFLgpw16Cipb7bC1knXsBiEAACH5BAUKABsALAcABADOAAsAAAX/4FZsJPkUmUGsLCEUTywXglFuSg7fW1xAvNWLF6sFFcPb42C8EZCj24EJdCp2yoegWsolS0Uu6fmamg8n8YYcLU2bXSiRaXMGvqV6/KAeJAh8VgZqCX+BexCFioWAYgqNi4qAR4ORhRuHY408jAeUhAmYYiuVlpiflqGZa5CWkzc5fKmbbhIpsAoQDRG8vQwQCBLCwxK6vb5qwhfGxxENahvCEA7NzskSy7vNzzzK09W/PNHF1NvX2dXcN8K55cfh69Luveol3vO8zwi4Yhj+AQwmCBw4IYclDAAJDlQggVOChAoLKkgFkSCAHDwWLKhIEOONARsDKryogFPIiAUb/95gJNIiw4wnI778GFPhzBKFOAq8qLJEhQpiNArjMcHCmlTCUDIouTKBhApELSxFWiGiVKY4E2CAekPgUphDu0742nRrVLJZnyrFSqKQ2ohoSYAMW6IoDpNJ4bLdILTnAj8KUF7UeENjAKuDyxIgOuGiOI0EBBMgLNew5AUrDTMGsFixwBIaNCQuAXJB57qNJ2OWm2Aj4skwCQCIyNkhhtMkdsIuodE0AN4LJDRgfLPtn5YDLdBlraAByuUbBgxQwICxMOnYpVOPej074OFdlfc0TqC62OIbcppHjV4o+LrieWhfT8JC/I/T6W8oCl29vQ0XjLdBaA3s1RcPBO7lFvpX8BVoG4O5jTXRQRDuJ6FDTzEWF1/BCZhgbyAKE9qICYLloQYOFtahVRsWYlZ4KQJHlwHS/IYaZ6sZd9tmu5HQm2xi1UaTbzxYwJk/wBF5g5EEYOBZeEfGZmNdFyFZmZIR4jikbLThlh5kUUVJGmRT7sekkziRWUIACABk3T4qCsedgO4xhgGcY7q5pHJ4klBBTQRJ0CeHcoYHHUh6wgfdn9uJdSdMiebGJ0zUPTcoS286FCkrZxnYoYYKWLkBowhQoBeaOlZAgVhLidrXqg2G
11636iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/oGFw2WZuT5oZROsSQnGaKjRvilI893MItlNOJ5v5gDcFrHhKIWcEYu/xFEqNv6B1N62aclysF7fsZYe5aOx2yL5aAUGSaT1oTYMBwQ5VGCAJgYIJCnx1gIOBhXdwiIl7d0p2iYGQUAQBjoOFSQR/lIQHnZ+Ue6OagqYzSqSJi5eTpTxGcjcSChANEbu8DBAIEsHBChe5vL13G7fFuscRDcnKuM3H0La3EA7Oz8kKEsXazr7Cw9/Gztar5uHHvte47MjktznZ2w0G1+D3BgirAqJmJMAQgMGEgwgn5Ei0gKDBhBMALGRYEOJBb5QcWlQo4cbAihZz3GgIMqFEBSM1/4ZEOWPAgpIIJXYU+PIhRG8ja1qU6VHlzZknJNQ6UanCjQkWCIGSUGEjAwVLjc44+DTqUQtPPS5gejUrTa5TJ3g9sWCr1BNUWZI161StiQUDmLYdGfesibQ3XMq1OPYthrwuA2yU2LBs2cBHIypYQPPlYAKFD5cVvNPtW8eVGbdcQADATsiNO4cFAPkvHpedPzc8kUcPgNGgZ5RNDZG05reoE9s2vSEP79MEGiQGy1qP8LA4ZcdtsJE48ONoLTBtTV0B9LsTnPceoIDBDQvS7W7vfjVY3q3eZ4A339J4eaAmKqU/sV58HvJh2RcnIBsDUw0ABqhBA5aV5V9XUFGiHfVeAiWwoFgJJrIXRH1tEMiDFV4oHoAEGlaWhgIGSGBO2nFomYY3mKjVglidaNYJGJDkWW2xxTfbjCbVaOGNqoX2GloR8ZeTaECS9pthRGJH2g0b3Agbk6hNANtteHD2GJUucfajCQBy5OOTQ25ZgUPvaVVQmbKh9510/qQpwXx3SQdfk8tZJOd5b6JJFplT3ZnmmX3qd5l1eg5q00HrtUkUn0AKaiGjClSAgKLYZcgWXwocGRcCFGCKwSB6ceqphwmYRUFYT/1WKlOdUpipmxW0mlCqHjYkAaeoZlqrqZ4qd+upQKaapn/AmgAegZ8KUtYtFAQQAgAh+QQFCgAbACwHAAQAzgALAAAF/+C2PUcmiCiZGUTrEkKBis8jQEquKwU5HyXIbEPgyX7BYa5wTNmEMwWsSXsqFbEh8DYs9mrgGjdK6GkPY5GOeU6ryz7UFopSQEzygOGhJBjoIgMDBAcBM0V/CYqLCQqFOwobiYyKjn2TlI6GKC2YjJZknouaZAcQlJUHl6eooJwKooobqoewrJSEmyKdt59NhRKFMxLEEA4RyMkMEAjDEhfGycqAG8TQx9IRDRDE3d3R2ctD1RLg0ttKEnbY5wZD3+zJ6M7X2RHi9Oby7u/r9g38UFjTh2xZJBEBMDAboogAgwkQI07IMUORwocSJwCgWDFBAIwZOaJIsOBjRogKJP8wTODw5ESVHVtm3AhzpEeQElOuNDlTZ0ycEUWKWFASqEahGwYUPbnxoAgEdlYSqDBkgoUNClAlIHbSAoOsqCRQnQHxq1axVb06FWFxLIqyaze0Tft1JVqyE+pWXMD1pF6bYl3+HTqAWNW8cRUFzmih0ZAAB2oGKukSAAGGRHWJgLiR6AylBLpuHKKUMlMCngMpDSAa9QIUggZVVvDaJobLeC3XZpvgNgCmtPcuwP3WgmXSq4do0DC6o2/guzcseECtUoO0hmcsGKDgOt7ssBd07wqesAIGZC1YIBa7PQHvb1+SFo+++HrJSQfB33xfav3i5eX3Hnb4CTJgegEq8tH/YQEOcIJzbm2G2EoYRLgBXFpVmFYDcREV4HIcnmUhiGBRouEMJGJGzHIspqgdXxK0yCKHRNXoIX4uorCdTyjkyNtdPWrA4Up82EbAbzMRxxZRR54WXVLDIRmRcag5d2R6ugl3ZXzNhTecchpMhIGVAKAYpgJjjsSklBEd99maZoo535ZvdamjBEpusJyctg3h4X8XqodBMx0tiNeg/oGJaKGABpogS40KSqiaEgBqlQWLUtqoVQnytekEjzo0hHqhRorppOZt2p923M2AAV+oBtpAnnPNoB6HaU6mAAIU+IXmi3j2mtFXuUoHKwXpzVrsjcgGOauKEjQrwq157hitGq2NoWmjh7z6Wmxb0m5w66+2VRAuXN/yFUAIACH5BAUKABsALAcABADOAAsAAAX/4CZuRiaM45MZqBgIRbs9AqTcuFLE7VHLOh7KB5ERdjJaEaU4ClO/lgKWjKKcMiJQ8KgumcieVdQMD8cbBeuAkkC6LYLhOxoQ2PF5Ys9PKPBMen17f0CCg4VSh32JV4t8jSNqEIOEgJKPlkYBlJWRInKdiJdkmQlvKAsLBxdABA4RsbIMBggtEhcQsLKxDBC2TAS6vLENdJLDxMZAubu8vjIbzcQRtMzJz79S08oQEt/guNiyy7fcvMbh4OezdAvGrakLAQwyABsELQkY9BP+//ckyPDD4J9BfAMh1GsBoImMeQUN+lMgUJ9CiRMa5msxoB9Gh/o8GmxYMZXIgxtR/yQ46S/gQAURR0pDwYDfywoyLPip5AdnCwsMFPBU4BPFhKBDi444quCmDKZOfwZ9KEGpCKgcN1jdALSpPqIYsabS+nSqvqplvYqQYAeDPgwKwjaMtiDl0oaqUAyo+3TuWwUAMPpVCfee0cEjVBGQq2ABx7oTWmQk4FglZMGN9fGVDMCuiH2AOVOu/PmyxM630gwM0CCn6q8LjVJ8GXvpa5Uwn95OTC/nNxkda1/dLSK475IjCD6dHbK1ZOa4hXP9DXs5chJ00UpVm5xo2qRpoxptwF2E4/IbJpB/SDz9+q9b1aNfQH08+p4a8uvX8B53fLP+ycAfemjsRUBgp1H20K+BghHgVgt1GXZXZpZ5lt4ECjxYR4ScUWiShEtZqBiIInRGWnERNnjiBglw+JyGnxUmGowsyiiZg189lNtPGACjV2+S9UjbU0JWF6SPvEk3QZEqsZYTk3UAaRSUnznJI5LmESCdBVSyaOWUWLK4I5gDUYVeV1T9l+FZClCAUVA09uSmRHBCKAECFEhW51ht6rnmWBXkaR+NjuHpJ40D3DmnQXt2F+ihZxlqVKOfQRACACH5BAUKABwALAcABADOAAsAAAX/ICdyUCkUo/g8mUG8MCGkKgspeC6j6XEIEBpBUeCNfECaglBcOVfJFK7YQwZHQ6JRZBUqTrSuVEuD3nI45pYjFuWKvjjSkCoRaBUMWxkwBGgJCXspQ36Bh4EEB0oKhoiBgyNLjo8Ki4QElIiWfJqHnISNEI+Ql5J9o6SgkqKkgqYihamPkW6oNBgSfiMMDQkGCBLCwxIQDhHIyQwQCGMKxsnKVyPCF9DREQ3MxMPX0cu4wt7J2uHWx9jlKd3o39MiuefYEcvNkuLt5O8c1ePI2tyELXGQwoGDAQf+iEC2xByDCRAjTlAgIUWCBRgCPJQ4AQBFXAs0coT40WLIjRxL/47AcHLkxIomRXL0CHPERZkpa4q4iVKiyp0tR/7kwHMkTUBBJR5dOCEBAVcKKtCAyOHpowXCpk7goABqBZdcvWploACpBKkpIJI1q5OD2rIWE0R1uTZu1LFwbWL9OlKuWb4c6+o9i3dEgw0RCGDUG9KlRw56gDY2qmCByZBaASi+TACA0TucAaTteCcy0ZuOK3N2vJlx58+LRQyY3Xm0ZsgjZg+oPQLi7dUcNXi0LOJw1pgNtB7XG6CBy+U75SYfPTSQAgZTNUDnQHt67wnbZyvwLgKiMN3oCZB3C76tdewpLFgIP2C88rbi4Y+QT3+8S5USMICZXWj1pkEDeUU3lOYGB3alSoEiMIjgX4WlgNF2EibIwQIXauWXSRg2SAOHIU5IIIMoZkhhWiJaiFVbKo6AQEgQXrTAazO1JhkBrBG3Y2Y6EsUhaGn95hprSN0oWpFE7rhkeaQBchGOEWnwEmc0uKWZj0LeuNV3W4Y2lZHFlQCSRjTIl8uZ+kG5HU/3sRlnTG2ytyadytnD3HrmuRcSn+0h1dycexIK1KCjYaCnjCCVqOFFJTZ5GkUUjESWaUIKU2lgCmAKKQIUjHapXRKE+t2og1VgankNYnohqKJ2CmKplso6GKz7WYCgqxeuyoF8u9IQAgA7',
11637			msg: null,
11638			msgText: '<em>Loading the next set of posts...</em>',
11639			selector: null,
11640			speed: 'fast',
11641			start: undefined
11642		},
11643		state: {
11644			isDuringAjax: false,
11645			isInvalidPage: false,
11646			isDestroyed: false,
11647			isDone: false, // For when it goes all the way through the archive.
11648			isPaused: false,
11649			isBeyondMaxPage: false,
11650			currPage: 1
11651		},
11652		debug: false,
11653		behavior: undefined,
11654		binder: $(window), // used to cache the selector
11655		nextSelector: 'div.navigation a:first',
11656		navSelector: 'div.navigation',
11657		contentSelector: null, // rename to pageFragment
11658		extraScrollPx: 150,
11659		itemSelector: 'div.post',
11660		animate: false,
11661		pathParse: undefined,
11662		dataType: 'html',
11663		appendCallback: true,
11664		bufferPx: 40,
11665		errorCallback: function () { },
11666		infid: 0, //Instance ID
11667		pixelsFromNavToBottom: undefined,
11668		path: undefined, // Either parts of a URL as an array (e.g. ["/page/", "/"] or a function that takes in the page number and returns a URL
11669		prefill: false, // When the document is smaller than the window, load data until the document is larger or links are exhausted
11670		maxPage: undefined // to manually control maximum page (when maxPage is undefined, maximum page limitation is not work)
11671	};
11672
11673	$.infinitescroll.prototype = {
11674
11675		/*
11676			----------------------------
11677			Private methods
11678			----------------------------
11679			*/
11680
11681		// Bind or unbind from scroll
11682		_binding: function infscr_binding(binding) {
11683
11684			var instance = this,
11685				opts = instance.options;
11686
11687			opts.v = '2.0b2.120520';
11688
11689			// if behavior is defined and this function is extended, call that instead of default
11690			if (!!opts.behavior && this['_binding_' + opts.behavior] !== undefined) {
11691				this['_binding_' + opts.behavior].call(this);
11692				return;
11693			}
11694
11695			if (binding !== 'bind' && binding !== 'unbind') {
11696				this._debug('Binding value  ' + binding + ' not valid');
11697				return false;
11698			}
11699
11700			if (binding === 'unbind') {
11701				(this.options.binder).unbind('smartscroll.infscr.' + instance.options.infid);
11702			} else {
11703				(this.options.binder)[binding]('smartscroll.infscr.' + instance.options.infid, function () {
11704					instance.scroll();
11705				});
11706			}
11707
11708			this._debug('Binding', binding);
11709		},
11710
11711		// Fundamental aspects of the plugin are initialized
11712		_create: function infscr_create(options, callback) {
11713
11714			// Add custom options to defaults
11715			var opts = $.extend(true, {}, $.infinitescroll.defaults, options);
11716			this.options = opts;
11717			var $window = $(window);
11718			var instance = this;
11719
11720			// Validate selectors
11721			if (!instance._validate(options)) {
11722				return false;
11723			}
11724
11725			// Validate page fragment path
11726			var path = $(opts.nextSelector).attr('href');
11727			if (!path) {
11728				this._debug('Navigation selector not found');
11729				return false;
11730			}
11731
11732			// Set the path to be a relative URL from root.
11733			opts.path = opts.path || this._determinepath(path);
11734
11735			// contentSelector is 'page fragment' option for .load() / .ajax() calls
11736			opts.contentSelector = opts.contentSelector || this.element;
11737
11738			// loading.selector - if we want to place the load message in a specific selector, defaulted to the contentSelector
11739			opts.loading.selector = opts.loading.selector || opts.contentSelector;
11740
11741			// Define loading.msg
11742			opts.loading.msg = opts.loading.msg || $('<div id="infscr-loading"><img alt="Loading..." src="' + opts.loading.img + '" /><div>' + opts.loading.msgText + '</div></div>');
11743
11744			// Preload loading.img
11745			(new Image()).src = opts.loading.img;
11746
11747			// distance from nav links to bottom
11748			// computed as: height of the document + top offset of container - top offset of nav link
11749			if (opts.pixelsFromNavToBottom === undefined) {
11750				opts.pixelsFromNavToBottom = $(document).height() - $(opts.navSelector).offset().top;
11751				this._debug('pixelsFromNavToBottom: ' + opts.pixelsFromNavToBottom);
11752			}
11753
11754			var self = this;
11755
11756			// determine loading.start actions
11757			opts.loading.start = opts.loading.start || function () {
11758				$(opts.navSelector).hide();
11759				opts.loading.msg
11760					.appendTo(opts.loading.selector)
11761					.show(opts.loading.speed, $.proxy(function () {
11762						this.beginAjax(opts);
11763					}, self));
11764			};
11765
11766			// determine loading.finished actions
11767			opts.loading.finished = opts.loading.finished || function () {
11768				if (!opts.state.isBeyondMaxPage)
11769					opts.loading.msg.fadeOut(opts.loading.speed);
11770			};
11771
11772			// callback loading
11773			opts.callback = function (instance, data, url) {
11774				if (!!opts.behavior && instance['_callback_' + opts.behavior] !== undefined) {
11775					instance['_callback_' + opts.behavior].call($(opts.contentSelector)[0], data, url);
11776				}
11777
11778				if (callback) {
11779					callback.call($(opts.contentSelector)[0], data, opts, url);
11780				}
11781
11782				if (opts.prefill) {
11783					$window.bind('resize.infinite-scroll', instance._prefill);
11784				}
11785			};
11786
11787			if (options.debug) {
11788				// Tell IE9 to use its built-in console
11789				if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log === 'object') {
11790					['log', 'info', 'warn', 'error', 'assert', 'dir', 'clear', 'profile', 'profileEnd']
11791						.forEach(function (method) {
11792							console[method] = this.call(console[method], console);
11793						}, Function.prototype.bind);
11794				}
11795			}
11796
11797			this._setup();
11798
11799			// Setups the prefill method for use
11800			if (opts.prefill) {
11801				this._prefill();
11802			}
11803
11804			// Return true to indicate successful creation
11805			return true;
11806		},
11807
11808		_prefill: function infscr_prefill() {
11809			var instance = this;
11810			var $window = $(window);
11811
11812			function needsPrefill() {
11813				return ($(instance.options.contentSelector).height() <= $window.height());
11814			}
11815
11816			this._prefill = function () {
11817				if (needsPrefill()) {
11818					instance.scroll();
11819				}
11820
11821				$window.bind('resize.infinite-scroll', function () {
11822					if (needsPrefill()) {
11823						$window.unbind('resize.infinite-scroll');
11824						instance.scroll();
11825					}
11826				});
11827			};
11828
11829			// Call self after setting up the new function
11830			this._prefill();
11831		},
11832
11833		// Console log wrapper
11834		_debug: function infscr_debug() {
11835			if (true !== this.options.debug) {
11836				return;
11837			}
11838
11839			if (typeof console !== 'undefined' && typeof console.log === 'function') {
11840				// Modern browsers
11841				// Single argument, which is a string
11842				if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') {
11843					console.log((Array.prototype.slice.call(arguments)).toString());
11844				} else {
11845					console.log(Array.prototype.slice.call(arguments));
11846				}
11847			} else if (!Function.prototype.bind && typeof console !== 'undefined' && typeof console.log === 'object') {
11848				// IE8
11849				Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
11850			}
11851		},
11852
11853		// find the number to increment in the path.
11854		_determinepath: function infscr_determinepath(path) {
11855
11856			var opts = this.options;
11857
11858			// if behavior is defined and this function is extended, call that instead of default
11859			if (!!opts.behavior && this['_determinepath_' + opts.behavior] !== undefined) {
11860				return this['_determinepath_' + opts.behavior].call(this, path);
11861			}
11862
11863			var url = new URL(path);
11864			var pathname = url.pathname;
11865			var hasNumber = /\d/.test(pathname);
11866
11867			if (!!opts.pathParse) {
11868				this._debug('pathParse manual');
11869				return opts.pathParse(path, this.options.state.currPage + 1);
11870            } else if (hasNumber && path.match(/(\?|\&)(upage=)(\d+)/)) {
11871				var parts = path.split(/(\?|\&)(upage=)(\d+)/);
11872				return [parts[0] + parts[1] + parts[2], parts[4]];
11873            } else if (path.match(/^(.*?)\b2\b(.*?$)/)) {
11874				path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);
11875
11876                // if there is any 2 in the url at all.
11877            } else if (path.match(/^(.*?)2(.*?$)/)) {
11878                // page= is used in django:
11879                // http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127
11880                if (path.match(/^(.*?page=)2(\/.*|$)/)) {
11881                    path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);
11882                    return path;
11883                }
11884
11885                path = path.match(/^(.*?)2(.*?$)/).slice(1);
11886
11887            } else {
11888                // page= is used in drupal too but second page is page=1 not page=2:
11889                // thx Jerod Fritz, vladikoff
11890                if (path.match(/^(.*?page=)1(\/.*|$)/)) {
11891                    path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);
11892                    return path;
11893                } else {
11894                    this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.");
11895                    // Get rid of isInvalidPage to allow permalink to state
11896                    opts.state.isInvalidPage = true;  //prevent it from running on this page.
11897                }
11898            }
11899            this._debug('determinePath', path);
11900            return path;
11901
11902        },
11903
11904        // Custom error
11905        _error: function infscr_error(xhr) {
11906
11907            var opts = this.options;
11908
11909            // if behavior is defined and this function is extended, call that instead of default
11910            if (!!opts.behavior && this['_error_'+opts.behavior] !== undefined) {
11911                this['_error_'+opts.behavior].call(this,xhr);
11912                return;
11913            }
11914
11915            if (xhr !== 'destroy' && xhr !== 'end') {
11916                xhr = 'unknown';
11917            }
11918
11919            this._debug('Error', xhr);
11920
11921            if (xhr === 'end' || opts.state.isBeyondMaxPage) {
11922                this._showdonemsg();
11923            }
11924
11925            opts.state.isDone = true;
11926            opts.state.currPage = 1; // if you need to go back to this instance
11927            opts.state.isPaused = false;
11928            opts.state.isBeyondMaxPage = false;
11929            this._binding('unbind');
11930
11931        },
11932
11933        // Load Callback
11934        _loadcallback: function infscr_loadcallback(box, data, url) {
11935            var opts = this.options,
11936            callback = this.options.callback, // GLOBAL OBJECT FOR CALLBACK
11937            result = (opts.state.isDone) ? 'done' : (!opts.appendCallback) ? 'no-append' : 'append',
11938            frag;
11939
11940            // if behavior is defined and this function is extended, call that instead of default
11941            if (!!opts.behavior && this['_loadcallback_'+opts.behavior] !== undefined) {
11942                this['_loadcallback_'+opts.behavior].call(this,box,data);
11943                return;
11944            }
11945
11946            switch (result) {
11947                case 'done':
11948                    this._showdonemsg();
11949                    return false;
11950
11951                case 'no-append':
11952                    if (opts.dataType === 'html') {
11953                        data = '<div>' + data + '</div>';
11954                        data = $(data).find(opts.itemSelector);
11955                    }
11956
11957                    // if it didn't return anything
11958                    if (data.length === 0) {
11959                        return this._error('end');
11960                    }
11961
11962                    break;
11963
11964                case 'append':
11965                    var children = box.children();
11966                    // if it didn't return anything
11967                    if (children.length === 0) {
11968                        return this._error('end');
11969                    }
11970
11971                    // use a documentFragment because it works when content is going into a table or UL
11972                    frag = document.createDocumentFragment();
11973                    while (box[0].firstChild) {
11974                        frag.appendChild(box[0].firstChild);
11975                    }
11976
11977                    this._debug('contentSelector', $(opts.contentSelector)[0]);
11978                    $(opts.contentSelector)[0].appendChild(frag);
11979                    // previously, we would pass in the new DOM element as context for the callback
11980                    // however we're now using a documentfragment, which doesn't have parents or children,
11981                    // so the context is the contentContainer guy, and we pass in an array
11982                    // of the elements collected as the first argument.
11983
11984                    data = children.get();
11985                    break;
11986            }
11987
11988            // loadingEnd function
11989            opts.loading.finished.call($(opts.contentSelector)[0],opts);
11990
11991            // smooth scroll to ease in the new content
11992            if (opts.animate) {
11993                var scrollTo = $(window).scrollTop() + $(opts.loading.msg).height() + opts.extraScrollPx + 'px';
11994                $('html,body').animate({ scrollTop: scrollTo }, 800, function () { opts.state.isDuringAjax = false; });
11995            }
11996
11997            if (!opts.animate) {
11998                // once the call is done, we can allow it again.
11999                opts.state.isDuringAjax = false;
12000            }
12001
12002            callback(this, data, url);
12003
12004            if (opts.prefill) {
12005                this._prefill();
12006            }
12007        },
12008
12009        _nearbottom: function infscr_nearbottom() {
12010
12011            var opts = this.options,
12012            pixelsFromWindowBottomToBottom = 0 + $(document).height() - (opts.binder.scrollTop()) - $(window).height();
12013
12014            // if behavior is defined and this function is extended, call that instead of default
12015            if (!!opts.behavior && this['_nearbottom_'+opts.behavior] !== undefined) {
12016                return this['_nearbottom_'+opts.behavior].call(this);
12017            }
12018
12019            this._debug('math:', pixelsFromWindowBottomToBottom, opts.pixelsFromNavToBottom);
12020
12021            // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....
12022            return (pixelsFromWindowBottomToBottom - opts.bufferPx < opts.pixelsFromNavToBottom);
12023
12024        },
12025
12026        // Pause / temporarily disable plugin from firing
12027        _pausing: function infscr_pausing(pause) {
12028
12029            var opts = this.options;
12030
12031            // if behavior is defined and this function is extended, call that instead of default
12032            if (!!opts.behavior && this['_pausing_'+opts.behavior] !== undefined) {
12033                this['_pausing_'+opts.behavior].call(this,pause);
12034                return;
12035            }
12036
12037            // If pause is not 'pause' or 'resume', toggle it's value
12038            if (pause !== 'pause' && pause !== 'resume' && pause !== null) {
12039                this._debug('Invalid argument. Toggling pause value instead');
12040            }
12041
12042            pause = (pause && (pause === 'pause' || pause === 'resume')) ? pause : 'toggle';
12043
12044            switch (pause) {
12045                case 'pause':
12046                    opts.state.isPaused = true;
12047                break;
12048
12049                case 'resume':
12050                    opts.state.isPaused = false;
12051                break;
12052
12053                case 'toggle':
12054                    opts.state.isPaused = !opts.state.isPaused;
12055                break;
12056            }
12057
12058            this._debug('Paused', opts.state.isPaused);
12059            return false;
12060
12061        },
12062
12063        // Behavior is determined
12064        // If the behavior option is undefined, it will set to default and bind to scroll
12065        _setup: function infscr_setup() {
12066
12067            var opts = this.options;
12068
12069            // if behavior is defined and this function is extended, call that instead of default
12070            if (!!opts.behavior && this['_setup_'+opts.behavior] !== undefined) {
12071                this['_setup_'+opts.behavior].call(this);
12072                return;
12073            }
12074
12075            this._binding('bind');
12076
12077            return false;
12078
12079        },
12080
12081        // Show done message
12082        _showdonemsg: function infscr_showdonemsg() {
12083
12084            var opts = this.options;
12085
12086            // if behavior is defined and this function is extended, call that instead of default
12087            if (!!opts.behavior && this['_showdonemsg_'+opts.behavior] !== undefined) {
12088                this['_showdonemsg_'+opts.behavior].call(this);
12089                return;
12090            }
12091
12092            opts.loading.msg
12093            .find('img')
12094            .hide()
12095            .parent()
12096            .find('div').html(opts.loading.finishedMsg).animate({ opacity: 1 }, 2000, function () {
12097                $(this).parent().fadeOut(opts.loading.speed);
12098            });
12099
12100            // user provided callback when done
12101            opts.errorCallback.call($(opts.contentSelector)[0],'done');
12102        },
12103
12104        // grab each selector option and see if any fail
12105        _validate: function infscr_validate(opts) {
12106            for (var key in opts) {
12107                if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0) {
12108                    this._debug('Your ' + key + ' found no elements.');
12109                    return false;
12110                }
12111            }
12112
12113            return true;
12114        },
12115
12116        /*
12117            ----------------------------
12118            Public methods
12119            ----------------------------
12120            */
12121
12122        // Bind to scroll
12123        bind: function infscr_bind() {
12124            this._binding('bind');
12125        },
12126
12127        // Destroy current instance of plugin
12128        destroy: function infscr_destroy() {
12129            this.options.state.isDestroyed = true;
12130            this.options.loading.finished();
12131            return this._error('destroy');
12132        },
12133
12134        // Set pause value to false
12135        pause: function infscr_pause() {
12136            this._pausing('pause');
12137        },
12138
12139        // Set pause value to false
12140        resume: function infscr_resume() {
12141            this._pausing('resume');
12142        },
12143
12144        beginAjax: function infscr_ajax(opts) {
12145            var instance = this,
12146                path = opts.path,
12147                box, desturl, method, condition;
12148
12149			// increment the URL bit. e.g. /page/3/
12150            opts.state.currPage++;
12151
12152            // Manually control maximum page
12153            if ( opts.maxPage !== undefined && opts.state.currPage > opts.maxPage ){
12154                opts.state.isBeyondMaxPage = true;
12155                this.destroy();
12156                return;
12157            }
12158
12159            // if we're dealing with a table we can't use DIVs
12160            box = $(opts.contentSelector).is('table, tbody') ? $('<tbody/>') : $('<div/>');
12161
12162			desturl = (typeof path === 'function') ? path(opts.state.currPage) : path.join(opts.state.currPage);
12163
12164            instance._debug('heading into ajax', desturl);
12165
12166            method = (opts.dataType === 'html' || opts.dataType === 'json' ) ? opts.dataType : 'html+callback';
12167            if (opts.appendCallback && opts.dataType === 'html') {
12168                method += '+callback';
12169            }
12170
12171            switch (method) {
12172                case 'html+callback':
12173                    instance._debug('Using HTML via .load() method');
12174                    box.load(desturl + ' ' + opts.itemSelector, undefined, function infscr_ajax_callback(responseText) {
12175                        instance._loadcallback(box, responseText, desturl);
12176                    });
12177
12178                    break;
12179
12180                case 'html':
12181                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
12182                    $.ajax({
12183                        // params
12184                        url: desturl,
12185                        dataType: opts.dataType,
12186                        complete: function infscr_ajax_callback(jqXHR, textStatus) {
12187                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');
12188                            if (condition) {
12189                                instance._loadcallback(box, jqXHR.responseText, desturl);
12190                            } else {
12191                                instance._error('end');
12192                            }
12193                        }
12194                    });
12195
12196                    break;
12197                case 'json':
12198                    instance._debug('Using ' + (method.toUpperCase()) + ' via $.ajax() method');
12199                    $.ajax({
12200                        dataType: 'json',
12201                        type: 'GET',
12202                        url: desturl,
12203                        success: function (data, textStatus, jqXHR) {
12204                            condition = (typeof (jqXHR.isResolved) !== 'undefined') ? (jqXHR.isResolved()) : (textStatus === 'success' || textStatus === 'notmodified');
12205                            if (opts.appendCallback) {
12206                                // if appendCallback is true, you must defined template in options.
12207                                // note that data passed into _loadcallback is already an html (after processed in opts.template(data)).
12208                                if (opts.template !== undefined) {
12209                                    var theData = opts.template(data);
12210                                    box.append(theData);
12211                                    if (condition) {
12212                                        instance._loadcallback(box, theData);
12213                                    } else {
12214                                        instance._error('end');
12215                                    }
12216                                } else {
12217                                    instance._debug('template must be defined.');
12218                                    instance._error('end');
12219                                }
12220                            } else {
12221                                // if appendCallback is false, we will pass in the JSON object. you should handle it yourself in your callback.
12222                                if (condition) {
12223                                    instance._loadcallback(box, data, desturl);
12224                                } else {
12225                                    instance._error('end');
12226                                }
12227                            }
12228                        },
12229                        error: function() {
12230                            instance._debug('JSON ajax request failed.');
12231                            instance._error('end');
12232                        }
12233                    });
12234
12235                    break;
12236            }
12237        },
12238
12239        // Retrieve next set of content items
12240        retrieve: function infscr_retrieve(pageNum) {
12241            pageNum = pageNum || null;
12242
12243            var instance = this,
12244            opts = instance.options;
12245
12246            // if behavior is defined and this function is extended, call that instead of default
12247            if (!!opts.behavior && this['retrieve_'+opts.behavior] !== undefined) {
12248                this['retrieve_'+opts.behavior].call(this,pageNum);
12249                return;
12250            }
12251
12252            // for manual triggers, if destroyed, get out of here
12253            if (opts.state.isDestroyed) {
12254                this._debug('Instance is destroyed');
12255                return false;
12256            }
12257
12258            // we dont want to fire the ajax multiple times
12259            opts.state.isDuringAjax = true;
12260
12261            opts.loading.start.call($(opts.contentSelector)[0],opts);
12262        },
12263
12264        // Check to see next page is needed
12265        scroll: function infscr_scroll() {
12266
12267            var opts = this.options,
12268            state = opts.state;
12269
12270            // if behavior is defined and this function is extended, call that instead of default
12271            if (!!opts.behavior && this['scroll_'+opts.behavior] !== undefined) {
12272                this['scroll_'+opts.behavior].call(this);
12273                return;
12274            }
12275
12276            if (state.isDuringAjax || state.isInvalidPage || state.isDone || state.isDestroyed || state.isPaused) {
12277                return;
12278            }
12279
12280            if (!this._nearbottom()) {
12281                return;
12282            }
12283
12284            this.retrieve();
12285
12286        },
12287
12288        // Toggle pause value
12289        toggle: function infscr_toggle() {
12290            this._pausing();
12291        },
12292
12293        // Unbind from scroll
12294        unbind: function infscr_unbind() {
12295            this._binding('unbind');
12296        },
12297
12298        // update options
12299        update: function infscr_options(key) {
12300            if ($.isPlainObject(key)) {
12301                this.options = $.extend(true,this.options,key);
12302            }
12303        }
12304    };
12305
12306
12307    /*
12308        ----------------------------
12309        Infinite Scroll function
12310        ----------------------------
12311
12312        Borrowed logic from the following...
12313
12314        jQuery UI
12315        - https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.widget.js
12316
12317        jCarousel
12318        - https://github.com/jsor/jcarousel/blob/master/lib/jquery.jcarousel.js
12319
12320        Masonry
12321        - https://github.com/desandro/masonry/blob/master/jquery.masonry.js
12322
12323*/
12324
12325    $.fn.infinitescroll = function infscr_init(options, callback) {
12326
12327
12328        var thisCall = typeof options;
12329
12330        switch (thisCall) {
12331
12332            // method
12333            case 'string':
12334                var args = Array.prototype.slice.call(arguments, 1);
12335
12336                this.each(function () {
12337                    var instance = $.data(this, 'infinitescroll');
12338
12339                    if (!instance) {
12340                        // not setup yet
12341                        // return $.error('Method ' + options + ' cannot be called until Infinite Scroll is setup');
12342                        return false;
12343                    }
12344
12345                    if (!$.isFunction(instance[options]) || options.charAt(0) === '_') {
12346                        // return $.error('No such method ' + options + ' for Infinite Scroll');
12347                        return false;
12348                    }
12349
12350                    // no errors!
12351                    instance[options].apply(instance, args);
12352                });
12353
12354            break;
12355
12356            // creation
12357            case 'object':
12358
12359                this.each(function () {
12360
12361                var instance = $.data(this, 'infinitescroll');
12362
12363                if (instance) {
12364
12365                    // update options of current instance
12366                    instance.update(options);
12367
12368                } else {
12369
12370                    // initialize new instance
12371                    instance = new $.infinitescroll(options, callback, this);
12372
12373                    // don't attach if instantiation failed
12374                    if (!instance.failed) {
12375                        $.data(this, 'infinitescroll', instance);
12376                    }
12377
12378                }
12379
12380            });
12381
12382            break;
12383
12384        }
12385
12386        return this;
12387    };
12388
12389
12390
12391    /*
12392     * smartscroll: debounced scroll event for jQuery *
12393     * https://github.com/lukeshumard/smartscroll
12394     * Based on smartresize by @louis_remi: https://github.com/lrbabe/jquery.smartresize.js *
12395     * Copyright 2011 Louis-Remi & Luke Shumard * Licensed under the MIT license. *
12396     */
12397
12398    var event = $.event,
12399    scrollTimeout;
12400
12401    event.special.smartscroll = {
12402        setup: function () {
12403            $(this).bind('scroll', event.special.smartscroll.handler);
12404        },
12405        teardown: function () {
12406            $(this).unbind('scroll', event.special.smartscroll.handler);
12407        },
12408        handler: function (event, execAsap) {
12409            // Save the context
12410            var context = this,
12411            args = arguments;
12412
12413            // set correct event type
12414            event.type = 'smartscroll';
12415
12416            if (scrollTimeout) { clearTimeout(scrollTimeout); }
12417            scrollTimeout = setTimeout(function () {
12418                $(context).trigger('smartscroll', args);
12419            }, execAsap === 'execAsap' ? 0 : 100);
12420        }
12421    };
12422
12423    $.fn.smartscroll = function (fn) {
12424        return fn ? this.bind('smartscroll', fn) : this.trigger('smartscroll', ['execAsap']);
12425    };
12426
12427}));
12428
12429/*!
12430Waypoints - 4.0.1
12431Copyright © 2011-2016 Caleb Troughton
12432Licensed under the MIT license.
12433https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
12434*/
12435(function() {
12436  'use strict'
12437
12438  var keyCounter = 0
12439  var allWaypoints = {}
12440
12441  /* http://imakewebthings.com/waypoints/api/waypoint */
12442  function Waypoint(options) {
12443    if (!options) {
12444      throw new Error('No options passed to Waypoint constructor')
12445    }
12446    if (!options.element) {
12447      throw new Error('No element option passed to Waypoint constructor')
12448    }
12449    if (!options.handler) {
12450      throw new Error('No handler option passed to Waypoint constructor')
12451    }
12452
12453    this.key = 'waypoint-' + keyCounter
12454    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
12455    this.element = this.options.element
12456    this.adapter = new Waypoint.Adapter(this.element)
12457    this.callback = options.handler
12458    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
12459    this.enabled = this.options.enabled
12460    this.triggerPoint = null
12461    this.group = Waypoint.Group.findOrCreate({
12462      name: this.options.group,
12463      axis: this.axis
12464    })
12465    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
12466
12467    if (Waypoint.offsetAliases[this.options.offset]) {
12468      this.options.offset = Waypoint.offsetAliases[this.options.offset]
12469    }
12470    this.group.add(this)
12471    this.context.add(this)
12472    allWaypoints[this.key] = this
12473    keyCounter += 1
12474  }
12475
12476  /* Private */
12477  Waypoint.prototype.queueTrigger = function(direction) {
12478    this.group.queueTrigger(this, direction)
12479  }
12480
12481  /* Private */
12482  Waypoint.prototype.trigger = function(args) {
12483    if (!this.enabled) {
12484      return
12485    }
12486    if (this.callback) {
12487      this.callback.apply(this, args)
12488    }
12489  }
12490
12491  /* Public */
12492  /* http://imakewebthings.com/waypoints/api/destroy */
12493  Waypoint.prototype.destroy = function() {
12494    this.context.remove(this)
12495    this.group.remove(this)
12496    delete allWaypoints[this.key]
12497  }
12498
12499  /* Public */
12500  /* http://imakewebthings.com/waypoints/api/disable */
12501  Waypoint.prototype.disable = function() {
12502    this.enabled = false
12503    return this
12504  }
12505
12506  /* Public */
12507  /* http://imakewebthings.com/waypoints/api/enable */
12508  Waypoint.prototype.enable = function() {
12509    this.context.refresh()
12510    this.enabled = true
12511    return this
12512  }
12513
12514  /* Public */
12515  /* http://imakewebthings.com/waypoints/api/next */
12516  Waypoint.prototype.next = function() {
12517    return this.group.next(this)
12518  }
12519
12520  /* Public */
12521  /* http://imakewebthings.com/waypoints/api/previous */
12522  Waypoint.prototype.previous = function() {
12523    return this.group.previous(this)
12524  }
12525
12526  /* Private */
12527  Waypoint.invokeAll = function(method) {
12528    var allWaypointsArray = []
12529    for (var waypointKey in allWaypoints) {
12530      allWaypointsArray.push(allWaypoints[waypointKey])
12531    }
12532    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
12533      allWaypointsArray[i][method]()
12534    }
12535  }
12536
12537  /* Public */
12538  /* http://imakewebthings.com/waypoints/api/destroy-all */
12539  Waypoint.destroyAll = function() {
12540    Waypoint.invokeAll('destroy')
12541  }
12542
12543  /* Public */
12544  /* http://imakewebthings.com/waypoints/api/disable-all */
12545  Waypoint.disableAll = function() {
12546    Waypoint.invokeAll('disable')
12547  }
12548
12549  /* Public */
12550  /* http://imakewebthings.com/waypoints/api/enable-all */
12551  Waypoint.enableAll = function() {
12552    Waypoint.Context.refreshAll()
12553    for (var waypointKey in allWaypoints) {
12554      allWaypoints[waypointKey].enabled = true
12555    }
12556    return this
12557  }
12558
12559  /* Public */
12560  /* http://imakewebthings.com/waypoints/api/refresh-all */
12561  Waypoint.refreshAll = function() {
12562    Waypoint.Context.refreshAll()
12563  }
12564
12565  /* Public */
12566  /* http://imakewebthings.com/waypoints/api/viewport-height */
12567  Waypoint.viewportHeight = function() {
12568    return window.innerHeight || document.documentElement.clientHeight
12569  }
12570
12571  /* Public */
12572  /* http://imakewebthings.com/waypoints/api/viewport-width */
12573  Waypoint.viewportWidth = function() {
12574    return document.documentElement.clientWidth
12575  }
12576
12577  Waypoint.adapters = []
12578
12579  Waypoint.defaults = {
12580    context: window,
12581    continuous: true,
12582    enabled: true,
12583    group: 'default',
12584    horizontal: false,
12585    offset: 0
12586  }
12587
12588  Waypoint.offsetAliases = {
12589    'bottom-in-view': function() {
12590      return this.context.innerHeight() - this.adapter.outerHeight()
12591    },
12592    'right-in-view': function() {
12593      return this.context.innerWidth() - this.adapter.outerWidth()
12594    }
12595  }
12596
12597  window.Waypoint = Waypoint
12598}())
12599;(function() {
12600  'use strict'
12601
12602  function requestAnimationFrameShim(callback) {
12603    window.setTimeout(callback, 1000 / 60)
12604  }
12605
12606  var keyCounter = 0
12607  var contexts = {}
12608  var Waypoint = window.Waypoint
12609  var oldWindowLoad = window.onload
12610
12611  /* http://imakewebthings.com/waypoints/api/context */
12612  function Context(element) {
12613    this.element = element
12614    this.Adapter = Waypoint.Adapter
12615    this.adapter = new this.Adapter(element)
12616    this.key = 'waypoint-context-' + keyCounter
12617    this.didScroll = false
12618    this.didResize = false
12619    this.oldScroll = {
12620      x: this.adapter.scrollLeft(),
12621      y: this.adapter.scrollTop()
12622    }
12623    this.waypoints = {
12624      vertical: {},
12625      horizontal: {}
12626    }
12627
12628    element.waypointContextKey = this.key
12629    contexts[element.waypointContextKey] = this
12630    keyCounter += 1
12631    if (!Waypoint.windowContext) {
12632      Waypoint.windowContext = true
12633      Waypoint.windowContext = new Context(window)
12634    }
12635
12636    this.createThrottledScrollHandler()
12637    this.createThrottledResizeHandler()
12638  }
12639
12640  /* Private */
12641  Context.prototype.add = function(waypoint) {
12642    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
12643    this.waypoints[axis][waypoint.key] = waypoint
12644    this.refresh()
12645  }
12646
12647  /* Private */
12648  Context.prototype.checkEmpty = function() {
12649    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
12650    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
12651    var isWindow = this.element == this.element.window
12652    if (horizontalEmpty && verticalEmpty && !isWindow) {
12653      this.adapter.off('.waypoints')
12654      delete contexts[this.key]
12655    }
12656  }
12657
12658  /* Private */
12659  Context.prototype.createThrottledResizeHandler = function() {
12660    var self = this
12661
12662    function resizeHandler() {
12663      self.handleResize()
12664      self.didResize = false
12665    }
12666
12667    this.adapter.on('resize.waypoints', function() {
12668      if (!self.didResize) {
12669        self.didResize = true
12670        Waypoint.requestAnimationFrame(resizeHandler)
12671      }
12672    })
12673  }
12674
12675  /* Private */
12676  Context.prototype.createThrottledScrollHandler = function() {
12677    var self = this
12678    function scrollHandler() {
12679      self.handleScroll()
12680      self.didScroll = false
12681    }
12682
12683    this.adapter.on('scroll.waypoints', function() {
12684      if (!self.didScroll || Waypoint.isTouch) {
12685        self.didScroll = true
12686        Waypoint.requestAnimationFrame(scrollHandler)
12687      }
12688    })
12689  }
12690
12691  /* Private */
12692  Context.prototype.handleResize = function() {
12693    Waypoint.Context.refreshAll()
12694  }
12695
12696  /* Private */
12697  Context.prototype.handleScroll = function() {
12698    var triggeredGroups = {}
12699    var axes = {
12700      horizontal: {
12701        newScroll: this.adapter.scrollLeft(),
12702        oldScroll: this.oldScroll.x,
12703        forward: 'right',
12704        backward: 'left'
12705      },
12706      vertical: {
12707        newScroll: this.adapter.scrollTop(),
12708        oldScroll: this.oldScroll.y,
12709        forward: 'down',
12710        backward: 'up'
12711      }
12712    }
12713
12714    for (var axisKey in axes) {
12715      var axis = axes[axisKey]
12716      var isForward = axis.newScroll > axis.oldScroll
12717      var direction = isForward ? axis.forward : axis.backward
12718
12719      for (var waypointKey in this.waypoints[axisKey]) {
12720        var waypoint = this.waypoints[axisKey][waypointKey]
12721        if (waypoint.triggerPoint === null) {
12722          continue
12723        }
12724        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
12725        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
12726        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
12727        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
12728        if (crossedForward || crossedBackward) {
12729          waypoint.queueTrigger(direction)
12730          triggeredGroups[waypoint.group.id] = waypoint.group
12731        }
12732      }
12733    }
12734
12735    for (var groupKey in triggeredGroups) {
12736      triggeredGroups[groupKey].flushTriggers()
12737    }
12738
12739    this.oldScroll = {
12740      x: axes.horizontal.newScroll,
12741      y: axes.vertical.newScroll
12742    }
12743  }
12744
12745  /* Private */
12746  Context.prototype.innerHeight = function() {
12747    /*eslint-disable eqeqeq */
12748    if (this.element == this.element.window) {
12749      return Waypoint.viewportHeight()
12750    }
12751    /*eslint-enable eqeqeq */
12752    return this.adapter.innerHeight()
12753  }
12754
12755  /* Private */
12756  Context.prototype.remove = function(waypoint) {
12757    delete this.waypoints[waypoint.axis][waypoint.key]
12758    this.checkEmpty()
12759  }
12760
12761  /* Private */
12762  Context.prototype.innerWidth = function() {
12763    /*eslint-disable eqeqeq */
12764    if (this.element == this.element.window) {
12765      return Waypoint.viewportWidth()
12766    }
12767    /*eslint-enable eqeqeq */
12768    return this.adapter.innerWidth()
12769  }
12770
12771  /* Public */
12772  /* http://imakewebthings.com/waypoints/api/context-destroy */
12773  Context.prototype.destroy = function() {
12774    var allWaypoints = []
12775    for (var axis in this.waypoints) {
12776      for (var waypointKey in this.waypoints[axis]) {
12777        allWaypoints.push(this.waypoints[axis][waypointKey])
12778      }
12779    }
12780    for (var i = 0, end = allWaypoints.length; i < end; i++) {
12781      allWaypoints[i].destroy()
12782    }
12783  }
12784
12785  /* Public */
12786  /* http://imakewebthings.com/waypoints/api/context-refresh */
12787  Context.prototype.refresh = function() {
12788    /*eslint-disable eqeqeq */
12789    var isWindow = this.element == this.element.window
12790    /*eslint-enable eqeqeq */
12791    var contextOffset = isWindow ? undefined : this.adapter.offset()
12792    var triggeredGroups = {}
12793    var axes
12794
12795    this.handleScroll()
12796    axes = {
12797      horizontal: {
12798        contextOffset: isWindow ? 0 : contextOffset.left,
12799        contextScroll: isWindow ? 0 : this.oldScroll.x,
12800        contextDimension: this.innerWidth(),
12801        oldScroll: this.oldScroll.x,
12802        forward: 'right',
12803        backward: 'left',
12804        offsetProp: 'left'
12805      },
12806      vertical: {
12807        contextOffset: isWindow ? 0 : contextOffset.top,
12808        contextScroll: isWindow ? 0 : this.oldScroll.y,
12809        contextDimension: this.innerHeight(),
12810        oldScroll: this.oldScroll.y,
12811        forward: 'down',
12812        backward: 'up',
12813        offsetProp: 'top'
12814      }
12815    }
12816
12817    for (var axisKey in axes) {
12818      var axis = axes[axisKey]
12819      for (var waypointKey in this.waypoints[axisKey]) {
12820        var waypoint = this.waypoints[axisKey][waypointKey]
12821        var adjustment = waypoint.options.offset
12822        var oldTriggerPoint = waypoint.triggerPoint
12823        var elementOffset = 0
12824        var freshWaypoint = oldTriggerPoint == null
12825        var contextModifier, wasBeforeScroll, nowAfterScroll
12826        var triggeredBackward, triggeredForward
12827
12828        if (waypoint.element !== waypoint.element.window) {
12829          elementOffset = waypoint.adapter.offset()[axis.offsetProp]
12830        }
12831
12832        if (typeof adjustment === 'function') {
12833          adjustment = adjustment.apply(waypoint)
12834        }
12835        else if (typeof adjustment === 'string') {
12836          adjustment = parseFloat(adjustment)
12837          if (waypoint.options.offset.indexOf('%') > - 1) {
12838            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
12839          }
12840        }
12841
12842        contextModifier = axis.contextScroll - axis.contextOffset
12843        waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)
12844        wasBeforeScroll = oldTriggerPoint < axis.oldScroll
12845        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
12846        triggeredBackward = wasBeforeScroll && nowAfterScroll
12847        triggeredForward = !wasBeforeScroll && !nowAfterScroll
12848
12849        if (!freshWaypoint && triggeredBackward) {
12850          waypoint.queueTrigger(axis.backward)
12851          triggeredGroups[waypoint.group.id] = waypoint.group
12852        }
12853        else if (!freshWaypoint && triggeredForward) {
12854          waypoint.queueTrigger(axis.forward)
12855          triggeredGroups[waypoint.group.id] = waypoint.group
12856        }
12857        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
12858          waypoint.queueTrigger(axis.forward)
12859          triggeredGroups[waypoint.group.id] = waypoint.group
12860        }
12861      }
12862    }
12863
12864    Waypoint.requestAnimationFrame(function() {
12865      for (var groupKey in triggeredGroups) {
12866        triggeredGroups[groupKey].flushTriggers()
12867      }
12868    })
12869
12870    return this
12871  }
12872
12873  /* Private */
12874  Context.findOrCreateByElement = function(element) {
12875    return Context.findByElement(element) || new Context(element)
12876  }
12877
12878  /* Private */
12879  Context.refreshAll = function() {
12880    for (var contextId in contexts) {
12881      contexts[contextId].refresh()
12882    }
12883  }
12884
12885  /* Public */
12886  /* http://imakewebthings.com/waypoints/api/context-find-by-element */
12887  Context.findByElement = function(element) {
12888    return contexts[element.waypointContextKey]
12889  }
12890
12891  window.onload = function() {
12892    if (oldWindowLoad) {
12893      oldWindowLoad()
12894    }
12895    Context.refreshAll()
12896  }
12897
12898
12899  Waypoint.requestAnimationFrame = function(callback) {
12900    var requestFn = window.requestAnimationFrame ||
12901      window.mozRequestAnimationFrame ||
12902      window.webkitRequestAnimationFrame ||
12903      requestAnimationFrameShim
12904    requestFn.call(window, callback)
12905  }
12906  Waypoint.Context = Context
12907}())
12908;(function() {
12909  'use strict'
12910
12911  function byTriggerPoint(a, b) {
12912    return a.triggerPoint - b.triggerPoint
12913  }
12914
12915  function byReverseTriggerPoint(a, b) {
12916    return b.triggerPoint - a.triggerPoint
12917  }
12918
12919  var groups = {
12920    vertical: {},
12921    horizontal: {}
12922  }
12923  var Waypoint = window.Waypoint
12924
12925  /* http://imakewebthings.com/waypoints/api/group */
12926  function Group(options) {
12927    this.name = options.name
12928    this.axis = options.axis
12929    this.id = this.name + '-' + this.axis
12930    this.waypoints = []
12931    this.clearTriggerQueues()
12932    groups[this.axis][this.name] = this
12933  }
12934
12935  /* Private */
12936  Group.prototype.add = function(waypoint) {
12937    this.waypoints.push(waypoint)
12938  }
12939
12940  /* Private */
12941  Group.prototype.clearTriggerQueues = function() {
12942    this.triggerQueues = {
12943      up: [],
12944      down: [],
12945      left: [],
12946      right: []
12947    }
12948  }
12949
12950  /* Private */
12951  Group.prototype.flushTriggers = function() {
12952    for (var direction in this.triggerQueues) {
12953      var waypoints = this.triggerQueues[direction]
12954      var reverse = direction === 'up' || direction === 'left'
12955      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
12956      for (var i = 0, end = waypoints.length; i < end; i += 1) {
12957        var waypoint = waypoints[i]
12958        if (waypoint.options.continuous || i === waypoints.length - 1) {
12959          waypoint.trigger([direction])
12960        }
12961      }
12962    }
12963    this.clearTriggerQueues()
12964  }
12965
12966  /* Private */
12967  Group.prototype.next = function(waypoint) {
12968    this.waypoints.sort(byTriggerPoint)
12969    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
12970    var isLast = index === this.waypoints.length - 1
12971    return isLast ? null : this.waypoints[index + 1]
12972  }
12973
12974  /* Private */
12975  Group.prototype.previous = function(waypoint) {
12976    this.waypoints.sort(byTriggerPoint)
12977    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
12978    return index ? this.waypoints[index - 1] : null
12979  }
12980
12981  /* Private */
12982  Group.prototype.queueTrigger = function(waypoint, direction) {
12983    this.triggerQueues[direction].push(waypoint)
12984  }
12985
12986  /* Private */
12987  Group.prototype.remove = function(waypoint) {
12988    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
12989    if (index > -1) {
12990      this.waypoints.splice(index, 1)
12991    }
12992  }
12993
12994  /* Public */
12995  /* http://imakewebthings.com/waypoints/api/first */
12996  Group.prototype.first = function() {
12997    return this.waypoints[0]
12998  }
12999
13000  /* Public */
13001  /* http://imakewebthings.com/waypoints/api/last */
13002  Group.prototype.last = function() {
13003    return this.waypoints[this.waypoints.length - 1]
13004  }
13005
13006  /* Private */
13007  Group.findOrCreate = function(options) {
13008    return groups[options.axis][options.name] || new Group(options)
13009  }
13010
13011  Waypoint.Group = Group
13012}())
13013;(function() {
13014  'use strict'
13015
13016  var $ = window.jQuery
13017  var Waypoint = window.Waypoint
13018
13019  function JQueryAdapter(element) {
13020    this.$element = $(element)
13021  }
13022
13023  $.each([
13024    'innerHeight',
13025    'innerWidth',
13026    'off',
13027    'offset',
13028    'on',
13029    'outerHeight',
13030    'outerWidth',
13031    'scrollLeft',
13032    'scrollTop'
13033  ], function(i, method) {
13034    JQueryAdapter.prototype[method] = function() {
13035      var args = Array.prototype.slice.call(arguments)
13036      return this.$element[method].apply(this.$element, args)
13037    }
13038  })
13039
13040  $.each([
13041    'extend',
13042    'inArray',
13043    'isEmptyObject'
13044  ], function(i, method) {
13045    JQueryAdapter[method] = $[method]
13046  })
13047
13048  Waypoint.adapters.push({
13049    name: 'jquery',
13050    Adapter: JQueryAdapter
13051  })
13052  Waypoint.Adapter = JQueryAdapter
13053}())
13054;(function() {
13055  'use strict'
13056
13057  var Waypoint = window.Waypoint
13058
13059  function createExtension(framework) {
13060    return function() {
13061      var waypoints = []
13062      var overrides = arguments[0]
13063
13064      if (framework.isFunction(arguments[0])) {
13065        overrides = framework.extend({}, arguments[1])
13066        overrides.handler = arguments[0]
13067      }
13068
13069      this.each(function() {
13070        var options = framework.extend({}, overrides, {
13071          element: this
13072        })
13073        if (typeof options.context === 'string') {
13074          options.context = framework(this).closest(options.context)[0]
13075        }
13076        waypoints.push(new Waypoint(options))
13077      })
13078
13079      return waypoints
13080    }
13081  }
13082
13083  if (window.jQuery) {
13084    window.jQuery.fn.waypoint = createExtension(window.jQuery)
13085  }
13086  if (window.Zepto) {
13087    window.Zepto.fn.waypoint = createExtension(window.Zepto)
13088  }
13089}())
13090;
13091/*!
13092Waypoints Inview Shortcut - 4.0.1
13093Copyright © 2011-2016 Caleb Troughton
13094Licensed under the MIT license.
13095https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
13096*/
13097(function() {
13098  'use strict'
13099
13100  function noop() {}
13101
13102  var Waypoint = window.Waypoint
13103
13104  /* http://imakewebthings.com/waypoints/shortcuts/inview */
13105  function Inview(options) {
13106    this.options = Waypoint.Adapter.extend({}, Inview.defaults, options)
13107    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
13108    this.waypoints = []
13109    this.element = this.options.element
13110    this.createWaypoints()
13111  }
13112
13113  /* Private */
13114  Inview.prototype.createWaypoints = function() {
13115    var configs = {
13116      vertical: [{
13117        down: 'enter',
13118        up: 'exited',
13119        offset: '100%'
13120      }, {
13121        down: 'entered',
13122        up: 'exit',
13123        offset: 'bottom-in-view'
13124      }, {
13125        down: 'exit',
13126        up: 'entered',
13127        offset: 0
13128      }, {
13129        down: 'exited',
13130        up: 'enter',
13131        offset: function() {
13132          return -this.adapter.outerHeight()
13133        }
13134      }],
13135      horizontal: [{
13136        right: 'enter',
13137        left: 'exited',
13138        offset: '100%'
13139      }, {
13140        right: 'entered',
13141        left: 'exit',
13142        offset: 'right-in-view'
13143      }, {
13144        right: 'exit',
13145        left: 'entered',
13146        offset: 0
13147      }, {
13148        right: 'exited',
13149        left: 'enter',
13150        offset: function() {
13151          return -this.adapter.outerWidth()
13152        }
13153      }]
13154    }
13155
13156    for (var i = 0, end = configs[this.axis].length; i < end; i++) {
13157      var config = configs[this.axis][i]
13158      this.createWaypoint(config)
13159    }
13160  }
13161
13162  /* Private */
13163  Inview.prototype.createWaypoint = function(config) {
13164    var self = this
13165    this.waypoints.push(new Waypoint({
13166      context: this.options.context,
13167      element: this.options.element,
13168      enabled: this.options.enabled,
13169      handler: (function(config) {
13170        return function(direction) {
13171          self.options[config[direction]].call(self, direction)
13172        }
13173      }(config)),
13174      offset: config.offset,
13175      horizontal: this.options.horizontal
13176    }))
13177  }
13178
13179  /* Public */
13180  Inview.prototype.destroy = function() {
13181    for (var i = 0, end = this.waypoints.length; i < end; i++) {
13182      this.waypoints[i].destroy()
13183    }
13184    this.waypoints = []
13185  }
13186
13187  Inview.prototype.disable = function() {
13188    for (var i = 0, end = this.waypoints.length; i < end; i++) {
13189      this.waypoints[i].disable()
13190    }
13191  }
13192
13193  Inview.prototype.enable = function() {
13194    for (var i = 0, end = this.waypoints.length; i < end; i++) {
13195      this.waypoints[i].enable()
13196    }
13197  }
13198
13199  Inview.defaults = {
13200    context: window,
13201    enabled: true,
13202    enter: noop,
13203    entered: noop,
13204    exit: noop,
13205    exited: noop
13206  }
13207
13208  Waypoint.Inview = Inview
13209}())
13210;
13211
13212/*
13213 * SmartMenus jQuery v0.9.6
13214 * http://www.smartmenus.org/
13215 *
13216 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd.
13217 * http://vadikom.com/
13218 *
13219 * Released under the MIT license:
13220 * http://www.opensource.org/licenses/MIT
13221 */
13222
13223(function($) {
13224
13225	var menuTrees = [],
13226		IE = !!window.createPopup, // we need to detect it, unfortunately
13227		IElt9 = IE && !document.defaultView,
13228		IElt8 = IE && !document.querySelector,
13229		IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined',
13230		mouse = false, // optimize for touch by default - we will detect for mouse input
13231		mouseDetectionEnabled = false;
13232
13233	// Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.)
13234	function initMouseDetection(disable) {
13235		if (!mouseDetectionEnabled && !disable) {
13236			// if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present
13237			// in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events)
13238			var firstTime = true,
13239				lastMove = null;
13240			$(document).bind({
13241				'mousemove.smartmenus_mouse': function(e) {
13242					var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() };
13243					if (lastMove) {
13244						var deltaX = Math.abs(lastMove.x - thisMove.x),
13245							deltaY = Math.abs(lastMove.y - thisMove.y);
13246	 					if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) {
13247							mouse = true;
13248							// if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes
13249							if (firstTime) {
13250								var $a = $(e.target).closest('a');
13251								if ($a.is('a')) {
13252									$.each(menuTrees, function() {
13253										if ($.contains(this.$root[0], $a[0])) {
13254											this.itemEnter({ currentTarget: $a[0] });
13255											return false;
13256										}
13257									});
13258								}
13259								firstTime = false;
13260							}
13261						}
13262					}
13263					lastMove = thisMove;
13264				},
13265				'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) {
13266					if (!/^(4|mouse|pen)$/.test(e.originalEvent.pointerType)) {
13267						mouse = false;
13268					}
13269				}
13270			});
13271			mouseDetectionEnabled = true;
13272		} else if (mouseDetectionEnabled && disable) {
13273			$(document).unbind('.smartmenus_mouse');
13274			mouseDetectionEnabled = false;
13275		}
13276	};
13277
13278	$.SmartMenus = function(elm, options) {
13279		this.$root = $(elm);
13280		this.opts = options;
13281		this.rootId = ''; // internal
13282		this.$subArrow = null;
13283		this.subMenus = []; // all sub menus in the tree (UL elms) in no particular order (only real - e.g. UL's in mega sub menus won't be counted)
13284		this.activatedItems = []; // stores last activated A's for each level
13285		this.visibleSubMenus = []; // stores visible sub menus UL's
13286		this.showTimeout = 0;
13287		this.hideTimeout = 0;
13288		this.scrollTimeout = 0;
13289		this.clickActivated = false;
13290		this.zIndexInc = 0;
13291		this.$firstLink = null; // we'll use these for some tests
13292		this.$firstSub = null; // at runtime so we'll cache them
13293		this.disabled = false;
13294		this.$disableOverlay = null;
13295		this.lastLevel = 0;
13296		this.init();
13297	};
13298
13299	$.extend($.SmartMenus, {
13300		hideAll: function() {
13301			$.each(menuTrees, function() {
13302				this.menuHideAll();
13303			});
13304		},
13305		destroy: function() {
13306			while (menuTrees.length) {
13307				menuTrees[0].destroy();
13308			}
13309			initMouseDetection(true);
13310		},
13311		prototype: {
13312			init: function(refresh) {
13313				var self = this;
13314
13315				if (!refresh) {
13316					menuTrees.push(this);
13317
13318					this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, '');
13319
13320					if (this.$root.hasClass('sm-rtl')) {
13321						this.opts.rightToLeftSubMenus = true;
13322					}
13323
13324					// init root (main menu)
13325					this.$root
13326						.data('smartmenus', this)
13327						.attr('data-smartmenus-id', this.rootId)
13328						.dataSM('level', 1)
13329						.bind({
13330							// 'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
13331							// 'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this)
13332							'mouseover.smartmenus': $.proxy(this.rootOver, this),
13333							'mouseout.smartmenus': $.proxy(this.rootOut, this)
13334						})
13335						.delegate('a, div.logo-container', {
13336							'mouseenter.smartmenus': $.proxy(this.itemEnter, this),
13337							'mouseleave.smartmenus': $.proxy(this.itemLeave, this),
13338							'mousedown.smartmenus': $.proxy(this.itemDown, this),
13339							'focus.smartmenus': $.proxy(this.itemFocus, this),
13340							'blur.smartmenus': $.proxy(this.itemBlur, this),
13341							'click.smartmenus': $.proxy(this.itemClick, this),
13342							'touchend.smartmenus': $.proxy(this.itemTouchEnd, this)
13343						});
13344
13345					var eNamespace = '.smartmenus' + this.rootId;
13346					// hide menus on tap or click outside the root UL
13347					if (this.opts.hideOnClick) {
13348							$(document).on('touchstart' + eNamespace, $.proxy(this.docTouchStart, this))
13349								.on('touchmove' + eNamespace, $.proxy(this.docTouchMove, this))
13350								.on('touchend' + eNamespace, $.proxy(this.docTouchEnd, this))
13351								// for Opera Mobile < 11.5, webOS browser, etc. we'll check click too
13352								.on('click' + eNamespace, $.proxy(this.docClick, this));
13353					}
13354					// hide sub menus on resize
13355					$(window).on('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
13356					var $vmenu = $('body.vmenu .vmenu-container');
13357					if ( ! $vmenu.length && UNCODE.wwidth > UNCODE.mediaQuery ) {
13358						$(window).on('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
13359					}
13360
13361					if (this.opts.subIndicators) {
13362						this.$subArrow = $('<span/>').addClass('sub-arrow');
13363						if (this.opts.subIndicatorsText) {
13364							this.$subArrow.html(this.opts.subIndicatorsText);
13365						}
13366					}
13367
13368					// make sure mouse detection is enabled
13369					initMouseDetection();
13370				}
13371
13372				// init sub menus
13373				this.$firstSub = this.$root.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').each(function() { self.menuInit($(this)); }).eq(0);
13374
13375				this.$firstLink = this.$root.find('a').eq(0);
13376
13377				// find current item
13378				if (this.opts.markCurrentItem) {
13379					var reDefaultDoc = /(index|default)\.[^#\?\/]*/i,
13380						reHash = /#.*/,
13381						locHref = window.location.href.replace(reDefaultDoc, ''),
13382						locHrefNoHash = locHref.replace(reHash, '');
13383					this.$root.find('a').each(function() {
13384						var href = this.href.replace(reDefaultDoc, ''),
13385							$this = $(this);
13386						if (href == locHref || href == locHrefNoHash) {
13387							$this.addClass('current');
13388							if (self.opts.markCurrentTree) {
13389								$this.parents('li').each(function() {
13390									var $this = $(this);
13391									if ($this.dataSM('sub')) {
13392										$this.children('a').addClass('current');
13393									}
13394								});
13395							}
13396						}
13397					});
13398				}
13399			},
13400			destroy: function() {
13401				this.menuHideAll();
13402				this.$root
13403					.removeData('smartmenus')
13404					.removeAttr('data-smartmenus-id')
13405					.removeDataSM('level')
13406					.unbind('.smartmenus')
13407					.undelegate('.smartmenus');
13408				var eNamespace = '.smartmenus' + this.rootId;
13409				$(document).unbind(eNamespace);
13410				$(window).unbind(eNamespace);
13411				if (this.opts.subIndicators) {
13412					this.$subArrow = null;
13413				}
13414				var self = this;
13415				$.each(this.subMenus, function() {
13416					if (this.hasClass('mega-menu')) {
13417						this.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').removeDataSM('in-mega');
13418					}
13419					if (this.dataSM('shown-before')) {
13420						if (IElt8) {
13421							this.children().css({ styleFloat: '', width: '' });
13422						}
13423						if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) {
13424							if (!IE6) {
13425								this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap');
13426							} else {
13427								this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', '');
13428							}
13429						}
13430						if (this.dataSM('scroll-arrows')) {
13431							this.dataSM('scroll-arrows').remove();
13432						}
13433						this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' });
13434					}
13435					if (self.opts.subIndicators) {
13436						this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove();
13437					}
13438					this.removeDataSM('shown-before')
13439						.removeDataSM('ie-shim')
13440						.removeDataSM('scroll-arrows')
13441						.removeDataSM('parent-a')
13442						.removeDataSM('level')
13443						.removeDataSM('beforefirstshowfired')
13444						.parent().removeDataSM('sub');
13445				});
13446				if (this.opts.markCurrentItem) {
13447					this.$root.find('a.current').removeClass('current');
13448				}
13449				this.$root = null;
13450				this.$firstLink = null;
13451				this.$firstSub = null;
13452				if (this.$disableOverlay) {
13453					this.$disableOverlay.remove();
13454					this.$disableOverlay = null;
13455				}
13456				menuTrees.splice($.inArray(this, menuTrees), 1);
13457			},
13458			disable: function(noOverlay) {
13459				if (!this.disabled) {
13460					this.menuHideAll();
13461					// display overlay over the menu to prevent interaction
13462					if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) {
13463						var pos = this.$root.offset();
13464						this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({
13465							position: 'absolute',
13466							top: pos.top,
13467							left: pos.left,
13468							width: this.$root.outerWidth(),
13469							height: this.$root.outerHeight(),
13470							zIndex: this.getStartZIndex() + 1,
13471							opacity: 0
13472						}).appendTo(document.body);
13473					}
13474					this.disabled = true;
13475				}
13476			},
13477			docClick: function(e) {
13478				// hide on any click outside the menu or on a menu link
13479				if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a:not([data-filter])')) {
13480					this.menuHideAll($(e.target));
13481				}
13482			},
13483			docTouchEnd: function(e) {
13484				if (!this.lastTouch) {
13485					return;
13486				}
13487				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))) {
13488					if (this.hideTimeout) {
13489						clearTimeout(this.hideTimeout);
13490						this.hideTimeout = 0;
13491					}
13492					// hide with a delay to prevent triggering accidental unwanted click on some page element
13493					var self = this;
13494					this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350);
13495				}
13496				this.lastTouch = null;
13497			},
13498			docTouchMove: function(e) {
13499				if (!this.lastTouch) {
13500					return;
13501				}
13502				var touchPoint = e.originalEvent.touches[0];
13503				this.lastTouch.x2 = touchPoint.pageX;
13504				this.lastTouch.y2 = touchPoint.pageY;
13505			},
13506			docTouchStart: function(e) {
13507				var touchPoint = e.originalEvent.touches[0];
13508				this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target };
13509			},
13510			enable: function() {
13511				if (this.disabled) {
13512					if (this.$disableOverlay) {
13513						this.$disableOverlay.remove();
13514						this.$disableOverlay = null;
13515					}
13516					this.disabled = false;
13517				}
13518			},
13519			getHeight: function($elm) {
13520				return this.getOffset($elm, true);
13521			},
13522			// returns precise width/height float values in IE9+, FF4+, recent WebKit
13523			// http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/
13524			getOffset: function($elm, height) {
13525				var old,
13526					$win = $(window),
13527					winW = $win.width();
13528				if ($elm.css('display') == 'none') {
13529					old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility };
13530					$elm.css({ position: 'absolute', visibility: 'hidden' }).show();
13531					if ( 
13532						($('body').hasClass('menu-mobile-off-canvas') && winW < 960 && $elm.closest('.main-menu-container').length)
13533						||
13534						(( $('body').hasClass('vmenu-offcanvas-overlay') || $('body').hasClass('vmenu') ) && winW >= 960 && $elm.closest('.main-menu-container').length && !$elm.closest('.menu-horizontal-inner').length)
13535					) {
13536						$elm.closest('li').addClass('smartmenu-open-item');
13537					}
13538				}
13539				var defaultView = $elm[0].ownerDocument.defaultView,
13540					compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null),
13541					val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']);
13542				if (val) {
13543					val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft'])
13544	 					+ parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight'])
13545	 					+ parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth'])
13546	 					+ parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']);
13547				} else {
13548					val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth;
13549				}
13550				if (old) {
13551					$elm.hide().css(old);
13552				}
13553				return val;
13554			},
13555			getWidth: function($elm) {
13556				return this.getOffset($elm);
13557			},
13558			getStartZIndex: function() {
13559				var zIndex = parseInt(this.$root.css('z-index'));
13560				return !isNaN(zIndex) ? zIndex : 1;
13561			},
13562			handleEvents: function() {
13563				return !this.disabled && this.isCSSOn();
13564			},
13565			handleItemEvents: function($a) {
13566				return this.handleEvents() && !this.isLinkInMegaMenu($a);
13567			},
13568			isCollapsible: function() {
13569				return this.$firstSub.css('position') == 'static';
13570			},
13571			isCSSOn: function() {
13572				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';
13573			},
13574			isFixed: function() {
13575				return this.$root.css('position') == 'fixed';
13576			},
13577			isLinkInMegaMenu: function($a) {
13578				return !$a.parent().parent().dataSM('level');
13579			},
13580			isTouchMode: function() {
13581				return !mouse || this.isCollapsible();
13582			},
13583			itemActivate: function($a, $show) {
13584				var $li = $a.parent(),
13585					$ul = $li.parent(),
13586					level = $ul.dataSM('level'),
13587					winh = $(window).height();
13588				// 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
13589				if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) {
13590					var self = this;
13591					$($ul.parentsUntil('[data-smartmenus-id]', 'ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').get().reverse()).add($ul).each(function() {
13592						self.itemActivate($(this).dataSM('parent-a'));
13593					});
13594				}
13595				// hide any visible deeper level sub menus
13596				if (this.visibleSubMenus.length > level) {
13597					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--) {
13598						this.lastLevel = level;
13599						if ( typeof $show === 'undefined' && this.isCollapsible() ) {
13600							this.menuHide(this.visibleSubMenus[i], $a);
13601							return;
13602						} else {
13603							this.menuHide(this.visibleSubMenus[i]);
13604						}
13605					}
13606				}
13607				// save new active item and sub menu for this level
13608				this.activatedItems[level - 1] = $a;
13609				this.visibleSubMenus[level - 1] = $ul;
13610				if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) {
13611					return;
13612				}
13613				// show the sub menu if this item has one
13614				var $sub = $li.dataSM('sub');
13615				if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) {
13616				// if ($sub && (this.isTouchMode() || (!this.opts.showOnClick))) {
13617					var aRect = $a[0].getBoundingClientRect();
13618					if ( (aRect.y < 0 || aRect.y > winh) && this.isCollapsible() && (this.lastLevel === this.activatedItems.length) ) {
13619						setTimeout(function(){
13620							var currentScroll = $a.closest('.main-menu-container').scrollTop();
13621							$a.closest('.main-menu-container').scrollTop(currentScroll + aRect.y);
13622						}, 1);
13623					}
13624					this.menuShow($sub);
13625				}
13626			},
13627			itemBlur: function(e) {
13628				var $a = $(e.currentTarget);
13629				if (!this.handleItemEvents($a)) {
13630					return;
13631				}
13632				this.$root.triggerHandler('blur.smapi', $a[0]);
13633			},
13634			itemClick: function(e) {
13635				var $a = $(e.currentTarget);
13636
13637				if (!this.handleItemEvents($a)) {
13638					return;
13639				}
13640				$a.removeDataSM('mousedown');
13641				if (this.$root.triggerHandler('click.smapi', $a[0]) === false) {
13642					return false;
13643				}
13644				var $sub = $a.parent().dataSM('sub');
13645				if (this.isTouchMode()) {
13646					// undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu
13647					if ($a.dataSM('href')) {
13648						$a.attr('href', $a.dataSM('href')).removeDataSM('href');
13649					}
13650					// if the sub is not visible
13651					if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
13652						// try to activate the item and show the sub
13653						this.itemActivate($a);
13654						// if "itemActivate" showed the sub, prevent the click so that the link is not loaded
13655						// 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
13656						if ($sub.is(':visible')) {
13657							return false;
13658						}
13659					}
13660				// } else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub && !$sub.is(':visible')) {
13661				} else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) {
13662					this.clickActivated = true;
13663					this.menuShow($sub);
13664					return false;
13665				}
13666				if ($a.hasClass('disabled')) {
13667					return false;
13668				}
13669				if (this.$root.triggerHandler('select.smapi', $a[0]) === false) {
13670					return false;
13671				}
13672			},
13673			itemDown: function(e) {
13674				var $a = $(e.currentTarget);
13675				if (!this.handleItemEvents($a)) {
13676					return;
13677				}
13678				$a.dataSM('mousedown', true);
13679			},
13680			itemEnter: function(e) {
13681				// if ( this.opts.showOnClick ) {
13682				// 	return
13683				// }
13684				var $a = $(e.currentTarget);
13685				if (!this.handleItemEvents($a)) {
13686					return;
13687				}
13688				if (!this.isTouchMode()) {
13689					if (this.showTimeout) {
13690						clearTimeout(this.showTimeout);
13691						this.showTimeout = 0;
13692					}
13693					var self = this;
13694					this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout);
13695				}
13696				this.$root.triggerHandler('mouseenter.smapi', $a[0]);
13697			},
13698			itemFocus: function(e) {
13699				var $a = $(e.currentTarget);
13700				if (!this.handleItemEvents($a)) {
13701					return;
13702				}
13703				// 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
13704				if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) {
13705					this.itemActivate($a);
13706				}
13707				this.$root.triggerHandler('focus.smapi', $a[0]);
13708			},
13709			itemLeave: function(e) {
13710				// if ( this.opts.showOnClick ) {
13711				// 	return
13712				// }
13713				var $a = $(e.currentTarget);
13714				if (!this.handleItemEvents($a)) {
13715					return;
13716				}
13717				if (!this.isTouchMode()) {
13718					if ($a[0].blur) {
13719						$a[0].blur();
13720					}
13721					if (this.showTimeout) {
13722						clearTimeout(this.showTimeout);
13723						this.showTimeout = 0;
13724					}
13725				}
13726				$a.removeDataSM('mousedown');
13727				this.$root.triggerHandler('mouseleave.smapi', $a[0]);
13728			},
13729			itemTouchEnd: function(e) {
13730				var $a = $(e.currentTarget);
13731				if (!this.handleItemEvents($a)) {
13732					return;
13733				}
13734				// prevent the address bar on iPhone from sliding down when expanding a sub menu
13735				var $sub = $a.parent().dataSM('sub');
13736				if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
13737					$a.dataSM('href', $a.attr('href'));
13738					$a.attr('href', '#');
13739				}
13740			},
13741			menuFixLayout: function($ul) {
13742				// fixes a menu that is being shown for the first time
13743				if (!$ul.dataSM('shown-before')) {
13744					$ul.hide().dataSM('shown-before', true);
13745					// fix the layout of the items in IE<8
13746					if (IElt8) {
13747						$ul.children().css({ styleFloat: 'left', width: '100%' });
13748					}
13749				}
13750			},
13751			menuHide: function($sub, $show) {
13752				if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) {
13753					return;
13754				}
13755				$sub.stop(true, true);
13756				if ($sub.is(':visible')) {
13757					var self = this;
13758					var complete = function() {
13759						// unset z-index
13760						if (IElt9) {
13761							$sub.parent().css('z-index', '');
13762						} else {
13763							$sub.css('z-index', '');
13764						}
13765						if ( typeof $show !== 'undefined' ) {
13766							self.itemActivate($show, true)
13767						}
13768					};
13769					// if sub is collapsible (mobile view)
13770					if (this.isCollapsible()) {
13771						if (this.opts.collapsibleHideFunction) {
13772							this.opts.collapsibleHideFunction.call(this, $sub, complete);
13773						} else {
13774							$sub.hide(this.opts.collapsibleHideDuration, complete);
13775						}
13776					} else {
13777						if (this.opts.hideFunction) {
13778							this.opts.hideFunction.call(this, $sub, complete);
13779						} else {
13780							$sub.hide(this.opts.hideDuration, complete);
13781						}
13782					}
13783					// remove IE iframe shim
13784					if ($sub.dataSM('ie-shim')) {
13785						$sub.dataSM('ie-shim').remove();
13786					}
13787					// deactivate scrolling if it is activated for this sub
13788					if ($sub.dataSM('scroll')) {
13789						$sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide();
13790					}
13791					// unhighlight parent item
13792					$sub.dataSM('parent-a').removeClass('highlighted');
13793					var level = $sub.dataSM('level');
13794					this.activatedItems.splice(level - 1, 1);
13795					this.visibleSubMenus.splice(level - 1, 1);
13796					this.$root.triggerHandler('hide.smapi', $sub[0]);
13797				}
13798			},
13799			menuHideAll: function($item) {
13800				if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return;
13801				var $win = $(window),
13802					winW = $win.width();
13803				if (this.showTimeout) {
13804					clearTimeout(this.showTimeout);
13805					this.showTimeout = 0;
13806				}
13807				// hide all subs
13808				for (var i = this.visibleSubMenus.length - 1; i > 0; i--) {
13809					if ( this.visibleSubMenus[i].closest('.smartmenu-open-item').length ) {
13810						if ( $item != undefined && $item.closest('.smartmenu-open-item').length ) {
13811							this.menuHide(this.visibleSubMenus[i]);
13812							$(this.visibleSubMenus[i]).closest('.smartmenu-open-item').removeClass('smartmenu-open-item');
13813						} else {
13814							return;
13815						}
13816					} else {
13817						//if ( !this.visibleSubMenus[i].closest('.menu-accordion').length ) {
13818							this.menuHide(this.visibleSubMenus[i]);
13819						//}
13820					}
13821				}
13822				// hide root if it's popup
13823				if (this.opts.isPopup) {
13824					this.$root.stop(true, true);
13825					if (this.$root.is(':visible')) {
13826						if (this.opts.hideFunction) {
13827							this.opts.hideFunction.call(this, this.$root);
13828						} else {
13829							this.$root.hide(this.opts.hideDuration);
13830						}
13831						// remove IE iframe shim
13832						if (this.$root.dataSM('ie-shim')) {
13833							this.$root.dataSM('ie-shim').remove();
13834						}
13835					}
13836				}
13837				this.activatedItems = [];
13838				this.visibleSubMenus = [];
13839				this.clickActivated = false;
13840				// reset z-index increment
13841				this.zIndexInc = 0;
13842			},
13843			menuIframeShim: function($ul) {
13844				// create iframe shim for the menu
13845				if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) {
13846					$ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 })
13847						.css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' })
13848					);
13849				}
13850			},
13851			menuInit: function($ul) {
13852				if (!$ul.dataSM('in-mega')) {
13853					this.subMenus.push($ul);
13854					// mark UL's in mega drop downs (if any) so we can neglect them
13855					if ($ul.hasClass('mega-menu')) {
13856						$ul.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').dataSM('in-mega', true);
13857					}
13858					// get level (much faster than, for example, using parentsUntil)
13859					var level = 2,
13860						par = $ul[0];
13861					while (par != null && par.parentNode != null && ( par = par.parentNode.parentNode) != this.$root[0]) {
13862						level++;
13863					}
13864					// cache stuff
13865					$ul.dataSM('parent-a', $ul.prevAll('a').eq(-1))
13866						.dataSM('level', level)
13867						.parent().dataSM('sub', $ul);
13868					// add sub indicator to parent item
13869					if (this.opts.subIndicators) {
13870						$ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone());
13871					}
13872				}
13873				if ( $('.vc_row[data-parent].has-bg', $ul).length && !$('.vc_row[data-parent]:not(.has-bg)', $ul).length ) {
13874					$ul.addClass('has-bg-items');
13875				}
13876			},
13877			menuPosition: function($sub) {
13878				var fixIE = $('html.ie').length;
13879				// if (fixIE) {
13880				// 	var $rowParent = $($sub).closest('.main-menu-container');
13881				// 	$rowParent.height($rowParent.height());
13882				// }
13883				var $a = $sub.dataSM('parent-a'),
13884					$li = $sub.parent(),
13885					$ul = $sub.parent().parent(),
13886					// $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'),
13887					$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'),
13888					level = $sub.dataSM('level'),
13889					subW = this.getWidth($sub),
13890					subH = this.getHeight($sub),
13891					itemOffset = $a.offset(),
13892					itemX = itemOffset.left,
13893					itemY = itemOffset.top,
13894					itemW = this.getWidth($a),
13895					itemH = this.getHeight($a),
13896					$win = $(window),
13897					winX = $win.scrollLeft(),
13898					winY = $win.scrollTop(),
13899					winW = $win.width(),
13900					winH = $win.height(),
13901					containerW = $container.width(),
13902					containerOffsetX = containerW + ((winW - containerW) / 2),
13903					horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'),
13904					subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX,
13905					subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY,
13906					x, y, leftPos;
13907
13908				if (horizontalParent) {
13909					x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX;
13910					y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY;
13911				} else {
13912					x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : subW - subOffsetX;
13913					y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY;
13914				}
13915				if (this.opts.keepInViewport && !this.isCollapsible()) {
13916					if (this.isFixed()) {
13917						itemX -= winX;
13918						itemY -= winY;
13919						winX = winY = 0;
13920					}
13921					var absX = itemX + x,
13922						absY = itemY + y;
13923					if (this.opts.rightToLeftSubMenus && absX < winX) {
13924						x = horizontalParent ? winX - absX + x : itemW - subOffsetX;
13925					} else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) {
13926						x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW;
13927					}
13928					if (!horizontalParent) {
13929						if (subH < winH && absY + subH > winY + winH) {
13930							y += winY + winH - subH - absY;
13931						} else if (subH >= winH || absY < winY) {
13932							y += winY - absY;
13933						}
13934					}
13935					// do we need scrolling?
13936					// 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH"
13937					if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) {
13938						var self = this;
13939						if (!$sub.dataSM('scroll-arrows')) {
13940							$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]])
13941								.bind({
13942									mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); },
13943									mouseleave: function(e) {
13944										self.menuScrollStop($sub);
13945										self.menuScrollOut($sub, e);
13946									},
13947									'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); }
13948								})
13949								.insertAfter($sub)
13950							);
13951						}
13952						// bind events to show/hide arrows on hover and save scrolling data for this sub
13953						var vportY = winY - (itemY + itemH);
13954						$sub.dataSM('scroll', {
13955								vportY: vportY,
13956								subH: subH,
13957								winH: winH,
13958								step: 1
13959							})
13960							.bind({
13961								'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); },
13962								'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); },
13963								'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); }
13964							})
13965							.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
13965StartZIndex() + this.zIndexInc })
13966							.eq(0).css('margin-top', vportY).end()
13967							.eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end()
13968							.eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show();
13969					}
13970				}
13971				if ( !$sub.closest('.menu-accordion').length ) {
13972					var rightPos = 'auto';
13973					if ( $sub.closest('.grid-filters').length ) {
13974						if ( $sub.closest('.text-right').length ) {
13975							leftPos = '0px';
13976							rightPos = 'auto';
13977						} else {
13978							leftPos = 'auto';
13979							rightPos = '0px';
13980						}
13981						x = 0;
13982					} else {
13983						if ( $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)').length && $sub.closest('.row-menu').is('.limit-width') && level === 2) {
13984							var parentContW = $sub.closest('.menu-container').width();
13985							$sub.css({ width: parentContW});
13986							$sub.addClass('need-focus');
13987							leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.menu-container').offset().left));
13988							x = 0;
13989						} else if ( $sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)').length ) {
13990							$sub.css({ width: containerW});
13991							$sub.addClass('need-focus');
13992							leftPos = -1 * (parseFloat($sub.closest('ul.menu-smart').offset().left) - parseFloat($sub.closest('.row-menu').offset().left));
13993							if ( ! $('body').hasClass('megamenu-side-to-side') ) {
13994								leftPos += parseFloat($sub.closest('.row-menu-inner').css('paddingLeft'));
13995							}
13996							x = 0;
13997						} else {
13998							if ( $sub.is('.block-wrapper-parent') && !$sub.find('.col-custom-width').length && !$sub.find('.row-parent-limit').length && level === 2 ) {
13999								leftPos = ( $li.position().left - ( (UNCODE.wwidth - $sub.outerWidth() )/2) ) + 'px';
14000							} else {
14001								leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').css('paddingLeft')) : $li.position().left ) + 'px';
14002							}
14003							x = (level > 2 && x >= 0) ? x + 1 : x - 1;
14004						}
14005					}
14006				}
14007
14008				// $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) });
14009				$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) });
14010				// IE iframe shim
14011				this.menuIframeShim($sub);
14012				if ($sub.dataSM('ie-shim')) {
14013					$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) });
14014				}
14015			},
14016			menuScroll: function($sub, up, wheel) {
14017				var y = parseFloat($sub.css('margin-top')),
14018					scroll = $sub.dataSM('scroll'),
14019					navH = $('.navbar-main').outerHeight(),
14020					end = scroll.vportY + (up ? navH + 54 : scroll.winH - scroll.subH),
14021					step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step);
14022				$sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end);
14023				y = parseFloat($sub.css('margin-top'));
14024				// show opposite arrow if appropriate
14025				if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) {
14026					$sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show();
14027				}
14028				// accelerate when not using mousewheel to scroll
14029				if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) {
14030					$sub.dataSM('scroll').step += 0.5;
14031				}
14032				// "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used
14033				if (Math.abs(y - end) < 1) {
14034					$sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide();
14035					$sub.dataSM('scroll').step = 1;
14036				} else if (!wheel) {
14037					var self = this;
14038					this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval);
14039				}
14040			},
14041			menuScrollMousewheel: function($sub, e) {
14042				var $closestSub = $(e.target).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
14043				while ($closestSub.dataSM('in-mega')) {
14044					$closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
14045				}
14046				if ($closestSub[0] == $sub[0]) {
14047					var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0;
14048					if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) {
14049						this.menuScroll($sub, up, true);
14050					}
14051				}
14052				if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) {
14053					e.preventDefault();
14054				}
14055			},
14056			menuScrollOut: function($sub, e) {
14057				var reClass = /^scroll-(up|down)/,
14058					$closestSub = $(e.relatedTarget).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
14059				while ($closestSub.dataSM('in-mega')) {
14060					$closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
14061				}
14062				if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) {
14063					$sub.dataSM('scroll-arrows').css('visibility', 'hidden');
14064				}
14065			},
14066			menuScrollOver: function($sub, e) {
14067				var reClass = /^scroll-(up|down)/,
14068					$closestSub = $(e.target).closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
14069				while ($closestSub.dataSM('in-mega')) {
14070					$closestSub = $closestSub.parent().closest('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)');
14071				}
14072				if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) {
14073					$sub.dataSM('scroll-arrows').css('visibility', 'visible');
14074				}
14075			},
14076			menuScrollStop: function($sub) {
14077				if (this.scrollTimeout) {
14078					clearTimeout(this.scrollTimeout);
14079					this.scrollTimeout = 0;
14080					$sub.dataSM('scroll').step = 1;
14081				}
14082			},
14083			menuShow: function($sub) {
14084				if (!$sub.dataSM('beforefirstshowfired')) {
14085					$sub.dataSM('beforefirstshowfired', true);
14086					if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) {
14087						return;
14088					}
14089				}
14090				if ( this.isCollapsible() ) {
14091					this.$root.triggerHandler('beforecollapse.smapi', $sub[0]);
14092				}
14093				if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) {
14094					return;
14095				}
14096				this.menuFixLayout($sub);
14097				$sub.stop(true, true);
14098				if (!$sub.is(':visible')) {
14099					$sub.css({
14100						'visibility': 'visible',
14101						'pointer-events': 'auto',
14102					});
14103					// set z-index - for IE < 9 set it to the parent LI
14104					var zIndex = this.getStartZIndex() + (++this.zIndexInc);
14105					if (IElt9) {
14106						$sub.parent().css('z-index', zIndex);
14107					} else {
14108						$sub.css('z-index', zIndex);
14109					}
14110					// highlight parent item
14111					if (this.opts.keepHighlighted || this.isCollapsible()) {
14112						if ($sub.dataSM('parent-a').attr('data-type') != 'title')
14113							$sub.dataSM('parent-a').addClass('highlighted');
14114					}
14115					// min/max-width fix - no way to rely purely on CSS as all UL's are nested
14116					if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) {
14117						if (!IElt8) {
14118							$sub.css({ width: ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
14119							if (this.opts.subMenusMinWidth) {
14120							 	$sub.css('min-width', this.opts.subMenusMinWidth);
14121							}
14122							if (this.opts.subMenusMaxWidth) {
14123							 	var noMaxWidth = this.getWidth($sub);
14124							 	if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) {
14125								 	$sub.css('max-width', this.opts.subMenusMaxWidth);
14126							 	}
14127								if (noMaxWidth > this.getWidth($sub)) {
14128									$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
14129								}
14130							}
14131						// IE6,7
14132 						} else {
14133							$sub.children().css('styleFloat', 'none');
14134							if (IE6) {
14135								$sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1)
14136									.children().children('a').css('white-space', 'nowrap');
14137							} else { // IE7
14138								$sub.css({ width: ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
14139								if (this.opts.subMenusMinWidth) {
14140									$sub.css('min-width', this.opts.subMenusMinWidth);
14141								}
14142							}
14143							if (this.opts.subMenusMaxWidth) {
14144								var noMaxWidth = $sub.width();
14145								if (IE6) {
14146							 		var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width();
14147									if (noMaxWidth > maxWidth) {
14148										$sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', '');
14149									} else {
14150										$sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' });
14151									}
14152								} else { // IE7
14153								 	if ( ! $sub.hasClass('mega-menu-inner') && ! $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)') ) {
14154									 	$sub.css('max-width', this.opts.subMenusMaxWidth);
14155								 	}
14156									if (noMaxWidth > $sub.width()) {
14157										$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
14158									} else {
14159										$sub.width(noMaxWidth);
14160									}
14161								}
14162							} else {
14163							 	$sub.width($sub.width());
14164							}
14165							$sub.children().css('styleFloat', 'left');
14166						}
14167					}
14168					if ( ( ( ($sub.hasClass('mega-menu-inner') || $sub.find('[data-parent="true"]:not(.limit-width):not(.row-parent-limit)')) && $('body').hasClass('scrollable-megamenu') ) ) && UNCODE.wwidth > UNCODE.mediaQuery ) {
14169						var $nav = $('.navbar-main'),
14170							navH = 0,
14171							navTop = 0,
14172							$vmenu = $('body.vmenu .vmenu-container, body.menu-overlay .vmenu-container, body.menu-offcanvas .vmenu-container');
14173						if ( $nav.length && typeof $nav[0] !== 'undefined' ) {
14174							var navRect = $nav[0].getBoundingClientRect();
14175							navH = navRect.height;
14176							navTop = navRect.top;
14177						}
14178						if ( ! $vmenu.length ) {
14179							$sub.css({ maxHeight: UNCODE.wheight - navH });
14180							if ( $('.megamenu-block-wrapper', $sub).length ) {
14181								$sub.find('> li').addClass('has-scroll').css({ maxHeight: UNCODE.wheight - navH });
14182							}
14183						}
14184					}
14185					this.menuPosition($sub);
14186					// insert IE iframe shim
14187					if ($sub.dataSM('ie-shim')) {
14188						$sub.dataSM('ie-shim').insertBefore($sub);
14189					}
14190					var complete = function() {
14191						// fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used
14192						$sub.css('overflow', '');
14193					};
14194					// if sub is collapsible (mobile view)
14195					if (this.isCollapsible()) {
14196						if (this.opts.collapsibleShowFunction) {
14197							this.opts.collapsibleShowFunction.call(this, $sub, complete);
14198						} else {
14199							$sub.show(this.opts.collapsibleShowDuration, complete);
14200						}
14201					} else {
14202						if (this.opts.showFunction) {
14203							this.opts.showFunction.call(this, $sub, complete);
14204						} else {
14205							$sub.show(this.opts.showDuration, complete);
14206						}
14207					}
14208					// save new sub menu for this level
14209					this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub;
14210					this.$root.triggerHandler('show.smapi', $sub[0]);
14211				}
14212			},
14213			popupHide: function(noHideTimeout) {
14214				if (this.hideTimeout) {
14215					clearTimeout(this.hideTimeout);
14216					this.hideTimeout = 0;
14217				}
14218				var self = this;
14219				this.hideTimeout = setTimeout(function() {
14220					self.menuHideAll();
14221				}, noHideTimeout ? 1 : this.opts.hideTimeout);
14222			},
14223			popupShow: function(left, top) {
14224				if (!this.opts.isPopup) {
14225					alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.');
14226					return;
14227				}
14228				if (this.hideTimeout) {
14229					clearTimeout(this.hideTimeout);
14230					this.hideTimeout = 0;
14231				}
14232				this.menuFixLayout(this.$root);
14233				this.$root.stop(true, true);
14234				if (!this.$root.is(':visible')) {
14235					this.$root.css({ left: left, top: top });
14236					// IE iframe shim
14237					this.menuIframeShim(this.$root);
14238					if (this.$root.dataSM('ie-shim')) {
14239						this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
14239: left, top: top }).insertBefore(this.$root);
14240					}
14241					// show menu
14242					if (this.opts.showFunction) {
14243						this.opts.showFunction.call(this, this.$root);
14244					} else {
14245						this.$root.show(this.opts.showDuration);
14246					}
14247					this.visibleSubMenus[0] = this.$root;
14248				}
14249			},
14250			refresh: function() {
14251				this.menuHideAll();
14252				this.$root.find('ul:not(.nav-tabs):not(.unmenu-block):not(.unmenu-block *)').each(function() {
14253						var $this = $(this);
14254						if ($this.dataSM('scroll-arrows')) {
14255							$this.dataSM('scroll-arrows').remove();
14256						}
14257					})
14258					.removeDataSM('in-mega')
14259					.removeDataSM('shown-before')
14260					.removeDataSM('ie-shim')
14261					.removeDataSM('scroll-arrows')
14262					.removeDataSM('parent-a')
14263					.removeDataSM('level')
14264					.removeDataSM('beforefirstshowfired');
14265				this.$root.find('a.has-submenu').removeClass('has-submenu')
14266					.parent().removeDataSM('sub');
14267				if (this.opts.subIndicators) {
14268					this.$root.find('span.sub-arrow').remove();
14269				}
14270				if (this.opts.markCurrentItem) {
14271					this.$root.find('a.current').removeClass('current');
14272				}
14273				this.subMenus = [];
14274				this.init(true);
14275			},
14276			rootOut: function(e) {
14277				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
14278					return;
14279				}
14280				if (this.hideTimeout) {
14281					clearTimeout(this.hideTimeout);
14282					this.hideTimeout = 0;
14283				}
14284				if (!this.opts.showOnClick || !this.opts.hideOnClick) {
14285					var self = this;
14286					this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout);
14287				}
14288			},
14289			rootOver: function(e) {
14290				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
14291					return;
14292				}
14293				if (this.hideTimeout) {
14294					clearTimeout(this.hideTimeout);
14295					this.hideTimeout = 0;
14296				}
14297			},
14298			winResize: function(e) {
14299				if (!this.handleEvents()) {
14300					// we still need to resize the disable overlay if it's visible
14301					if (this.$disableOverlay) {
14302						var pos = this.$root.offset();
14303	 					this.$disableOverlay.css({
14304							top: pos.top,
14305							left: pos.left,
14306							width: this.$root.outerWidth(),
14307							height: this.$root.outerHeight()
14308						});
14309					}
14310					return;
14311				}
14312				// hide sub menus on resize - on mobile do it only on orientation change
14313				if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) {
14314					if (this.activatedItems.length) {
14315						this.activatedItems[this.activatedItems.length - 1][0].blur();
14316					}
14317					this.menuHideAll();
14318				}
14319			}
14320		}
14321	});
14322
14323	$.fn.dataSM = function(key, val) {
14324		if (val) {
14325			return this.data(key + '_smartmenus', val);
14326		}
14327		return this.data(key + '_smartmenus');
14328	}
14329
14330	$.fn.removeDataSM = function(key) {
14331		return this.removeData(key + '_smartmenus');
14332	}
14333
14334	$.fn.smartmenus = function(options) {
14335		if (typeof options == 'string') {
14336			var args = arguments,
14337				method = options;
14338			Array.prototype.shift.call(args);
14339			return this.each(function() {
14340				var smartmenus = $(this).data('smartmenus');
14341				if (smartmenus && smartmenus[method]) {
14342					smartmenus[method].apply(smartmenus, args);
14343				}
14344			});
14345		}
14346		var opts = $.extend({}, $.fn.smartmenus.defaults, options);
14347		return this.each(function() {
14348			new $.SmartMenus(this, opts);
14349		});
14350	}
14351
14352	// default settings
14353	$.fn.smartmenus.defaults = {
14354		isPopup:		false,		// is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar
14355		mainMenuSubOffsetX:	0,		// pixels offset from default position
14356		mainMenuSubOffsetY:	0,		// pixels offset from default position
14357		subMenusSubOffsetX:	0,		// pixels offset from default position
14358		subMenusSubOffsetY:	0,		// pixels offset from default position
14359		subMenusMinWidth:	false, //'10em',		// min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
14360		subMenusMaxWidth:	false, //'20em',		// max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
14361		subIndicators: 		true,		// create sub menu indicators - creates a SPAN and inserts it in the A
14362		subIndicatorsPos: 	'prepend',	// position of the SPAN relative to the menu item content ('prepend', 'append')
14363		subIndicatorsText:	'+',		// [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too)
14364		scrollStep: 		30,		// pixels step when scrolling long sub menus that do not fit in the viewport height
14365		scrollInterval:		30,		// interval between each scrolling step
14366		scrollAccelerate:	true,		// accelerate scrolling or use a fixed step
14367		showTimeout:		250,		// timeout before showing the sub menus
14368		hideTimeout:		500,		// timeout before hiding the sub menus
14369		showDuration:		0,		// duration for show animation - set to 0 for no animation - matters only if showFunction:null
14370		showFunction:		null,		// custom function to use when showing a sub menu (the default is the jQuery 'show')
14371							// don't forget to call complete() at the end of whatever you do
14372							// e.g.: function($ul, complete) { $ul.fadeIn(250, complete); }
14373		hideDuration:		0,		// duration for hide animation - set to 0 for no animation - matters only if hideFunction:null
14374		hideFunction:		function($ul, complete) { $ul.fadeOut(200, complete); },	// custom function to use when hiding a sub menu (the default is the jQuery 'hide')
14375							// don't forget to call complete() at the end of whatever you do
14376							// e.g.: function($ul, complete) { $ul.fadeOut(250, complete); }
14377		collapsibleShowDuration:0,		// duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null
14378		collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); },	// custom function to use when showing a collapsible sub menu
14379							// (i.e. when mobile styles are used to make the sub menus collapsible)
14380		collapsibleHideDuration:0,		// duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null
14381		collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); },	// custom function to use when hiding a collapsible sub menu
14382							// (i.e. when mobile styles are used to make the sub menus collapsible)
14383		showOnClick:		false,		// show the first-level sub menus onclick instead of onmouseover (matters only for mouse input)
14384		hideOnClick:		true,		// hide the sub menus on click/tap anywhere on the page
14385		keepInViewport:		true,		// reposition the sub menus if needed to make sure they always appear inside the viewport
14386		keepHighlighted:	true,		// keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's)
14387		markCurrentItem:	false,		// automatically add the 'current' class to the A element of the item linking to the current URL
14388		markCurrentTree:	true,		// add the 'current' class also to the A elements of all ancestor items of the current item
14389		rightToLeftSubMenus:	false,		// right to left display of the sub menus (check the CSS for the sub indicators' position)
14390		bottomToTopSubMenus:	false,		// bottom to top display of the sub menus
14391		overlapControlsInIE:	true		// make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.)
14392	};
14393
14394})(jQuery);
14395/*
14396 * jQuery Easing v1.4.1 - http://gsgd.co.uk/sandbox/jquery/easing/
14397 * Open source under the BSD License.
14398 * Copyright © 2008 George McGinley Smith
14399 * All rights reserved.
14400 * https://raw.github.com/gdsmith/jquery.easing/master/LICENSE
14401*/
14402
14403/* globals jQuery, define, module, require */
14404(function (factory) {
14405	if (typeof define === "function" && define.amd) {
14406		define(['jquery'], function ($) {
14407			return factory($);
14408		});
14409	} else if (typeof module === "object" && typeof module.exports === "object") {
14410		module.exports = factory(require('jquery'));
14411	} else {
14412		factory(jQuery);
14413	}
14414})(function($){
14415
14416	// Preserve the original jQuery "swing" easing as "jswing"
14417	if (typeof $.easing !== 'undefined') {
14418		$.easing['jswing'] = $.easing['swing'];
14419	}
14420
14421	var pow = Math.pow,
14422		sqrt = Math.sqrt,
14423		sin = Math.sin,
14424		cos = Math.cos,
14425		PI = Math.PI,
14426		c1 = 1.70158,
14427		c2 = c1 * 1.525,
14428		c3 = c1 + 1,
14429		c4 = ( 2 * PI ) / 3,
14430		c5 = ( 2 * PI ) / 4.5;
14431
14432	// x is the fraction of animation progress, in the range 0..1
14433	function bounceOut(x) {
14434		var n1 = 7.5625,
14435			d1 = 2.75;
14436		if ( x < 1/d1 ) {
14437			return n1*x*x;
14438		} else if ( x < 2/d1 ) {
14439			return n1*(x-=(1.5/d1))*x + .75;
14440		} else if ( x < 2.5/d1 ) {
14441			return n1*(x-=(2.25/d1))*x + .9375;
14442		} else {
14443			return n1*(x-=(2.625/d1))*x + .984375;
14444		}
14445	}
14446
14447	$.extend( $.easing, {
14448		def: 'easeOutQuad',
14449		swing: function (x) {
14450			return $.easing[$.easing.def](x);
14451		},
14452		easeInQuad: function (x) {
14453			return x * x;
14454		},
14455		easeOutQuad: function (x) {
14456			return 1 - ( 1 - x ) * ( 1 - x );
14457		},
14458		easeInOutQuad: function (x) {
14459			return x < 0.5 ?
14460				2 * x * x :
14461				1 - pow( -2 * x + 2, 2 ) / 2;
14462		},
14463		easeInCubic: function (x) {
14464			return x * x * x;
14465		},
14466		easeOutCubic: function (x) {
14467			return 1 - pow( 1 - x, 3 );
14468		},
14469		easeInOutCubic: function (x) {
14470			return x < 0.5 ?
14471				4 * x * x * x :
14472				1 - pow( -2 * x + 2, 3 ) / 2;
14473		},
14474		easeInQuart: function (x) {
14475			return x * x * x * x;
14476		},
14477		easeOutQuart: function (x) {
14478			return 1 - pow( 1 - x, 4 );
14479		},
14480		easeInOutQuart: function (x) {
14481			return x < 0.5 ?
14482				8 * x * x * x * x :
14483				1 - pow( -2 * x + 2, 4 ) / 2;
14484		},
14485		easeInQuint: function (x) {
14486			return x * x * x * x * x;
14487		},
14488		easeOutQuint: function (x) {
14489			return 1 - pow( 1 - x, 5 );
14490		},
14491		easeInOutQuint: function (x) {
14492			return x < 0.5 ?
14493				16 * x * x * x * x * x :
14494				1 - pow( -2 * x + 2, 5 ) / 2;
14495		},
14496		easeInSine: function (x) {
14497			return 1 - cos( x * PI/2 );
14498		},
14499		easeOutSine: function (x) {
14500			return sin( x * PI/2 );
14501		},
14502		easeInOutSine: function (x) {
14503			return -( cos( PI * x ) - 1 ) / 2;
14504		},
14505		easeInExpo: function (x) {
14506			return x === 0 ? 0 : pow( 2, 10 * x - 10 );
14507		},
14508		easeOutExpo: function (x) {
14509			return x === 1 ? 1 : 1 - pow( 2, -10 * x );
14510		},
14511		easeInOutExpo: function (x) {
14512			return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ?
14513				pow( 2, 20 * x - 10 ) / 2 :
14514				( 2 - pow( 2, -20 * x + 10 ) ) / 2;
14515		},
14516		easeInCirc: function (x) {
14517			return 1 - sqrt( 1 - pow( x, 2 ) );
14518		},
14519		easeOutCirc: function (x) {
14520			return sqrt( 1 - pow( x - 1, 2 ) );
14521		},
14522		easeInOutCirc: function (x) {
14523			return x < 0.5 ?
14524				( 1 - sqrt( 1 - pow( 2 * x, 2 ) ) ) / 2 :
14525				( sqrt( 1 - pow( -2 * x + 2, 2 ) ) + 1 ) / 2;
14526		},
14527		easeInElastic: function (x) {
14528			return x === 0 ? 0 : x === 1 ? 1 :
14529				-pow( 2, 10 * x - 10 ) * sin( ( x * 10 - 10.75 ) * c4 );
14530		},
14531		easeOutElastic: function (x) {
14532			return x === 0 ? 0 : x === 1 ? 1 :
14533				pow( 2, -10 * x ) * sin( ( x * 10 - 0.75 ) * c4 ) + 1;
14534		},
14535		easeInOutElastic: function (x) {
14536			return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ?
14537				-( pow( 2, 20 * x - 10 ) * sin( ( 20 * x - 11.125 ) * c5 )) / 2 :
14538				pow( 2, -20 * x + 10 ) * sin( ( 20 * x - 11.125 ) * c5 ) / 2 + 1;
14539		},
14540		easeInBack: function (x) {
14541			return c3 * x * x * x - c1 * x * x;
14542		},
14543		easeOutBack: function (x) {
14544			return 1 + c3 * pow( x - 1, 3 ) + c1 * pow( x - 1, 2 );
14545		},
14546		easeInOutBack: function (x) {
14547			return x < 0.5 ?
14548				( pow( 2 * x, 2 ) * ( ( c2 + 1 ) * 2 * x - c2 ) ) / 2 :
14549				( pow( 2 * x - 2, 2 ) *( ( c2 + 1 ) * ( x * 2 - 2 ) + c2 ) + 2 ) / 2;
14550		},
14551		easeInBounce: function (x) {
14552			return 1 - bounceOut( 1 - x );
14553		},
14554		easeOutBounce: bounceOut,
14555		easeInOutBounce: function (x) {
14556			return x < 0.5 ?
14557				( 1 - bounceOut( 1 - 2 * x ) ) / 2 :
14558				( 1 + bounceOut( 2 * x - 1 ) ) / 2;
14559		}
14560	});
14561	return $;
14562});
14563
14564/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
14565 * Licensed under the MIT License (LICENSE.txt).
14566 *
14567 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
14568 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
14569 * Thanks to: Seamus Leahy for adding deltaX and deltaY
14570 *
14571 * Version: 3.0.6
14572 *
14573 * Requires: 1.2.2+
14574 */
14575(function($) {
14576    var types = ['DOMMouseScroll', 'mousewheel'];
14577    if ($.event.fixHooks) {
14578        for (var i = types.length; i;) {
14579            $.event.fixHooks[types[--i]] = $.event.mouseHooks;
14580        }
14581    }
14582    $.event.special.mousewheel = {
14583        setup: function() {
14584            if (this.addEventListener) {
14585                for (var i = types.length; i;) {
14586                    this.addEventListener(types[--i], handler, false);
14587                }
14588            } else {
14589                this.onmousewheel = handler;
14590            }
14591        },
14592        teardown: function() {
14593            if (this.removeEventListener) {
14594                for (var i = types.length; i;) {
14595                    this.removeEventListener(types[--i], handler, false);
14596                }
14597            } else {
14598                this.onmousewheel = null;
14599            }
14600        }
14601    };
14602    $.fn.extend({
14603        mousewheel: function(fn) {
14604            return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
14605        },
14606        unmousewheel: function(fn) {
14607            return this.unbind("mousewheel", fn);
14608        }
14609    });
14610
14611    function handler(event) {
14612        var orgEvent = event || window.event,
14613            args = [].slice.call(arguments, 1),
14614            delta = 0,
14615            returnValue = true,
14616            deltaX = 0,
14617            deltaY = 0;
14618        event = $.event.fix(orgEvent);
14619        event.type = "mousewheel";
14620        // Old school scrollwheel delta
14621        if (orgEvent.wheelDelta) {
14622            delta = orgEvent.wheelDelta / 120;
14623        }
14624        if (orgEvent.detail) {
14625            delta = -orgEvent.detail / 3;
14626        }
14627        // New school multidimensional scroll (touchpads) deltas
14628        deltaY = delta;
14629        // Gecko
14630        if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) {
14631            deltaY = 0;
14632            deltaX = -1 * delta;
14633        }
14634        // Webkit
14635        if (orgEvent.wheelDeltaY !== undefined) {
14636            deltaY = orgEvent.wheelDeltaY / 120;
14637        }
14638        if (orgEvent.wheelDeltaX !== undefined) {
14639            deltaX = -1 * orgEvent.wheelDeltaX / 120;
14640        }
14641        // Add event and delta to the front of the arguments
14642        args.unshift(event, delta, deltaX, deltaY);
14643        return ($.event.dispatch || $.event.handle).apply(this, args);
14644    }
14645})(jQuery);
14646/**
14647 * jQuery iLightBox - Revolutionary Lightbox Plugin
14648 * http://www.ilightbox.net/
14649 *
14650 * @version: 2.2.4 - October 14, 2017
14651 *
14652 * @author: iProDev (Hemn Chawroka)
14653 *          http://www.iprodev.com/
14654 *
14655 */
14656(function($, window, undefined) {
14657
14658	var extensions = {
14659			flash: ['swf'],
14660			image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe', 'webp'],
14661			iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'],
14662			video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v']
14663		},
14664
14665		// Global DOM elements
14666		$win = $(window),
14667		$doc = $(document),
14668
14669		// Support indicators
14670		browser,
14671		transform,
14672		gpuAcceleration,
14673		fullScreenApi = '',
14674		userAgent = navigator.userAgent || navigator.vendor || window.opera,
14675        supportTouch = "ontouchstart" in window || navigator.msMaxTouchPoints || (navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1),
14676        ishybrid = navigator.maxTouchPoints && navigator.userAgent.indexOf('Windows') > -1,
14677        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)),
14678
14679		// Events
14680		clickEvent = ishybrid ? "itap.iLightBox click.iLightBox" : supportTouch ? "itap.iLightBox" : "click.iLightBox",
14681		touchStartEvent = ishybrid ? "touchstart.iLightBox mousedown.iLightBox" : supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox",
14682		touchStopEvent = ishybrid ? "touchend.iLightBox mouseup.iLightBox" : supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox",
14683		touchMoveEvent = ishybrid ? "touchmove.iLightBox mousemove.iLightBox" : supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox",
14684
14685		// Math shorthands
14686		abs = Math.abs,
14687		sqrt = Math.sqrt,
14688		round = Math.round,
14689		max = Math.max,
14690		min = Math.min,
14691		floor = Math.floor,
14692		random = Math.random,
14693
14694		pluginspages = {
14695			quicktime: 'http://www.apple.com/quicktime/download',
14696			flash: 'http://www.adobe.com/go/getflash'
14697		},
14698
14699		iLightBox = function(el, options, items, instant) {
14700			var iL = this;
14701
14702			iL.options = options,
14703				iL.selector = options.selector || el,
14704				iL.context = document,
14705				iL.instant = instant;
14706
14707			if (items.length < 1) iL.attachItems();
14708			else iL.items = items;
14709
14710			iL.vars = {
14711				total: iL.items.length,
14712				start: 0,
14713				current: null,
14714				next: null,
14715				prev: null,
14716				BODY: $('body'),
14717				loadRequests: 0,
14718				overlay: $('<div class="ilightbox-overlay"></div>'),
14719				loader: $('<div class="ilightbox-loader"><div></div></div>'),
14720				toolbar: $('<div class="ilightbox-toolbar"></div>'),
14721				innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'),
14722				title: $('<div class="ilightbox-title"></div>'),
14723				closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'),
14724				fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'),
14725				innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'),
14726				innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'),
14727				innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'),
14728				holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
14729				nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
14730				prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
14731				nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'),
14732				prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
14733				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>'),
14734				thumbs: false,
14735				nextLock: false,
14736				prevLock: false,
14737				hashLock: false,
14738				isMobile: false,
14739				mobileMaxWidth: 980,
14740				isInFullScreen: false,
14741				isSwipe: false,
14742				mouseID: 0,
14743				cycleID: 0,
14744				isPaused: 0,
14745				captionHeight: 39,
14746			};
14747
14748			// Hideable elements with mousemove event
14749			iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton);
14750
14751			iL.normalizeItems();
14752
14753			//Check necessary plugins
14754			iL.availPlugins();
14755
14756			//Set startFrom
14757			iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom;
14758
14759			//If randomStart
14760			iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom;
14761			iL.vars.start = iL.options.startFrom;
14762
14763			if (instant) iL.instantCall();
14764			else iL.patchItemsEvents();
14765
14766			if (iL.options.linkId) {
14767				iL.hashChangeHandler();
14768				$win.iLightBoxHashChange(function() {
14769					iL.hashChangeHandler();
14770				});
14771			}
14772
14773			if (supportTouch) {
14774				var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig,
14775					replace = "itap";
14776				iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace),
14777					iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace),
14778					iL.options.social.show = iL.options.social.show.replace(RegExp, replace),
14779					iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace);
14780			}
14781
14782			if (iL.options.controls.arrows || $(window).width() < UNCODE.mediaQuery) {
14783				$.extend(iL.options.styles, {
14784					nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4,
14785					prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4,
14786					nextOpacity: 0,
14787					prevOpacity: 0
14788				});
14789			}
14790		};
14791
14792	//iLightBox helpers
14793	iLightBox.prototype = {
14794		showLoader: function() {
14795			var iL = this;
14796			iL.vars.loadRequests += 1;
14797			if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.addClass('ilightbox-show').stop().animate({
14798				//top: '-30px'
14799				opacity: '1'
14800			}, iL.options.show.speed, 'easeOutCirc');
14801			else iL.vars.loader.addClass('ilightbox-show').stop().animate({
14802				//left: '-30px'
14803				opacity: '1'
14804			}, iL.options.show.speed, 'easeOutCirc');
14805		},
14806
14807		hideLoader: function() {
14808			var iL = this;
14809			iL.vars.loadRequests -= 1;
14810			iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests;
14811			if (iL.options.path.toLowerCase() == "horizontal") {
14812				if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({
14813					//top: '-192px'
14814					opacity: '0'
14815				}, iL.options.show.speed, 'easeInCirc');
14816			} else {
14817				if (iL.vars.loadRequests <= 0) iL.vars.loader.removeClass('ilightbox-show').stop().animate({
14818					//left: '-192px'
14819					opacity: '0'
14820				}, iL.options.show.speed, 'easeInCirc');
14821			}
14822		},
14823
14824		createUI: function() {
14825			var iL = this;
14826
14827			iL.ui = {
14828				currentElement: iL.vars.holder,
14829				nextElement: iL.vars.nextPhoto,
14830				prevElement: iL.vars.prevPhoto,
14831				currentItem: iL.vars.current,
14832				nextItem: iL.vars.next,
14833				prevItem: iL.vars.prev,
14834				hide: function() {
14835					iL.closeAction();
14836				},
14837				refresh: function() {
14838					(arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto();
14839				},
14840				fullscreen: function() {
14841					iL.fullScreenAction();
14842				}
14843			};
14844		},
14845
14846		attachItems: function() {
14847			var iL = this,
14848				itemsObject = new Array(),
14849				items = new Array();
14850
14851			$(iL.selector, iL.context).each(function() {
14852				var t = $(this),
14853					URL = t.attr(iL.options.attr) || null,
14854					options = t.data("options") && eval("({" + t.data("options") + "})") || {},
14855					caption = t.data('caption'),
14856					title = t.data('title'),
14857					type = t.data('type') || getTypeByExtension(URL),
14858					clone = t.data('lbox-clone') || false;
14859
14860				//Uncode addition ##START##
14861				if (type === false) {
14862					return;
14863				}
14864				//Uncode addition ##END##
14865
14866				if (t.data('lbox-clone') != undefined) return;
14867
14868				//Uncode addition ##START##
14869				if ( typeof t.attr('data-album') != 'undefined' && t.attr('data-album') != '' ) {
14870					var ALBUM_URLS = JSON.parse(t.attr('data-album')),
14871						URL_i,
14872						URLS_LENGHT = ALBUM_URLS.length;
14873
14874					for (URL_i = 0; URL_i < URLS_LENGHT; URL_i++) {
14875						if ( typeof ALBUM_URLS[URL_i].url !== 'undefined' && ALBUM_URLS[URL_i].url != '' ) {
14876							var item_opts = 'width:' + ALBUM_URLS[URL_i].width + ',height:' + ALBUM_URLS[URL_i].height + ',thumbnail: \'' + ALBUM_URLS[URL_i].thumbnail + '\'';
14877							item_opts = item_opts && eval("({" + item_opts + "})") || {},
14878							items.push({
14879								URL: ALBUM_URLS[URL_i].url,
14880								caption: ALBUM_URLS[URL_i].caption,
14881								title: ALBUM_URLS[URL_i].title,
14882								type: getTypeByExtension(ALBUM_URLS[URL_i].url),
14883								options: item_opts,
14884								clone: clone
14885							});
14886							var newT = t;
14887							newT.attr('href',ALBUM_URLS[URL_i].url);
14888							if (!iL.instant) itemsObject.push(newT);
14889						}
14890					}
14891				} else {
14892				//Uncode addition ##END##
14893					items.push({
14894						URL: URL,
14895						caption: caption,
14896						title: title,
14897						type: type,
14898						options: options,
14899						clone: clone
14900					});
14901				}
14902
14903
14904				if (iL.vars != undefined) iL.vars.total = items.length;
14905
14906				if (!iL.instant) itemsObject.push(t);
14907			});
14908
14909			iL.items = items,
14910				iL.itemsObject = itemsObject;
14911
14912		},
14913
14914		normalizeItems: function() {
14915			var iL = this,
14916				newItems = new Array();
14917
14918			$.each(iL.items, function(key, val) {
14919
14920				if (typeof val == "string") val = {
14921					url: val
14922				};
14923
14924				var URL = val.url || val.URL || null,
14925					options = val.options || {},
14926					caption = val.caption || null,
14927					title = val.title || null,
14928					type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL),
14929					ext = (typeof URL != 'object') ? getExtension(URL) : '';
14930
14931				options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
14932				options.videoType = options.videoType || null,
14933				options.skin = options.skin || iL.options.skin,
14934				options.width = options.width || null,
14935				options.height = options.height || null,
14936				options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true,
14937				options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true,
14938				options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons);
14939
14940				if (type == "video") {
14941					options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {};
14942
14943					options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null;
14944					options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls";
14945					options.html5video.preload = options.html5video.preload || "metadata";
14946					options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false;
14947					//UNCODE addition
14948					options.html5video.loop = (typeof options.html5video.loop != 'undefined') ? options.html5video.loop : false;
14949				}
14950
14951				if (!options.width || !options.height) {
14952					if (type == "video") options.width = 1280, options.height = 720;
14953					else if (type == "iframe") options.width = '100%', options.height = '90%';
14954					else if (type == "flash") options.width = 1280, options.height = 720;
14955				}
14956
14957				delete val.url;
14958				val.index = key;
14959				val.URL = URL;
14960				val.caption = caption;
14961				val.title = title;
14962				val.type = type;
14963				val.options = options;
14964				val.ext = ext;
14965
14966				newItems.push(val);
14967			});
14968
14969			iL.items = newItems;
14970		},
14971
14972		instantCall: function() {
14973			var iL = this,
14974				key = iL.vars.start;
14975
14976			iL.vars.current = key;
14977			iL.vars.next = (iL.items[key + 1]) ? key + 1 : null;
14978			iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null;
14979
14980			iL.addContents();
14981			iL.patchEvents();
14982		},
14983
14984		addContents: function() {
14985			var iL = this,
14986				vars = iL.vars,
14987				opts = iL.options,
14988				viewport = getViewport(),
14989				path = opts.path.toLowerCase(),
14990				recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) {
14991					return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition);
14992				}),
14993				needRecognition = recognizingItems.length > 0;
14994
14995			if (opts.mobileOptimizer && !opts.innerToolbar)
14996				vars.isMobile = viewport.width <= vars.mobileMaxWidth;
14997
14998			vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity);
14999
15000			if (opts.linkId)
15001				vars.overlay[0].setAttribute('linkid', opts.linkId);
15002
15003			//Add Toolbar Buttons
15004			if (opts.controls.toolbar) {
15005				vars.toolbar.addClass(opts.skin).append(vars.closeButton);
15006				if (opts.controls.fullscreen)
15007					vars.toolbar.append(vars.fullScreenButton);
15008				if (opts.controls.slideshow)
15009					vars.toolbar.append(vars.innerPlayButton);
15010				if (vars.total > 1)
15011					vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton);
15012			}
15013
15014			//Append elements to body
15015			vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto);
15016
15017			if (!opts.innerToolbar)
15018				vars.BODY.append(vars.toolbar);
15019			if (opts.controls.arrows)
15020				vars.BODY.append(vars.nextButton).append(vars.prevButton);
15021
15022			if (opts.controls.thumbnail && vars.total > 1) {
15023				vars.BODY.append(vars.thumbnails);
15024				vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path);
15025				$('div.ilightbox-thumbnails-grid', vars.thumbnails).empty();
15026				vars.thumbs = true;
15027			}
15028
15029			//Configure loader and arrows
15030			var loaderCss = (opts.path.toLowerCase() == "horizontal") ? {
15031				left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2))
15032			} : {
15033				top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2))
15034			};
15035			vars.loader.addClass(opts.skin).css(loaderCss);
15036			vars.nextButton.add(vars.prevButton).addClass(opts.skin);
15037			if (path == "horizontal")
15038				vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal');
15039
15040			// Configure arrow buttons
15041			vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile');
15042
15043			if (!opts.infinite) {
15044				vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
15045
15046				if (vars.current == 0)
15047					vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
15048				if (vars.current >= vars.total - 1)
15049					vars.nextButton.add(vars.innerNextButton).addClass('disabled');
15050			}
15051
15052			if (opts.show.effect) {
15053				vars.overlay.stop().fadeIn(opts.show.speed);
15054				vars.toolbar.stop().fadeIn(opts.show.speed);
15055			} else {
15056				vars.overlay.show();
15057				vars.toolbar.show();
15058			}
15059
15060			var length = recognizingItems.length;
15061			if (needRecognition) {
15062				iL.showLoader();
15063
15064				$.each(recognizingItems, function(key, val) {
15065					var resultFnc = function(result) {
15066							var key = -1,
15067								filter = iL.items.filter(function(e, i, arr) {
15068									if (e.URL == result.url)
15069										key = i;
15070
15071									return e.URL == result.url;
15072								}),
15073								self = iL.items[key];
15074
15075							if (result)
15076								$.extend(true, self, {
15077									URL: result.source,
15078									type: result.type,
15079									recognized: true,
15080									options: {
15081										html5video: result.html5video,
15082										width: (result.type == "image") ? 0 : (result.width || self.width),
15083										height: (result.type == "image") ? 0 : (result.height || self.height),
15084										thumbnail: self.options.thumbnail || result.thumbnail
15085									}
15086								});
15087
15088							length--;
15089
15090							if (length == 0) {
15091								iL.hideLoader();
15092
15093								vars.dontGenerateThumbs = false;
15094								iL.generateThumbnails();
15095
15096								if (opts.show.effect)
15097									setTimeout(function() {
15098										iL.generateBoxes();
15099									}, opts.show.speed);
15100								else
15101									iL.generateBoxes();
15102							}
15103						};
15104
15105					iL.ogpRecognition(this, resultFnc);
15106				});
15107			}
15108			else {
15109				if (opts.show.effect)
15110					setTimeout(function() {
15111						iL.generateBoxes();
15112					}, opts.show.speed);
15113				else
15114					iL.generateBoxes();
15115			}
15116
15117			iL.createUI();
15118
15119			window.iLightBox = {
15120				close: function() {
15121					iL.closeAction();
15122				},
15123				fullscreen: function() {
15124					iL.fullScreenAction();
15125				},
15126				moveNext: function() {
15127					iL.moveTo('next');
15128				},
15129				movePrev: function() {
15130					iL.moveTo('prev');
15131				},
15132				goTo: function(index) {
15133					iL.goTo(index);
15134				},
15135				refresh: function() {
15136					iL.refresh();
15137				},
15138				reposition: function() {
15139					(arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto();
15140				},
15141				setOption: function(options) {
15142					iL.setOption(options);
15143				},
15144				destroy: function() {
15145					iL.closeAction();
15146					iL.dispatchItemsEvents();
15147				}
15148			};
15149
15150			if (opts.linkId) {
15151				vars.hashLock = true;
15152				window.location.hash = opts.linkId + '/' + vars.current;
15153				setTimeout(function() {
15154					vars.hashLock = false;
15155				}, 55);
15156			}
15157
15158			if (!opts.slideshow.startPaused) {
15159				iL.resume();
15160				vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause');
15161			}
15162
15163			//Trigger the onOpen callback
15164			if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL);
15165		},
15166
15167		loadContent: function(obj, opt, speed) {
15168			var iL = this,
15169				holder, item;
15170
15171			iL.createUI();
15172
15173			obj.speed = speed || iL.options.effects.loadedFadeSpeed;
15174
15175			if (opt == 'current') {
15176				if (!obj.options.mousewheel) iL.vars.lockWheel = true;
15177				else iL.vars.lockWheel = false;
15178
15179				if (!obj.options.swipe) iL.vars.lockSwipe = true;
15180				else iL.vars.lockSwipe = false;
15181			}
15182
15183			switch (opt) {
15184				case 'current':
15185					holder = iL.vars.holder, item = iL.vars.current;
15186					break;
15187				case 'next':
15188					holder = iL.vars.nextPhoto, item = iL.vars.next;
15189					break;
15190				case 'prev':
15191					holder = iL.vars.prevPhoto, item = iL.vars.prev;
15192					break;
15193			}
15194
15195			holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin);
15196			$('div.ilightbox-inner-toolbar', holder).remove();
15197
15198			if (obj.title || iL.options.innerToolbar) {
15199				var innerToolbar = iL.vars.innerToolbar.clone();
15200				if (obj.title && iL.options.show.title) {
15201					var title = iL.vars.title.clone();
15202					title.empty().html(obj.title);
15203					innerToolbar.append(title);
15204				}
15205				if (iL.options.innerToolbar) {
15206					innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar);
15207				}
15208				holder.prepend(innerToolbar);
15209			}
15210
15211			//console.warn('loadContent', arguments);
15212
15213			iL.loadSwitcher(obj, holder, item, opt);
15214		},
15215
15216		loadSwitcher: function(obj, holder, item, opt) {
15217			var iL = this,
15218				opts = iL.options,
15219				api = {
15220					element: holder,
15221					position: item
15222				};
15223
15224			switch (obj.type) {
15225				case 'image':
15226					//Trigger the onBeforeLoad callback
15227					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15228					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15229
15230					iL.loadImage(obj.URL, function(img) {
15231						//Trigger the onAfterLoad callback
15232						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15233						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15234
15235						var width = (img) ? img.width : 400,
15236							height = (img) ? img.height : 200;
15237
15238						holder.data({
15239							naturalWidth: width,
15240							naturalHeight: height
15241						});
15242
15243						$('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>');
15244
15245						//Trigger the onRender callback
15246						if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15247						if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15248
15249						iL.configureHolder(obj, opt, holder);
15250					});
15251
15252					break;
15253
15254				case 'video':
15255					holder.data({
15256						naturalWidth: obj.options.width,
15257						naturalHeight: obj.options.height
15258					});
15259
15260					if (opt === 'current') {
15261						iL.addContent(holder, obj);
15262
15263						//Trigger the onRender callback
15264						if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15265						if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15266					} else {
15267						$('div.ilightbox-container', holder).empty();
15268					}
15269
15270					iL.configureHolder(obj, opt, holder);
15271
15272					break;
15273
15274				case 'iframe':
15275					//iL.showLoader();
15276					holder.data({
15277						naturalWidth: obj.options.width,
15278						naturalHeight: obj.options.height
15279					});
15280
15281					iL.configureHolder(obj, opt, holder);
15282
15283					if (opt === 'current') {
15284						var el = iL.addContent(holder, obj);
15285
15286						//Trigger the onRender callback
15287						if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15288						if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15289
15290						//Trigger the onBeforeLoad callback
15291						if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15292						if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15293
15294						el.bind('load', function() {
15295							//Trigger the onAfterLoad callback
15296							if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15297							if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15298
15299							//iL.hideLoader();
15300							el.unbind('load');
15301						});
15302					} else {
15303						$('div.ilightbox-container', holder).empty();
15304					}
15305
15306					break;
15307
15308				case 'inline':
15309					var el = $(obj.URL),
15310						content = iL.addContent(holder, obj),
15311						images = findImageInElement(holder);
15312
15313					holder.data({
15314						naturalWidth: (iL.items[item].options.width || el.outerWidth()),
15315						naturalHeight: (iL.items[item].options.height || el.outerHeight())
15316					});
15317					content.children().eq(0).show();
15318
15319					//Trigger the onRender callback
15320					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15321					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15322
15323					//Trigger the onBeforeLoad callback
15324					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15325					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15326
15327					iL.loadImage(images, function() {
15328						//Trigger the onAfterLoad callback
15329						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15330						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15331
15332						iL.configureHolder(obj, opt, holder);
15333					});
15334
15335					break;
15336
15337				case 'flash':
15338					var el = iL.addContent(holder, obj);
15339
15340					holder.data({
15341						naturalWidth: (iL.items[item].options.width || el.outerWidth()),
15342						naturalHeight: (iL.items[item].options.height || el.outerHeight())
15343					});
15344
15345					//Trigger the onRender callback
15346					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15347					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15348
15349					iL.configureHolder(obj, opt, holder);
15350
15351					break;
15352
15353				case 'ajax':
15354					var ajax = obj.options.ajax || {};
15355					//Trigger the onBeforeLoad callback
15356					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15357					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15358
15359					iL.showLoader();
15360					$.ajax({
15361						url: obj.URL || opts.ajaxSetup.url,
15362						data: ajax.data || null,
15363						dataType: ajax.dataType || "html",
15364						type: ajax.type || opts.ajaxSetup.type,
15365						cache: ajax.cache || opts.ajaxSetup.cache,
15366						crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain,
15367						global: ajax.global || opts.ajaxSetup.global,
15368						ifModified: ajax.ifModified || opts.ajaxSetup.ifModified,
15369						username: ajax.username || opts.ajaxSetup.username,
15370						password: ajax.password || opts.ajaxSetup.password,
15371						beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend,
15372						complete: ajax.complete || opts.ajaxSetup.complete,
15373						success: function(data, textStatus, jqXHR) {
15374							iL.hideLoader();
15375
15376							var el = $(data),
15377								container = $('div.ilightbox-container', holder),
15378								elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')),
15379								elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')),
15380								css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? {
15381									'overflow': 'hidden'
15382								} : {};
15383
15384							container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el));
15385							holder.show().data({
15386								naturalWidth: (elWidth || container.outerWidth()),
15387								naturalHeight: (elHeight || container.outerHeight())
15388							}).hide();
15389
15390							//Trigger the onRender callback
15391							if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15392							if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15393
15394							var images = findImageInElement(holder);
15395							iL.loadImage(images, function() {
15396								//Trigger the onAfterLoad callback
15397								if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15398								if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15399
15400								iL.configureHolder(obj, opt, holder);
15401							});
15402
15403							opts.ajaxSetup.success(data, textStatus, jqXHR);
15404							if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR);
15405						},
15406						error: function(jqXHR, textStatus, errorThrown) {
15407							//Trigger the onAfterLoad callback
15408							if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15409							if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15410
15411							iL.hideLoader();
15412							$('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>');
15413							iL.configureHolder(obj, opt, holder);
15414
15415							opts.ajaxSetup.error(jqXHR, textStatus, errorThrown);
15416							if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown);
15417						}
15418					});
15419
15420					break;
15421
15422				case 'html':
15423					var object = obj.URL,
15424						el
15425					container = $('div.ilightbox-container', holder);
15426
15427					if (object[0].nodeName) el = object.clone();
15428					else {
15429						var dom = $(object);
15430						if (dom.selector) el = $('<div>' + dom + '</div>');
15431						else el = dom;
15432					}
15433
15434					var elWidth = iL.items[item].options.width || parseInt(el.attr('width')),
15435						elHeight = iL.items[item].options.height || parseInt(el.attr('height'));
15436
15437					iL.addContent(holder, obj);
15438
15439					el.appendTo(document.documentElement).hide();
15440
15441					//Trigger the onRender callback
15442					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
15443					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
15444
15445					var images = findImageInElement(holder);
15446
15447					//Trigger the onBeforeLoad callback
15448					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
15449					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
15450
15451					iL.loadImage(images, function() {
15452						//Trigger the onAfterLoad callback
15453						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
15454						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
15455
15456						holder.show().data({
15457							naturalWidth: (elWidth || container.outerWidth()),
15458							naturalHeight: (elHeight || container.outerHeight())
15459						}).hide();
15460						el.remove();
15461
15462						iL.configureHolder(obj, opt, holder);
15463					});
15464
15465					break;
15466			}
15467		},
15468
15469		configureHolder: function(obj, opt, holder) {
15470			var iL = this,
15471				vars = iL.vars,
15472				opts = iL.options;
15473
15474			if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev');
15475
15476			if (opt == "current")
15477				var item = vars.current;
15478			else if (opt == "next")
15479				var opacity = opts.styles.nextOpacity,
15480					item = vars.next;
15481			else
15482				var opacity = opts.styles.prevOpacity,
15483					item = vars.prev;
15484
15485			var api = {
15486				element: holder,
15487				position: item
15488			};
15489
15490			iL.items[item].options.width = iL.items[item].options.width || 0,
15491			iL.items[item].options.height = iL.items[item].options.height || 0;
15492
15493			if (opt == "current") {
15494				if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() {
15495					holder.css(transform, '');
15496					if (obj.caption) {
15497						iL.setCaption(obj, holder);
15498						var caption = $('div.ilightbox-caption', holder),
15499							percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100);
15500						if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
15500Speed);
15501					}
15502
15503					var social = obj.options.social;
15504					if (social) {
15505						iL.setSocial(social, obj.URL, holder);
15506						if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed);
15507					}
15508
15509					//Generate thumbnails
15510					iL.generateThumbnails();
15511
15512					//Trigger the onShow callback
15513					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
15514					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
15515				});
15516				else {
15517					holder.show();
15518
15519					//Generate thumbnails
15520					iL.generateThumbnails();
15521
15522					//Trigger the onShow callback
15523					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
15524					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
15525				}
15526			} else {
15527				if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() {
15528					if (opt == "next") vars.nextLock = false;
15529					else vars.prevLock = false;
15530
15531					//Generate thumbnails
15532					iL.generateThumbnails();
15533
15534					//Trigger the onShow callback
15535					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
15536					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
15537				});
15538				else {
15539					holder.css({
15540						opacity: opacity
15541					}).show();
15542					if (opt == "next") vars.nextLock = false;
15543					else vars.prevLock = false;
15544
15545					//Generate thumbnails
15546					iL.generateThumbnails();
15547
15548					//Trigger the onShow callback
15549					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
15550					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
15551				}
15552			}
15553
15554			setTimeout(function() {
15555				iL.repositionPhoto();
15556			}, 0);
15557		},
15558
15559		generateBoxes: function() {
15560			var iL = this,
15561				vars = iL.vars,
15562				opts = iL.options;
15563
15564			if (opts.infinite && vars.total >= 3) {
15565				if (vars.current == vars.total - 1) vars.next = 0;
15566				if (vars.current == 0) vars.prev = vars.total - 1;
15567			} else opts.infinite = false;
15568
15569			//UNCODE addition
15570			if ( typeof iL.items[vars.current] == 'undefined' )
15571				vars.current = 0;
15572
15573			iL.loadContent(iL.items[vars.current], 'current', opts.show.speed);
15574
15575			if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed);
15576			if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed);
15577		},
15578
15579		generateThumbnails: function() {
15580			var iL = this,
15581				vars = iL.vars,
15582				opts = iL.options,
15583				timeOut = null;
15584
15585			if (vars.thumbs && !iL.vars.dontGenerateThumbs) {
15586				var thumbnails = vars.thumbnails,
15587					container = $('div.ilightbox-thumbnails-container', thumbnails),
15588					grid = $('div.ilightbox-thumbnails-grid', container),
15589					i = 0;
15590
15591				grid.removeAttr('style').empty();
15592
15593				$.each(iL.items, function(key, val) {
15594					var isActive = (vars.current == key) ? 'ilightbox-active' : '',
15595						opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity,
15596						thumb = val.options.thumbnail,
15597						thumbnail = $('<div class="ilightbox-thumbnail"></div>'),
15598						icon = $('<div class="ilightbox-thumbnail-icon"></div>');
15599
15600					thumbnail.css({
15601						opacity: 0
15602					}).addClass(isActive);
15603
15604					if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') {
15605						icon.addClass('ilightbox-thumbnail-video');
15606						thumbnail.append(icon);
15607					} else if (val.options.icon) {
15608						icon.addClass('ilightbox-thumbnail-' + val.options.icon);
15609						thumbnail.append(icon);
15610					}
15611
15612					if (thumb) iL.loadImage(thumb, function(img) {
15613						i++;
15614						if (img) thumbnail.data({
15615							naturalWidth: img.width,
15616							naturalHeight: img.height
15617						}).append('<img src="' + thumb + '" border="0" />');
15618						else thumbnail.data({
15619							naturalWidth: opts.thumbnails.maxWidth,
15620							naturalHeight: opts.thumbnails.maxHeight
15621						});
15622
15623						clearTimeout(timeOut);
15624						timeOut = setTimeout(function() {
15625							iL.positionThumbnails(thumbnails, container, grid);
15626						}, 20);
15627						setTimeout(function() {
15628							thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity);
15629						}, i * 20);
15630					});
15631
15632					grid.append(thumbnail);
15633				});
15634				iL.vars.dontGenerateThumbs = true;
15635			}
15636		},
15637
15638		positionThumbnails: function(thumbnails, container, grid) {
15639			var iL = this,
15640				vars = iL.vars,
15641				opts = iL.options,
15642				viewport = getViewport(),
15643				path = opts.path.toLowerCase();
15644
15645			if (!thumbnails) thumbnails = vars.thumbnails;
15646			if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails);
15647			if (!grid) grid = $('div.ilightbox-thumbnails-grid', container);
15648
15649			var thumbs = $('.ilightbox-thumbnail', grid),
15650				widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX,
15651				heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY,
15652				gridWidth = (path == 'horizontal') ? 0 : widthAvail,
15653				gridHeight = (path == 'horizontal') ? heightAvail : 0,
15654				active = $('.ilightbox-active', grid),
15655				gridCss = {},
15656				css = {};
15657
15658			if (arguments.length < 3) {
15659				thumbs.css({
15660					opacity: opts.thumbnails.normalOpacity
15661				});
15662				active.css({
15663					opacity: opts.thumbnails.activeOpacity
15664				});
15665			}
15666
15667			thumbs.each(function(i) {
15668				var t = $(this),
15669					data = t.data(),
15670					width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth;
15671				height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0;
15672				dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true);
15673
15674				t.css({
15675					width: dims.width,
15676					height: dims.height
15677				});
15678				if (path == 'horizontal') t.css({
15679					'float': 'left'
15680				});
15681
15682				(path == 'horizontal') ? (
15683					gridWidth += t.outerWidth()
15684				) : (
15685					gridHeight += t.outerHeight()
15686				);
15687			});
15688
15689			gridCss = {
15690				width: gridWidth,
15691				height: gridHeight
15692			};
15693
15694			grid.css(gridCss);
15695
15696			gridCss = {};
15697
15698			var gridOffset = grid.offset(),
15699				activeOffset = (active.length) ? active.offset() : {
15700					top: parseInt(heightAvail / 2),
15701					left: parseInt(widthAvail / 2)
15702				};
15703
15704			gridOffset.top = (gridOffset.top - $doc.scrollTop()),
15705				gridOffset.left = (gridOffset.left - $doc.scrollLeft()),
15706				activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()),
15707				activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft());
15708
15709			(path == 'horizontal') ? (
15710				gridCss.top = 0,
15711				gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2))
15712			) : (
15713				gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))),
15714				gridCss.left = 0
15715			);
15716
15717			if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc');
15718			else grid.css(gridCss);
15719		},
15720
15721		loadImage: function(image, callback) {
15722			if (!$.isArray(image)) image = [image];
15723
15724			var iL = this,
15725				length = image.length;
15726
15727			if (length > 0) {
15728				iL.showLoader();
15729				$.each(image, function(index, value) {
15730					var img = new Image();
15731					img.onload = function() {
15732						length -= 1;
15733						if (length == 0) {
15734							iL.hideLoader();
15735							callback(img);
15736						}
15737					};
15738					img.onerror = img.onabort = function() {
15739						length -= 1;
15740						if (length == 0) {
15741							iL.hideLoader();
15742							callback(false);
15743						}
15744					};
15745					img.src = image[index];
15746				});
15747			} else callback(false);
15748		},
15749
15750		patchItemsEvents: function() {
15751			var iL = this,
15752				vars = iL.vars,
15753				clickEvent = ishybrid ? "itap.iL click.iL" : supportTouch ? "itap.iL" : "click.iL",
15754				vEvent = ishybrid ? "click.iL itap.iL" : supportTouch ? "click.iL" : "itap.iL";
15755
15756			if (iL.context && iL.selector) {
15757				var $items = $(iL.selector, iL.context);
15758
15759				$(iL.context).on(clickEvent, iL.selector, function() {
15760					var $this = $(this),
15761						//UNCODE addition
15762						key = typeof $(this).data('lb-index') !== '' && $(this).closest('.owl-item').length ? $(this).data('lb-index') : $items.index($this);
15763					if (UNCODE.isMobile) {
15764						var isCarousel = $this.closest('.owl-carousel');
15765						if (isCarousel.length) {
15766							if (isCarousel.hasClass('owl-translating')) return false;
15767						}
15768					}
15769
15770					vars.current = key;
15771					vars.next = iL.items[key + 1] ? key + 1 : null;
15772					vars.prev = iL.items[key - 1] ? key - 1 : null;
15773
15774					//UNCODE addition
15775					if ( vars.BODY.hasClass('fp-slide-scrolling') )
15776						return false;
15777
15778					iL.addContents();
15779					iL.patchEvents();
15780
15781					return false;
15782				}).on(vEvent, iL.selector, function() {
15783					return false;
15784				});
15785			} else
15786				$.each(iL.itemsObject, function(key, val) {
15787					val.on(clickEvent, function() {
15788						vars.current = key;
15789						vars.next = iL.items[key + 1] ? key + 1 : null;
15790						vars.prev = iL.items[key - 1] ? key - 1 : null;
15791
15792						iL.addContents();
15793						iL.patchEvents();
15794
15795						return false;
15796					}).on(vEvent, function() {
15797						return false;
15798					});
15799				});
15800		},
15801
15802		dispatchItemsEvents: function() {
15803			var iL = this,
15804				vars = iL.vars,
15805				opts = iL.options;
15806
15807			if (iL.context && iL.selector)
15808				$(iL.context).off('.iL', iL.selector);
15809			else
15810				$.each(iL.itemsObject, function(key, val) {
15811					val.off('.iL');
15812				});
15813		},
15814
15815		refresh: function() {
15816			var iL = this;
15817
15818			iL.dispatchItemsEvents();
15819			iL.attachItems();
15820			iL.normalizeItems();
15821			iL.patchItemsEvents();
15822		},
15823
15824		patchEvents: function() {
15825			var iL = this,
15826				vars = iL.vars,
15827				opts = iL.options,
15828				path = opts.path.toLowerCase(),
15829				holders = $('.ilightbox-holder'),
15830				fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox',
15831				durationThreshold = 1000,
15832				horizontalDistanceThreshold =
15833				verticalDistanceThreshold = 100,
15834				buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild];
15835
15836			$win.bind('resize.iLightBox', function() {
15837				var viewport = getViewport();
15838
15839				if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth;
15840				vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile');
15841
15842				iL.repositionPhoto(null);
15843				if (supportTouch) {
15844					clearTimeout(vars.setTime);
15845					vars.setTime = setTimeout(function() {
15846						var scrollTop = getScrollXY().y;
15847						window.scrollTo(0, scrollTop - 30);
15848						window.scrollTo(0, scrollTop + 30);
15849						window.scrollTo(0, scrollTop);
15850					}, 2000);
15851				}
15852				if (vars.thumbs) iL.positionThumbnails();
15853			}).bind('keydown.iLightBox', function(event) {
15854				if (opts.controls.keyboard) {
15855					switch (event.keyCode) {
15856						case 13:
15857							if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction();
15858							break;
15859						case 27:
15860							if (opts.keyboard.esc) iL.closeAction();
15861							break;
15862						case 37:
15863							if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev');
15864							break;
15865						case 38:
15866							if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev');
15867							break;
15868						case 39:
15869							if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next');
15870							break;
15871						case 40:
15872							if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next');
15873							break;
15874					}
15875				}
15876			});
15877
15878			if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() {
15879				iL.doFullscreen();
15880			});
15881
15882			var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) {
15883					return arr.lastIndexOf(e) === i;
15884				}),
15885				holderEvents = "";
15886
15887			$.each(holderEventsArr, function(key, val) {
15888				if (key != 0) holderEvents += ' ';
15889				holderEvents += val;
15890			});
15891
15892			$doc.on(clickEvent, '.ilightbox-overlay', function() {
15893				if (opts.overlay.blur) iL.closeAction();
15894			}).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() {
15895				iL.moveTo('next');
15896			}).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() {
15897				iL.moveTo('prev');
15898			}).on(clickEvent, '.ilightbox-thumbnail', function() {
15899				var t = $(this),
15900					thumbs = $('.ilightbox-thumbnail', vars.thumbnails),
15901					index = thumbs.index(t);
15902
15903				if (index != vars.current) iL.goTo(index);
15904			}).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) {
15905				var caption = $('div.ilightbox-caption', vars.holder),
15906					social = $('div.ilightbox-social', vars.holder),
15907					fadeSpeed = opts.effects.fadeSpeed;
15908
15909				if (vars.nextLock || vars.prevLock) {
15910					if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed);
15911					else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed);
15912
15913					if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed);
15914					else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed);
15915				} else {
15916					if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed);
15917					else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed);
15918
15919					if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed);
15920					else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed);
15921				}
15922			}).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) {
15923				if (e.type == 'mouseenter') vars.lockWheel = true;
15924				else vars.lockWheel = false;
15925			}).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() {
15926				var t = $(this);
15927
15928				if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction();
15929				else if (t.hasClass('ilightbox-play')) {
15930					iL.resume();
15931					t.addClass('ilightbox-pause').removeClass('ilightbox-play');
15932				} else if (t.hasClass('ilightbox-pause')) {
15933					iL.pause();
15934					t.addClass('ilightbox-play').removeClass('ilightbox-pause');
15935				} else iL.closeAction();
15936			}).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) {
15937				// prevent scrolling
15938				e.preventDefault();
15939			});
15940
15941			function mouseMoveHandler(e) {
15942				if (!vars.isMobile) {
15943					if (!vars.mouseID) {
15944						vars.hideableElements.show();
15945					}
15946
15947					vars.mouseID = clearTimeout(vars.mouseID);
15948
15949					if (buttonsArray.indexOf(e.target) === -1)
15950						vars.mouseID = setTimeout(function() {
15951							vars.hideableElements.hide();
15952							vars.mouseID = clearTimeout(vars.mouseID);
15953						}, 3000);
15954				}
15955			}
15956
15957			if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler);
15958
15959			if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) {
15960				if (e.type == 'mouseenter' && vars.cycleID) iL.pause();
15961				else if (e.type == 'mouseleave' && vars.isPaused) iL.resume();
15962			});
15963
15964			var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails'),
15965				delay = false;
15966
15967			if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) {
15968				event.preventDefault();
15969				if (delay) return;
15970				delay = true;
15971				if (!vars.lockWheel) {
15972					event.preventDefault();
15973					if (delta < 0) {
15974						iL.moveTo('next');
15975					} else if (delta > 0) {
15976						iL.moveTo('prev');
15977					}
15978				}
15979				setTimeout(function(){
15980					delay = false;
15981				}, 2000);
15982			});
15983
15984			if (opts.controls.swipe) holders.on(touchStartEvent, function(event) {
15985				if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return;
15986
15987				vars.BODY.addClass('ilightbox-closedhand');
15988
15989				var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event,
15990					scrollTop = $doc.scrollTop(),
15991					scrollLeft = $doc.scrollLeft(),
15992					offsets = [
15993						holders.eq(0).offset(),
15994						holders.eq(1).offset(),
15995						holders.eq(2).offset()
15996					],
15997					offSet = [{
15998						top: offsets[0].top - scrollTop,
15999						left: offsets[0].left - scrollLeft
16000					}, {
16001						top: offsets[1].top - scrollTop,
16002						left: offsets[1].left - scrollLeft
16003					}, {
16004						top: offsets[2].top - scrollTop,
16005						left: offsets[2].left - scrollLeft
16006					}],
16007					start = {
16008						time: (new Date()).getTime(),
16009						coords: [data.pageX - scrollLeft, data.pageY - scrollTop]
16010					},
16011					stop;
16012
16013				function moveEachHandler(i) {
16014					var t = $(this),
16015						offset = offSet[i],
16016						scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])];
16017
16018					t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px';
16019				}
16020
16021				function moveHandler(event) {
16022
16023					if (!start) return;
16024
16025					var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event;
16026
16027					stop = {
16028						time: (new Date()).getTime(),
16029						coords: [data.pageX - scrollLeft, data.pageY - scrollTop]
16030					};
16031
16032					holders.each(moveEachHandler);
16033
16034					// prevent scrolling
16035					event.preventDefault();
16036				}
16037
16038				function repositionHolders() {
16039					holders.each(function() {
16040						var t = $(this),
16041							offset = t.data('offset') || {
16042								top: t.offset().top - scrollTop,
16043								left: t.offset().left - scrollLeft
16044							},
16045							top = offset.top,
16046							left = offset.left;
16047
16048						t.css(transform, gpuAcceleration).stop().animate({
16049							top: top,
16050							left: left
16051						}, 500, 'easeOutCirc', function() {
16052							t.css(transform, '');
16053						});
16054					});
16055				}
16056
16057				holders.bind(touchMoveEvent, moveHandler);
16058				$doc.one(touchStopEvent, function(event) {
16059					holders.unbind(touchMoveEvent, moveHandler);
16060
16061					vars.BODY.removeClass('ilightbox-closedhand');
16062
16063					if (start && stop) {
16064						if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) {
16065							if (start.coords[0] > stop.coords[0]) {
16066								if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders();
16067								else {
16068									vars.isSwipe = true;
16069									iL.moveTo('next');
16070								}
16071							} else {
16072								if (vars.current == 0 && !opts.infinite) repositionHolders();
16073								else {
16074									vars.isSwipe = true;
16075									iL.moveTo('prev');
16076								}
16077							}
16078						} 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) {
16079							if (start.coords[1] > stop.coords[1]) {
16080								if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders();
16081								else {
16082									vars.isSwipe = true;
16083									iL.moveTo('next');
16084								}
16085							} else {
16086								if (vars.current == 0 && !opts.infinite) repositionHolders();
16087								else {
16088									vars.isSwipe = true;
16089									iL.moveTo('prev');
16090								}
16091							}
16092						} else repositionHolders();
16093					}
16094					start = stop = undefined;
16095				});
16096			});
16097
16098		},
16099
16100		goTo: function(index) {
16101			var iL = this,
16102				vars = iL.vars,
16103				opts = iL.options,
16104				diff = (index - vars.current);
16105
16106			if (opts.infinite) {
16107				if (index == vars.total - 1 && vars.current == 0) diff = -1;
16108				if (vars.current == vars.total - 1 && index == 0) diff = 1;
16109			}
16110
16111			if (diff == 1) iL.moveTo('next');
16112			else if (diff == -1) iL.moveTo('prev');
16113			else {
16114
16115				if (vars.nextLock || vars.prevLock) return false;
16116
16117				//Trigger the onBeforeChange callback
16118				if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui);
16119
16120				if (opts.linkId) {
16121					vars.hashLock = true;
16122					window.location.hash = opts.linkId + '/' + index;
16123				}
16124
16125				if (iL.items[index]) {
16126					if (!iL.items[index].options.mousewheel) vars.lockWheel = true;
16127					else iL.vars.lockWheel = false;
16128
16129					if (!iL.items[index].options.swipe) vars.lockSwipe = true;
16130					else vars.lockSwipe = false;
16131				}
16132
16133				$.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) {
16134					val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed);
16135				});
16136
16137				vars.current = index;
16138				vars.next = index + 1;
16139				vars.prev = index - 1;
16140
16141				iL.createUI();
16142
16143				setTimeout(function() {
16144					iL.generateBoxes();
16145				}, opts.effects.loadedFadeSpeed + 50);
16146
16147				$('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active');
16148				iL.positionThumbnails();
16149
16150				if (opts.linkId) setTimeout(function() {
16151					vars.hashLock = false;
16152				}, 55);
16153
16154				// Configure arrow buttons
16155				if (!opts.infinite) {
16156					vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
16157
16158					if (vars.current == 0) {
16159						vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
16160					}
16161					if (vars.current >= vars.total - 1) {
16162						vars.nextButton.add(vars.innerNextButton).addClass('disabled');
16163					}
16164				}
16165
16166				// Reset next cycle timeout
16167				iL.resetCycle();
16168
16169				//Trigger the onAfterChange callback
16170				if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui);
16171			}
16172		},
16173
16174		moveTo: function(side) {
16175			var iL = this,
16176				vars = iL.vars,
16177				opts = iL.options,
16178				path = opts.path.toLowerCase(),
16179				viewport = getViewport(),
16180				switchSpeed = opts.effects.switchSpeed;
16181
16182			if (vars.nextLock || vars.prevLock) return false;
16183			else {
16184
16185				var item = (side == "next") ? vars.next : vars.prev;
16186
16187				if (opts.linkId) {
16188					vars.hashLock = true;
16189					window.location.hash = opts.linkId + '/' + item;
16190				}
16191
16192				if (side == "next") {
16193					if (!iL.items[item]) return false;
16194					var firstHolder = vars.nextPhoto,
16195						secondHolder = vars.holder,
16196						lastHolder = vars.prevPhoto,
16197						firstClass = 'ilightbox-prev',
16198						secondClass = 'ilightbox-next';
16199				} else if (side == "prev") {
16200					if (!iL.items[item]) return false;
16201					var firstHolder = vars.prevPhoto,
16202						secondHolder = vars.holder,
16203						lastHolder = vars.nextPhoto,
16204						firstClass = 'ilightbox-next',
16205						secondClass = 'ilightbox-prev';
16206				}
16207
16208				//Trigger the onBeforeChange callback
16209				if (typeof opts.callback.onBeforeChange == 'function')
16210					opts.callback.onBeforeChange.call(iL, iL.ui);
16211
16212				(side == "next") ? vars.nextLock = true: vars.prevLock = true;
16213
16214				var captionFirst = $('div.ilightbox-caption', secondHolder),
16215					socialFirst = $('div.ilightbox-social', secondHolder);
16216
16217				if (captionFirst.length)
16218					captionFirst.stop().fadeOut(switchSpeed, function() {
16219						$(this).remove();
16220					});
16221				if (socialFirst.length)
16222					socialFirst.stop().fadeOut(switchSpeed, function() {
16223						$(this).remove();
16224					});
16225
16226				if (iL.items[item].caption) {
16227					iL.setCaption(iL.items[item], firstHolder);
16228					var caption = $('div.ilightbox-caption', firstHolder),
16229						percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100);
16230					if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed);
16231				}
16232
16233				var social = iL.items[item].options.social;
16234				if (social) {
16235					iL.setSocial(social, iL.items[item].URL, firstHolder);
16236					if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed);
16237				}
16238
16239				$.each([firstHolder, secondHolder, lastHolder], function(key, val) {
16240					val.removeClass('ilightbox-next ilightbox-prev');
16241				});
16242
16243				var firstOffset = firstHolder.data('offset'),
16244					winW = (viewport.width - (opts.styles.pageOffsetX)),
16245					winH = (viewport.height - (opts.styles.pageOffsetY)),
16246					width = firstOffset.newDims.width,
16247					height = firstOffset.newDims.height,
16248					thumbsOffset = firstOffset.thumbsOffset,
16249					diff = firstOffset.diff,
16250					top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)),
16251					left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2));
16252
16253				var secondOffset = secondHolder.data('offset'),
16254					object = secondOffset.object;
16255
16256				/*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) {
16257					var objRatio = width / height;
16258					height = height - vars.captionHeight;
16259					width = height * objRatio;
16260					top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top,
16261					left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2));
16262				}*/
16263
16264				firstHolder.show().css(transform, gpuAcceleration).animate({
16265					top: top,
16266					left: left,
16267					opacity: 1
16268				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
16269					firstHolder.css(transform, '');
16270				});
16271
16272				$('div.ilightbox-container', firstHolder).animate({
16273					width: width,
16274					height: height
16275				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc');
16276
16277				diff = secondOffset.diff;
16278
16279				width = secondOffset.newDims.width,
16280					height = secondOffset.newDims.height;
16281
16282				width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']),
16283					height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']),
16284					top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2));
16285
16286				if (side == 'prev')
16287					left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2));
16288				else {
16289					top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)),
16290					left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2));
16291				}
16292
16293				/*if (object.item.caption && !isNaN(width) && !isNaN(height) && UNCODE.wwidth > UNCODE.mediaQuery) {
16294					var objRatio = width / height;
16295					height = height - vars.captionHeight;
16296					width = height * objRatio;
16297					top = path == 'horizontal' ? parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)) : top;
16298				}*/
16299
16300				$('div.ilightbox-container', secondHolder).animate({
16301					width: width,
16302					height: height
16303				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc');
16304
16305				secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({
16306					top: top,
16307					left: left,
16308					opacity: opts.styles.prevOpacity,
16309				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
16310					secondHolder.css(transform, '');
16311
16312					$('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active');
16313					iL.positionThumbnails();
16314
16315					if (iL.items[item]) {
16316						if (!iL.items[item].options.mousewheel) vars.lockWheel = true;
16317						else vars.lockWheel = false;
16318
16319						if (!iL.items[item].options.swipe) vars.lockSwipe = true;
16320						else vars.lockSwipe = false;
16321					}
16322
16323					vars.isSwipe = false;
16324
16325					// Remove iframe & video from previous slide
16326					if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) {
16327						$('div.ilightbox-container', secondHolder).empty();
16328					}
16329
16330					if (side == "next") {
16331						vars.nextPhoto = lastHolder,
16332							vars.prevPhoto = secondHolder,
16333							vars.holder = firstHolder;
16334
16335						vars.nextPhoto.hide();
16336
16337						vars.next = vars.next + 1,
16338							vars.prev = vars.current,
16339							vars.current = vars.current + 1;
16340
16341						if (opts.infinite) {
16342							if (vars.current > vars.total - 1) vars.current = 0;
16343							if (vars.current == vars.total - 1) vars.next = 0;
16344							if (vars.current == 0) vars.prev = vars.total - 1;
16345						}
16346
16347						iL.createUI();
16348
16349						if (!iL.items[vars.next])
16350							vars.nextLock = false;
16351						else
16352							iL.loadContent(iL.items[vars.next], 'next');
16353					} else {
16354						vars.prevPhoto = lastHolder;
16355						vars.nextPhoto = secondHolder;
16356						vars.holder = firstHolder;
16357
16358						vars.prevPhoto.hide();
16359
16360						vars.next = vars.current;
16361						vars.current = vars.prev;
16362						vars.prev = vars.current - 1;
16363
16364						if (opts.infinite) {
16365							if (vars.current == vars.total - 1) vars.next = 0;
16366							if (vars.current == 0) vars.prev = vars.total - 1;
16367						}
16368
16369						iL.createUI();
16370
16371						if (!iL.items[vars.prev])
16372							vars.prevLock = false;
16373						else
16374							iL.loadContent(iL.items[vars.prev], 'prev');
16375					}
16376
16377					// Add iframe & video content for current slide
16378					if (['iframe', 'video'].indexOf(iL.items[vars.current].type) !== -1) {
16379						iL.loadContent(iL.items[vars.current], 'current');
16380					}
16381
16382					if (opts.linkId) setTimeout(function() {
16383						vars.hashLock = false;
16384					}, 55);
16385
16386					// Configure arrow buttons
16387					if (!opts.infinite) {
16388						vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
16389
16390						if (vars.current == 0)
16391							vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
16392						if (vars.current >= vars.total - 1)
16393							vars.nextButton.add(vars.innerNextButton).addClass('disabled');
16394					}
16395
16396					iL.repositionPhoto();
16397
16398					// Reset next cycle timeout
16399					iL.resetCycle();
16400
16401					//Trigger the onAfterChange callback
16402					if (typeof opts.callback.onAfterChange == 'function')
16403						opts.callback.onAfterChange.call(iL, iL.ui);
16404				});
16405
16406				top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)),
16407					left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left');
16408
16409				lastHolder.css(transform, gpuAcceleration).animate({
16410					top: top,
16411					left: left,
16412					opacity: opts.styles.nextOpacity
16413				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
16414					lastHolder.css(transform, '');
16415				}).addClass(secondClass);
16416			}
16417		},
16418
16419		setCaption: function(obj, target) {
16420			var iL = this,
16421				caption = $('<div class="ilightbox-caption"></div>');
16422
16423			if (obj.caption) {
16424				caption.html(obj.caption);
16425				$('div.ilightbox-container', target).append(caption);
16426			}
16427		},
16428
16429		normalizeSocial: function(obj, url) {
16430			var iL = this,
16431				vars = iL.vars,
16432				opts = iL.options,
16433				baseURL = window.location.href;
16434
16435			$.each(obj, function(key, value) {
16436				if (!value)
16437					return true;
16438
16439				var item = key.toLowerCase(),
16440					source, text;
16441
16442				switch (item) {
16443					case 'facebook':
16444						source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}",
16445							text = "Share on Facebook";
16446						break;
16447					case 'twitter':
16448						source = "http://twitter.com/home?status={URL}",
16449							text = "Share on Twitter";
16450						break;
16451					case 'digg':
16452						source = "http://digg.com/submit?phase=2&url={URL}",
16453							text = "Share on Digg";
16454						break;
16455					case 'reddit':
16456						source = "http://reddit.com/submit?url={URL}",
16457							text = "Share on reddit";
16458						break;
16459				}
16460
16461				obj[key] = {
16462					URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL,
16463					source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url),
16464					text: value.text || text || "Share on " + key,
16465					width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640,
16466					height: value.height || 360
16467				};
16468
16469			});
16470
16471			return obj;
16472		},
16473
16474		setSocial: function(obj, url, target) {
16475			var iL = this,
16476				socialBar = $('<div class="ilightbox-social"></div>'),
16477				buttons = '<ul>';
16478
16479			obj = iL.normalizeSocial(obj, url);
16480
16481			$.each(obj, function(key, value) {
16482				var item = key.toLowerCase(),
16483					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, '+'));
16484				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>';
16485			});
16486
16487			buttons += '</ul>';
16488
16489			socialBar.html(buttons);
16490			$('div.ilightbox-container', target).append(socialBar);
16491		},
16492
16493		fullScreenAction: function() {
16494			var iL = this,
16495				vars = iL.vars;
16496
16497			if (fullScreenApi.supportsFullScreen) {
16498				if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement);
16499				else fullScreenApi.requestFullScreen(document.documentElement);
16500			} else {
16501				iL.doFullscreen();
16502			}
16503		},
16504
16505		doFullscreen: function() {
16506			var iL = this,
16507				vars = iL.vars,
16508				viewport = getViewport(),
16509				opts = iL.options;
16510
16511			if (opts.fullAlone) {
16512				var currentHolder = vars.holder,
16513					current = iL.items[vars.current],
16514					windowWidth = viewport.width,
16515					windowHeight = viewport.height,
16516					elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader],
16517					hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails];
16518
16519				if (!vars.isInFullScreen) {
16520					vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true;
16521					vars.overlay.css({
16522						opacity: 1
16523					});
16524
16525					$.each(hideElements, function(i, element) {
16526						element.hide();
16527					});
16528
16529					vars.fullScreenButton.attr('title', opts.text.exitFullscreen);
16530
16531					if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
16532						naturalWidthOld: currentHolder.data('naturalWidth'),
16533						naturalHeightOld: currentHolder.data('naturalHeight'),
16534						naturalWidth: windowWidth,
16535						naturalHeight: windowHeight
16536					});
16537					else {
16538						var viewport = current.options.fullViewPort || opts.fullViewPort || '',
16539							newWidth = windowWidth,
16540							newHeight = windowHeight,
16541							width = currentHolder.data('naturalWidth'),
16542							height = currentHolder.data('naturalHeight');
16543
16544						if (viewport.toLowerCase() == 'fill') {
16545							newHeight = (newWidth / width) * height;
16546
16547							if (newHeight < windowHeight) {
16548								newWidth = (windowHeight / height) * width,
16549									newHeight = windowHeight;
16550							}
16551						} else if (viewport.toLowerCase() == 'fit') {
16552							var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true);
16553
16554							newWidth = dims.width,
16555								newHeight = dims.height;
16556						} else if (viewport.toLowerCase() == 'stretch') {
16557							newWidth = newWidth,
16558								newHeight = newHeight;
16559						} else {
16560							var scale = (width > newWidth || height > newHeight) ? true : false,
16561								dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale);
16562							newWidth = dims.width,
16563								newHeight = dims.height;
16564						}
16565
16566						currentHolder.data({
16567							naturalWidthOld: currentHolder.data('naturalWidth'),
16568							naturalHeightOld: currentHolder.data('naturalHeight'),
16569							naturalWidth: newWidth,
16570							naturalHeight: newHeight
16571						});
16572					}
16573
16574					$.each(elements, function(key, val) {
16575						val.addClass('ilightbox-fullscreen');
16576					});
16577
16578					//Trigger the onEnterFullScreen callback
16579					if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui);
16580				} else {
16581					vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false;
16582					vars.overlay.css({
16583						opacity: iL.options.overlay.opacity
16584					});
16585
16586					$.each(hideElements, function(i, element) {
16587						element.show();
16588					});
16589
16590					vars.fullScreenButton.attr('title', opts.text.enterFullscreen);
16591
16592					currentHolder.data({
16593						naturalWidth: currentHolder.data('naturalWidthOld'),
16594						naturalHeight: currentHolder.data('naturalHeightOld'),
16595						naturalWidthOld: null,
16596						naturalHeightOld: null
16597					});
16598
16599					$.each(elements, function(key, val) {
16600						val.removeClass('ilightbox-fullscreen');
16601					});
16602
16603					//Trigger the onExitFullScreen callback
16604					if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui);
16605				}
16606			} else {
16607				if (!vars.isInFullScreen) vars.isInFullScreen = true;
16608				else vars.isInFullScreen = false;
16609			}
16610			iL.repositionPhoto(true);
16611		},
16612
16613		closeAction: function() {
16614			var iL = this,
16615				vars = iL.vars,
16616				opts = iL.options;
16617
16618			$win.unbind('.iLightBox');
16619			$doc.off('.iLightBox');
16620
16621			if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement);
16622
16623			$('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox');
16624
16625			if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() {
16626				vars.overlay.remove();
16627				vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox');
16628			});
16629			else {
16630				vars.overlay.remove();
16631				vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox');
16632			}
16633
16634			var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails];
16635
16636			$.each(fadeOuts, function(i, element) {
16637				element.removeAttr('style').remove();
16638			});
16639
16640			vars.dontGenerateThumbs = vars.isInFullScreen = false;
16641
16642			window.iLightBox = null;
16643
16644			if (opts.linkId) {
16645				vars.hashLock = true;
16646				removeHash();
16647				setTimeout(function() {
16648					vars.hashLock = false;
16649				}, 55);
16650			}
16651
16652			vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
16653
16654			//Trigger the onHide callback
16655			if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui);
16656		},
16657
16658		repositionPhoto: function() {
16659			var iL = this,
16660				vars = iL.vars,
16661				opts = iL.options,
16662				path = opts.path.toLowerCase(),
16663				viewport = getViewport(),
16664				winWidth = viewport.width,
16665				winHeight = viewport.height;
16666
16667			if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0;
16668
16669			var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()),
16670				thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)),
16671				width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)),
16672				height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)),
16673				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,
16674				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)));
16675
16676			var elObject = {
16677				type: 'current',
16678				width: width,
16679				height: height,
16680				item: iL.items[vars.current],
16681				offsetW: offsetW,
16682				offsetH: offsetH,
16683				thumbsOffsetW: thumbsOffsetW,
16684				thumbsOffsetH: thumbsOffsetH,
16685				animate: arguments.length,
16686				holder: vars.holder
16687			};
16688
16689			iL.repositionEl(elObject);
16690
16691			if (iL.items[vars.next]) {
16692				elObject = $.extend(elObject, {
16693					type: 'next',
16694					item: iL.items[vars.next],
16695					offsetX: opts.styles.nextOffsetX,
16696					offsetY: opts.styles.nextOffsetY,
16697					holder: vars.nextPhoto
16698				});
16699
16700				iL.repositionEl(elObject);
16701			}
16702
16703			if (iL.items[vars.prev]) {
16704				elObject = $.extend(elObject, {
16705					type: 'prev',
16706					item: iL.items[vars.prev],
16707					offsetX: opts.styles.nextOffsetX,
16708					offsetY: opts.styles.prevOffsetY,
16709					holder: vars.prevPhoto
16710				});
16711
16712				iL.repositionEl(elObject);
16713			}
16714
16715			var loaderCss = (path == "horizontal") ? {
16716				left: parseInt((width / 2) - (vars.loader.outerWidth() / 2))
16717			} : {
16718				top: parseInt((height / 2) - (vars.loader.outerHeight() / 2))
16719			};
16720			vars.loader.css(loaderCss);
16721		},
16722
16723		repositionEl: function(obj) {
16724			var iL = this,
16725				vars = iL.vars,
16726				opts = iL.options,
16727				path = opts.path.toLowerCase(),
16728				widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW),
16729				heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH),
16730				itemParent = obj.item,
16731				item = obj.item.options,
16732				holder = obj.holder,
16733				offsetX = obj.offsetX || 0,
16734				offsetY = obj.offsetY || 0,
16735				//Uncode change ##START##
16736				toolbarHeight = $('.ilightbox-inner-toolbar', holder).length ? parseInt( $('.ilightbox-inner-toolbar', holder).outerHeight() ) : 0,
16737				//Uncode change ##END##
16738				thumbsOffsetW = obj.thumbsOffsetW,
16739				thumbsOffsetH = obj.thumbsOffsetH;
16740
16741			if (obj.type == 'current') {
16742				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);
16743				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);
16744			} else {
16745				if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width;
16746				if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height;
16747			}
16748
16749
16750			//Uncode change ##START##
16751			heightAvail = parseInt(heightAvail - toolbarHeight);
16752			// heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight());
16753			//Uncode change ##END##
16754
16755			var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'),
16756				height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight');
16757
16758			var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? {
16759					width: width,
16760					height: height
16761				} : iL.getNewDimenstions(widthAvail, heightAvail, width, height)),
16762				newDims = $.extend({}, dims, {});
16763
16764			if (obj.type == 'prev' || obj.type == 'next')
16765				width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)),
16766				height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale));
16767			else
16768				width = dims.width,
16769				height = dims.height;
16770
16771			var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2),
16772				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);
16773
16774			switch (obj.type) {
16775				case 'current':
16776					var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)),
16777						left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2));
16778					break;
16779
16780				case 'next':
16781					var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)),
16782						left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2));
16783					break;
16784
16785				case 'prev':
16786					var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)),
16787						left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2));
16788					break;
16789			}
16790
16791			holder.data('offset', {
16792				top: top,
16793				left: left,
16794				newDims: newDims,
16795				diff: {
16796					W: widthDiff,
16797					H: heightDiff
16798				},
16799				thumbsOffset: {
16800					W: thumbsOffsetW,
16801					H: thumbsOffsetH
16802				},
16803				object: obj
16804			});
16805
16806			var opacityMobile;
16807			if ( isMobile ) {
16808				opacityMobile = {
16809					opacity: 1,
16810					top: top,
16811					left: left
16812				};
16813			} else {
16814				opacityMobile = {
16815					top: top,
16816					left: left
16817				};
16818			}
16819
16820			if (obj.animate > 0 && opts.effects.reposition) {
16821				holder.css(transform, gpuAcceleration).stop().animate(
16822					opacityMobile,
16823					opts.effects.repositionSpeed, 'easeOutCirc', function() {
16824					holder.css(transform, '');
16825				});
16826				$('div.ilightbox-container', holder).stop().animate({
16827					width: width,
16828					height: height
16829				}, opts.effects.repositionSpeed, 'easeOutCirc');
16830				$('div.ilightbox-inner-toolbar', holder).stop().animate({
16831					width: width
16832				}, opts.effects.repositionSpeed, 'easeOutCirc', function() {
16833					$(this).css('overflow', 'visible');
16834				});
16835			} else {
16836				holder.css(opacityMobile);
16837				$('div.ilightbox-container', holder).css({
16838					width: width,
16839					height: height
16840				});
16841				$('div.ilightbox-inner-toolbar', holder).css({
16842					width: width
16843				});
16844			}
16845		},
16846
16847
16848		resume: function(priority) {
16849			var iL = this,
16850				vars = iL.vars,
16851				opts = iL.options;
16852
16853			if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) {
16854				return;
16855			}
16856
16857			vars.isPaused = 0;
16858
16859			if (vars.cycleID) {
16860				vars.cycleID = clearTimeout(vars.cycleID);
16861			}
16862
16863			vars.cycleID = setTimeout(function() {
16864				if (vars.current == vars.total - 1) iL.goTo(0);
16865				else iL.moveTo('next');
16866			}, opts.slideshow.pauseTime);
16867		},
16868
16869		pause: function(priority) {
16870			var iL = this,
16871				vars = iL.vars,
16872				opts = iL.options;
16873
16874			if (priority < vars.isPaused) {
16875				return;
16876			}
16877
16878			vars.isPaused = priority || 100;
16879
16880			if (vars.cycleID) {
16881				vars.cycleID = clearTimeout(vars.cycleID);
16882			}
16883		},
16884
16885		resetCycle: function() {
16886			var iL = this,
16887				vars = iL.vars,
16888				opts = iL.options;
16889
16890			if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) {
16891				iL.resume();
16892			}
16893		},
16894
16895		getNewDimenstions: function(width, height, width_old, height_old, thumb) {
16896			var iL = this;
16897
16898			if (!width) factor = height / height_old;
16899			else if (!height) factor = width / width_old;
16900			else factor = min(width / width_old, height / height_old);
16901
16902			if (!thumb) {
16903				if (factor > iL.options.maxScale) factor = iL.options.maxScale;
16904				else if (factor < iL.options.minScale) factor = iL.options.minScale;
16905			}
16906
16907			var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width,
16908				final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height;
16909
16910			return {
16911				width: final_width,
16912				height: final_height,
16913				ratio: factor
16914			};
16915		},
16916
16917		setOption: function(options) {
16918			var iL = this;
16919
16920			iL.options = $.extend(true, iL.options, options || {});
16921			iL.refresh();
16922		},
16923
16924		availPlugins: function() {
16925			var iL = this,
16926				testEl = document.createElement("video");
16927
16928			iL.plugins = {
16929				flash: !isMobile,
16930				quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false,
16931				html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')),
16932				html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')),
16933				html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')),
16934				html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, ''))
16935			};
16936		},
16937
16938		addContent: function(element, obj) {
16939			var iL = this,
16940				el;
16941
16942			switch (obj.type) {
16943				case 'video':
16944					var HTML5 = false,
16945						videoType = obj.videoType,
16946						html5video = obj.options.html5video;
16947
16948					if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264)
16949						obj.ext = 'mp4',
16950						obj.URL = html5video.h264 || obj.URL;
16951					else if (html5video.webm && iL.plugins.html5WebM)
16952						obj.ext = 'webm',
16953						obj.URL = html5video.webm || obj.URL;
16954					else if (html5video.ogg && iL.plugins.html5Vorbis)
16955						obj.ext = 'ogv',
16956						obj.URL = html5video.ogg || obj.URL;
16957
16958					if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4";
16959					else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm";
16960					else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg";
16961					else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime";
16962
16963					if (HTML5) {
16964						el = $('<video />
16964', {
16965							"width": "100%",
16966							"height": "100%",
16967							"preload": html5video.preload,
16968							"autoplay": html5video.autoplay,
16969							"loop": html5video.loop,
16970							"poster": html5video.poster,
16971							"controls": html5video.controls,
16972							"controlslist": "nodownload"
16973						}).append($('<source />', {
16974							"src": obj.URL,
16975							"type": videoType
16976						}));
16977					} else {
16978						if (!iL.plugins.quicktime) el = $('<span />', {
16979							"class": "ilightbox-alert",
16980							html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime')
16981						});
16982						else {
16983
16984							el = $('<object />', {
16985								"type": "video/quicktime",
16986								"pluginspage": pluginspages.quicktime
16987							}).attr({
16988								"data": obj.URL,
16989								"width": "100%",
16990								"height": "100%"
16991							}).append($('<param />', {
16992								"name": "src",
16993								"value": obj.URL
16994							})).append($('<param />', {
16995								"name": "autoplay",
16996								"value": "false"
16997							})).append($('<param />', {
16998								"name": "loop",
16999								"value": "false"
17000							})).append($('<param />', {
17001								"name": "scale",
17002								"value": "tofit"
17003							}));
17004
17005							if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false');
17006						}
17007					}
17008
17009					break;
17010
17011				case 'flash':
17012					if (!iL.plugins.flash) el = $('<span />', {
17013						"class": "ilightbox-alert",
17014						html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player')
17015					});
17016					else {
17017						var flashvars = "",
17018							i = 0;
17019
17020						if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) {
17021							if (i != 0) flashvars += "&";
17022							flashvars += k + "=" + encodeURIComponent(v);
17023							i++;
17024						});
17025						else flashvars = null;
17026
17027						el = $('<embed />').attr({
17028							"type": "application/x-shockwave-flash",
17029							"src": obj.URL,
17030							"width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%",
17031							"height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%",
17032							"quality": "high",
17033							"bgcolor": "#000000",
17034							"play": "true",
17035							"loop": "true",
17036							"menu": "true",
17037							"wmode": "transparent",
17038							"scale": "showall",
17039							"allowScriptAccess": "always",
17040							"allowFullScreen": "true",
17041							"flashvars": flashvars,
17042							"fullscreen": "yes"
17043						});
17044					}
17045
17046					break;
17047
17048				case 'iframe':
17049					el = $('<iframe />').attr({
17050						"width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%",
17051						"height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%",
17052						src: obj.URL,
17053						frameborder: 0,
17054						'hspace': 0,
17055						'vspace': 0,
17056						'scrolling': supportTouch ? 'auto' : 'scroll',
17057						'webkitAllowFullScreen': '',
17058						'mozallowfullscreen': '',
17059						'allowFullScreen': ''
17060					});
17061
17062					break;
17063
17064				case 'inline':
17065					el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true));
17066
17067					break;
17068
17069				case 'html':
17070					var object = obj.URL,
17071						el;
17072
17073					if (object[0].nodeName) {
17074						el = $('<div class="ilightbox-wrapper"></div>').html(object);
17075					} else {
17076						var dom = $(obj.URL),
17077							html = (dom.selector) ? $('<div>' + dom + '</div>') : dom;
17078						el = $('<div class="ilightbox-wrapper"></div>').html(html);
17079					}
17080
17081					break;
17082			}
17083
17084			$('div.ilightbox-container', element).empty().html(el);
17085
17086			// For fixing Chrome about just playing the video for first time
17087			if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() {
17088				var src = el[0].currentSrc + '?' + floor(random() * 30000);
17089				el[0].currentSrc = src;
17090				el[0].src = src;
17091			});
17092
17093			return el;
17094		},
17095
17096		ogpRecognition: function(obj, callback) {
17097			var iL = this,
17098				url = obj.URL;
17099
17100			iL.showLoader();
17101			doAjax(url, function(data) {
17102				iL.hideLoader();
17103				if (data) {
17104					var object = new Object();
17105
17106					object.length = false,
17107					object.url = data.url;
17108
17109					if (data.status == 200) {
17110						var result = data.results,
17111							type = result.type,
17112							source = result.source;
17113
17114						object.source = source.src,
17115						object.width = source.width && parseInt(source.width) || 0,
17116						object.height = source.height && parseInt(source.height) || 0,
17117						object.type = type,
17118						object.thumbnail = source.thumbnail || result.images && result.images[0],
17119						object.html5video = result.html5video || {},
17120						object.length = true;
17121
17122						if (source.type == 'application/x-shockwave-flash') object.type = "flash";
17123						else if (source.type.indexOf("video/") != -1) object.type = "video";
17124						else if (source.type.indexOf("/html") != -1) object.type = "iframe";
17125						else if (source.type.indexOf("image/") != -1) object.type = "image";
17126
17127					} else if (typeof data.response != 'undefined')
17128						throw data.response;
17129
17130					callback.call(this, object.length ? object : false);
17131				}
17132			});
17133		},
17134
17135		hashChangeHandler: function(url) {
17136			var iL = this,
17137				vars = iL.vars,
17138				opts = iL.options,
17139				URL = url || window.location.href,
17140				hash = parseURI(URL).hash,
17141				split = hash.split('/'),
17142				index = split[1];
17143
17144			if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return;
17145
17146			if (index) {
17147				var target = split[1] || 0;
17148				if (iL.items[target]) {
17149					var overlay = $('.ilightbox-overlay');
17150					if (overlay.length && overlay.attr('linkid') == opts.linkId) {
17151						iL.goTo(target);
17152					} else {
17153						iL.itemsObject[target].trigger(ishybrid ? "itap click" : supportTouch ? 'itap' : 'click');
17154						//iL.goTo(target);
17155					}
17156				} else {
17157					var overlay = $('.ilightbox-overlay');
17158					if (overlay.length) iL.closeAction();
17159				}
17160			} else {
17161				var overlay = $('.ilightbox-overlay');
17162				if (overlay.length) iL.closeAction();
17163			}
17164		}
17165	};
17166
17167	/**
17168	 * Parse style to pixels.
17169	 *
17170	 * @param {Object}   $element   jQuery object with element.
17171	 * @param {Property} property   CSS property to get the pixels from.
17172	 *
17173	 * @return {Int}
17174	 */
17175	function getPixel($element, property) {
17176		return parseInt($element.css(property), 10) || 0;
17177	}
17178
17179	/**
17180	 * Make sure that number is within the limits.
17181	 *
17182	 * @param {Number} number
17183	 * @param {Number} min
17184	 * @param {Number} max
17185	 *
17186	 * @return {Number}
17187	 */
17188	function within(number, min, max) {
17189		return number < min ? min : number > max ? max : number;
17190	}
17191
17192	/**
17193	 * Get viewport/window size (width and height).
17194	 *
17195	 * @return {Object}
17196	 */
17197	function getViewport() {
17198		var e = window,
17199			a = 'inner';
17200		if (!('innerWidth' in window)) {
17201			a = 'client';
17202			e = document.documentElement || document.body;
17203		}
17204		return {
17205			width: e[a + 'Width'],
17206			height: e[a + 'Height']
17207		}
17208	}
17209
17210	/**
17211	 * Remove hash tag from the URL
17212	 *
17213	 * @return {Void}
17214	 */
17215	function removeHash() {
17216		var scroll = getScrollXY();
17217
17218		//UNCODE change
17219		// window.location.hash = "";
17220		// history.pushState("", document.title, window.location.pathname + window.location.search);
17221		history.replaceState({}, document.title, window.location.pathname + window.location.search);
17222
17223		// Restore the scroll offset, should be flicker free
17224		window.scrollTo(scroll.x, scroll.y);
17225	}
17226
17227	/**
17228	 * Do the ajax requests with callback.
17229	 *
17230	 * @param {String}   url
17231	 * @param {Function} callback
17232	 *
17233	 * @return {Void}
17234	 */
17235	function doAjax(url, callback) {
17236		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');
17237		$.ajax({
17238			url: url,
17239			dataType: 'jsonp'
17240		});
17241
17242		iLCallback = function(data) {
17243			callback.call(this, data);
17244		};
17245	}
17246
17247	/**
17248	 * Find image from DOM elements
17249	 *
17250	 * @param {Element} element
17251	 *
17252	 * @return {Void}
17253	 */
17254	function findImageInElement(element) {
17255		var elements = $('*', element),
17256			imagesArr = new Array();
17257
17258		elements.each(function() {
17259			var url = "",
17260				element = this;
17261
17262			if ($(element).css("background-image") != "none") {
17263				url = $(element).css("background-image");
17264			} else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") {
17265				url = $(element).attr("src");
17266			}
17267
17268			if (url.indexOf("gradient") == -1) {
17269				url = url.replace(/url\(\"/g, "");
17270				url = url.replace(/url\(/g, "");
17271				url = url.replace(/\"\)/g, "");
17272				url = url.replace(/\)/g, "");
17273
17274				var urls = url.split(",");
17275
17276				for (var i = 0; i < urls.length; i++) {
17277					if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) {
17278						var extra = "";
17279						if (browser.msie && browser.version < 9) {
17280							extra = "?" + floor(random() * 3000);
17281						}
17282						imagesArr.push(urls[i] + extra);
17283					}
17284				}
17285			}
17286		});
17287
17288		return imagesArr;
17289	}
17290
17291	/**
17292	 * Get file extension.
17293	 *
17294	 * @param {String} URL
17295	 *
17296	 * @return {String}
17297	 */
17298	function getExtension(URL) {
17299		if (URL !== null) {
17300			//UNCODE: fix issue to detect media type with query strings
17301			var ext = URL.indexOf('?') !== -1 ? URL.split('?')[0] : URL;
17302			ext = ext.split('.').pop().toLowerCase();
17303
17304			return ext;
17305		}
17306	}
17307
17308	/**
17309	 * Get type via extension.
17310	 *
17311	 * @param {String} URL
17312	 *
17313	 * @return {String}
17314	 */
17315	function getTypeByExtension(URL) {
17316		var type,
17317			ext = getExtension(URL);
17318
17319		//Uncode addition ##START##
17320		if (URL == undefined) {
17321			return false;
17322		}
17323		//Uncode addition ##END##
17324
17325		if (extensions.image.indexOf(ext) !== -1) type = 'image';
17326		else if (extensions.flash.indexOf(ext) !== -1) type = 'flash';
17327		else if (extensions.video.indexOf(ext) !== -1) type = 'video';
17328		else if (ext.substring(0, 1) == "#") type = 'inline'; //Uncode addition
17329		else type = 'iframe';
17330
17331		return type;
17332	}
17333
17334	/**
17335	 * Return value from percent of a number.
17336	 *
17337	 * @param {Number} percent
17338	 * @param {Number} total
17339	 *
17340	 * @return {Number}
17341	 */
17342	function percentToValue(percent, total) {
17343		return parseInt((total / 100) * percent);
17344	}
17345
17346	/**
17347	 * A JavaScript equivalent of PHP’s parse_url.
17348	 *
17349	 * @param {String} url           The URL to parse.
17350	 *
17351	 * @return {Mixed}
17352	 */
17353	function parseURI(url) {
17354		var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
17355		// authority = '//' + user + ':' + pass '@' + hostname + ':' port
17356		return (m ? {
17357			href: m[0] || '',
17358			protocol: m[1] || '',
17359			authority: m[2] || '',
17360			host: m[3] || '',
17361			hostname: m[4] || '',
17362			port: m[5] || '',
17363			pathname: m[6] || '',
17364			search: m[7] || '',
17365			hash: m[8] || ''
17366		} : null);
17367	}
17368
17369	/**
17370	 * Gets the absolute URI.
17371	 *
17372	 * @param {String} href     The relative URL.
17373	 * @param {String} base     The base URL.
17374	 *
17375	 * @return {String}         The absolute URL.
17376	 */
17377	function absolutizeURI(base, href) { // RFC 3986
17378		var iL = this;
17379
17380		function removeDotSegments(input) {
17381			var output = [];
17382			input.replace(/^(\.\.?(\/|$))+/, '')
17383				.replace(/\/(\.(\/|$))+/g, '/')
17384				.replace(/\/\.\.$/, '/../')
17385				.replace(/\/?[^\/]*/g, function(p) {
17386					if (p === '/..') {
17387						output.pop();
17388					} else {
17389						output.push(p);
17390					}
17391				});
17392			return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
17393		}
17394
17395		href = parseURI(href || '');
17396		base = parseURI(base || '');
17397
17398		return !href || !base ? null : (href.protocol || base.protocol) +
17399			(href.protocol || href.authority ? href.authority : base.authority) +
17400			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)) +
17401			(href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
17402			href.hash;
17403	}
17404
17405	/**
17406	 * A JavaScript equivalent of PHP’s version_compare.
17407	 *
17408	 * @param {String} v1
17409	 * @param {String} v2
17410	 * @param {String} operator
17411	 *
17412	 * @return {Boolean}
17413	 */
17414	function version_compare(v1, v2, operator) {
17415		this.php_js = this.php_js || {};
17416		this.php_js.ENV = this.php_js.ENV || {};
17417		var i = 0,
17418			x = 0,
17419			compare = 0,
17420			vm = {
17421				'dev': -6,
17422				'alpha': -5,
17423				'a': -5,
17424				'beta': -4,
17425				'b': -4,
17426				'RC': -3,
17427				'rc': -3,
17428				'#': -2,
17429				'p': 1,
17430				'pl': 1
17431			},
17432			prepVersion = function(v) {
17433				v = ('' + v).replace(/[_\-+]/g, '.');
17434				v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.');
17435				return (!v.length ? [-8] : v.split('.'));
17436			},
17437			numVersion = function(v) {
17438				return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
17439			};
17440		v1 = prepVersion(v1);
17441		v2 = prepVersion(v2);
17442		x = max(v1.length, v2.length);
17443		for (i = 0; i < x; i++) {
17444			if (v1[i] == v2[i]) {
17445				continue;
17446			}
17447			v1[i] = numVersion(v1[i]);
17448			v2[i] = numVersion(v2[i]);
17449			if (v1[i] < v2[i]) {
17450				compare = -1;
17451				break;
17452			} else if (v1[i] > v2[i]) {
17453				compare = 1;
17454				break;
17455			}
17456		}
17457		if (!operator) {
17458			return compare;
17459		}
17460
17461		switch (operator) {
17462			case '>':
17463			case 'gt':
17464				return (compare > 0);
17465			case '>=':
17466			case 'ge':
17467				return (compare >= 0);
17468			case '<=':
17469			case 'le':
17470				return (compare <= 0);
17471			case '==':
17472			case '=':
17473			case 'eq':
17474				return (compare === 0);
17475			case '<>':
17476			case '!=':
17477			case 'ne':
17478				return (compare !== 0);
17479			case '':
17480			case '<':
17481			case 'lt':
17482				return (compare < 0);
17483			default:
17484				return null;
17485		}
17486	}
17487
17488
17489	// Begin the iLightBox plugin
17490	$.fn.iLightBox = function() {
17491
17492		var args = arguments,
17493			opt = ($.isPlainObject(args[0])) ? args[0] : args[1],
17494			items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1];
17495
17496		if (!opt) opt = {};
17497
17498		// Default options. Play carefully.
17499		var options = $.extend(true, {
17500			attr: 'href',
17501			path: 'vertical',
17502			skin: 'dark',
17503			linkId: false,
17504			infinite: false,
17505			startFrom: 0,
17506			randomStart: false,
17507			keepAspectRatio: true,
17508			maxScale: 1,
17509			minScale: .2,
17510			innerToolbar: false,
17511			smartRecognition: false,
17512			mobileOptimizer: true,
17513			fullAlone: true,
17514			fullViewPort: null,
17515			fullStretchTypes: 'flash, video',
17516			overlay: {
17517				blur: true,
17518				opacity: .85
17519			},
17520			controls: {
17521				arrows: false,
17522				slideshow: false,
17523				toolbar: true,
17524				fullscreen: true,
17525				thumbnail: true,
17526				keyboard: true,
17527				mousewheel: true,
17528				swipe: true
17529			},
17530			keyboard: {
17531				left: true, // previous
17532				right: true, // next
17533				up: true, // previous
17534				down: true, // next
17535				esc: true, // close
17536				shift_enter: true // fullscreen
17537			},
17538			show: {
17539				effect: true,
17540				speed: 300,
17541				title: true
17542			},
17543			hide: {
17544				effect: true,
17545				speed: 300
17546			},
17547			caption: {
17548				start: true,
17549				show: 'mouseenter',
17550				hide: 'mouseleave'
17551			},
17552			social: {
17553				start: true,
17554				show: 'mouseenter',
17555				hide: 'mouseleave',
17556				buttons: false
17557			},
17558			styles: {
17559				pageOffsetX: 0,
17560				pageOffsetY: 0,
17561				nextOffsetX: 45,
17562				nextOffsetY: 0,
17563				nextOpacity: 1,
17564				nextScale: 1,
17565				prevOffsetX: 45,
17566				prevOffsetY: 0,
17567				prevOpacity: 1,
17568				prevScale: 1
17569			},
17570			thumbnails: {
17571				maxWidth: 120,
17572				maxHeight: 80,
17573				normalOpacity: 1,
17574				activeOpacity: .6
17575			},
17576			effects: {
17577				reposition: true,
17578				repositionSpeed: 200,
17579				switchSpeed: 500,
17580				loadedFadeSpeed: 180,
17581				fadeSpeed: 200
17582			},
17583			slideshow: {
17584				pauseTime: 5000,
17585				pauseOnHover: false,
17586				startPaused: true
17587			},
17588			text: {
17589				close: "Press Esc to close",
17590				enterFullscreen: "Enter Fullscreen (Shift+Enter)",
17591				exitFullscreen: "Exit Fullscreen (Shift+Enter)",
17592				slideShow: "Slideshow",
17593				next: "Next",
17594				previous: "Previous"
17595			},
17596			errors: {
17597				loadImage: "An error occurred when trying to load photo.",
17598				loadContents: "An error occurred when trying to load contents.",
17599				missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>."
17600			},
17601			ajaxSetup: {
17602				url: '',
17603				beforeSend: function(jqXHR, settings) {},
17604				cache: false,
17605				complete: function(jqXHR, textStatus) {},
17606				crossDomain: false,
17607				error: function(jqXHR, textStatus, errorThrown) {},
17608				success: function(data, textStatus, jqXHR) {},
17609				global: true,
17610				ifModified: false,
17611				username: null,
17612				password: null,
17613				type: 'GET'
17614			},
17615			callback: {}
17616		}, opt);
17617
17618		var instant = ($.isArray(items) || typeof items == 'string') ? true : false;
17619
17620		items = $.isArray(items) ? items : new Array();
17621
17622		if (typeof args[0] == 'string') items[0] = args[0];
17623
17624		if (version_compare($.fn.jquery, '1.8', '>=')) {
17625			var iLB = new iLightBox($(this), options, items, instant);
17626			return {
17627				close: function() {
17628					iLB.closeAction();
17629				},
17630				fullscreen: function() {
17631					iLB.fullScreenAction();
17632				},
17633				moveNext: function() {
17634					iLB.moveTo('next');
17635				},
17636				movePrev: function() {
17637					iLB.moveTo('prev');
17638				},
17639				goTo: function(index) {
17640					iLB.goTo(index);
17641				},
17642				refresh: function() {
17643					iLB.refresh();
17644				},
17645				reposition: function() {
17646					(arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto();
17647				},
17648				setOption: function(options) {
17649					iLB.setOption(options);
17650				},
17651				destroy: function() {
17652					iLB.closeAction();
17653					iLB.dispatchItemsEvents();
17654				}
17655			};
17656		} else {
17657			throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+";
17658		}
17659
17660	};
17661
17662
17663	$.iLightBox = function() {
17664		return $.fn.iLightBox(arguments[0], arguments[1]);
17665	};
17666
17667	function getScrollXY() {
17668		var scrOfX = 0,
17669			scrOfY = 0;
17670		if (typeof(window.pageYOffset) == 'number') {
17671			//Netscape compliant
17672			scrOfY = window.pageYOffset;
17673			scrOfX = window.pageXOffset;
17674		} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
17675			//DOM compliant
17676			scrOfY = document.body.scrollTop;
17677			scrOfX = document.body.scrollLeft;
17678		} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
17679			//IE6 standards compliant mode
17680			scrOfY = document.documentElement.scrollTop;
17681			scrOfX = document.documentElement.scrollLeft;
17682		}
17683		return {
17684			x: scrOfX,
17685			y: scrOfY
17686		};
17687	}
17688
17689	(function() {
17690		// add new event shortcuts
17691		$.each(("touchstart touchmove touchend " +
17692			"tap taphold " +
17693			"swipe swipeleft swiperight " +
17694			"scrollstart scrollstop").split(" "), function(i, name) {
17695
17696			$.fn[name] = function(fn) {
17697				return fn ? this.bind(name, fn) : this.trigger(name);
17698			};
17699
17700			// jQuery < 1.8
17701			// if ($.attrFn) {
17702			// 	$.attrFn[name] = true;
17703			// }
17704		});
17705
17706		var tapSettings = {
17707			startEvent: 'touchstart.iTap',
17708			endEvent: 'touchend.iTap'
17709		};
17710
17711		// tap Event:
17712		$.event.special.itap = {
17713			setup: function() {
17714
17715				var self = this,
17716					$self = $(this),
17717					start, stop;
17718
17719				$self.bind(tapSettings.startEvent, function(event) {
17720					start = getScrollXY();
17721
17722					$self.one(tapSettings.endEvent, function(event) {
17723						stop = getScrollXY();
17724
17725						var orgEvent = event || window.event;
17726						event = $.event.fix(orgEvent);
17727						event.type = "itap";
17728
17729						if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event);
17730
17731						start = stop = undefined;
17732					});
17733				});
17734			},
17735
17736			teardown: function() {
17737				$(this).unbind(tapSettings.startEvent);
17738			}
17739		};
17740	}());
17741
17742
17743	//Fullscreen API
17744	(function() {
17745		fullScreenApi = {
17746				supportsFullScreen: false,
17747				isFullScreen: function() {
17748					return false;
17749				},
17750				requestFullScreen: function() {},
17751				cancelFullScreen: function() {},
17752				fullScreenEventName: '',
17753				prefix: ''
17754			},
17755			browserPrefixes = 'webkit moz o ms khtml'.split(' ');
17756
17757		// check for native support
17758		if (typeof document.cancelFullScreen != 'undefined') {
17759			fullScreenApi.supportsFullScreen = true;
17760		} else {
17761			// check for fullscreen support by vendor prefix
17762			for (var i = 0, il = browserPrefixes.length; i < il; i++) {
17763				fullScreenApi.prefix = browserPrefixes[i];
17764
17765				if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') {
17766					fullScreenApi.supportsFullScreen = true;
17767
17768					break;
17769				}
17770			}
17771		}
17772
17773		// update methods to do something useful
17774		if (fullScreenApi.supportsFullScreen) {
17775			fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
17776
17777			fullScreenApi.isFullScreen = function() {
17778				switch (this.prefix) {
17779					case '':
17780						return document.fullScreen;
17781					case 'webkit':
17782						return document.webkitIsFullScreen;
17783					default:
17784						return document[this.prefix + 'FullScreen'];
17785				}
17786			}
17787			fullScreenApi.requestFullScreen = function(el) {
17788				return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
17789			}
17790			fullScreenApi.cancelFullScreen = function(el) {
17791				return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
17792			}
17793		}
17794	}());
17795
17796	// Browser detect
17797	(function() {
17798		function uaMatch(ua) {
17799			ua = ua.toLowerCase();
17800
17801			var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
17802				/(webkit)[ \/]([\w.]+)/.exec(ua) ||
17803				/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
17804				/(msie) ([\w.]+)/.exec(ua) ||
17805				ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
17806
17807			return {
17808				browser: match[1] || "",
17809				version: match[2] || "0"
17810			};
17811		}
17812
17813		var matched = uaMatch(navigator.userAgent);
17814		browser = {};
17815
17816		if (matched.browser) {
17817			browser[matched.browser] = true;
17818			browser.version = matched.version;
17819		}
17820
17821		// Chrome is Webkit, but Webkit is also Safari.
17822		if (browser.chrome) {
17823			browser.webkit = true;
17824		} else if (browser.webkit) {
17825			browser.safari = true;
17826		}
17827	}());
17828
17829	// Feature detects
17830	(function() {
17831		var prefixes = ['', 'webkit', 'moz', 'ms', 'o'];
17832		var el = document.createElement('div');
17833
17834		function testProp(prop) {
17835			for (var p = 0, pl = prefixes.length; p < pl; p++) {
17836				var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop;
17837				if (el.style[prefixedProp] !== undefined) {
17838					return prefixedProp;
17839				}
17840			}
17841		}
17842
17843		// Global support indicators
17844		transform = testProp('transform') || '';
17845		gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : '';
17846	}());
17847
17848
17849	/*
17850		PluginDetect v0.7.9
17851		www.pinlady.net/PluginDetect/license/
17852		[ getVersion onWindowLoaded BetterIE ]
17853		[ Flash QuickTime Shockwave ]
17854	*/
17855	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;
17855d++){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);
17855d.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)}
17855c.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;
17855if(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();
17856
17857	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)};
17858
17859
17860	/*
17861		jQuery hashchange event v1.3
17862		https://github.com/cowboy/jquery-hashchange
17863		Copyright (c) 2010 "Cowboy" Ben Alman
17864		Dual licensed under the MIT and GPL licenses.
17865	*/
17866	(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=
17867	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||
17868	"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;
17868a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})();
17869
17870	if (!Array.prototype.filter) {
17871		Array.prototype.filter = function(fun /*, thisp */ ) {
17872			"use strict";
17873
17874			if (this == null)
17875				throw new TypeError();
17876
17877			var t = Object(this);
17878			var len = t.length >>> 0;
17879			if (typeof fun != "function")
17880				throw new TypeError();
17881
17882			var res = [];
17883			var thisp = arguments[1];
17884			for (var i = 0; i < len; i++) {
17885				if (i in t) {
17886					var val = t[i]; // in case fun mutates this
17887					if (fun.call(thisp, val, i, t))
17888						res.push(val);
17889				}
17890			}
17891
17892			return res;
17893		};
17894	}
17895
17896	if (!Array.prototype.indexOf) {
17897		Array.prototype.indexOf = function(searchElement, fromIndex) {
17898			var k;
17899
17900			if (this == null) {
17901				throw new TypeError('"this" is null or not defined');
17902			}
17903
17904			var O = Object(this);
17905
17906			var len = O.length >>> 0;
17907
17908			if (len === 0) {
17909				return -1;
17910			}
17911
17912			var n = +fromIndex || 0;
17913
17914			if (abs(n) === Infinity) {
17915				n = 0;
17916			}
17917
17918			if (n >= len) {
17919				return -1;
17920			}
17921
17922			k = max(n >= 0 ? n : len - abs(n), 0);
17923
17924			while (k < len) {
17925				var kValue;
17926				if (k in O && O[k] === searchElement) {
17927					return k;
17928				}
17929				k++;
17930			}
17931			return -1;
17932		};
17933	}
17934
17935	if (!Array.prototype.lastIndexOf) {
17936		Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) {
17937			"use strict";
17938
17939			if (this == null)
17940				throw new TypeError();
17941
17942			var t = Object(this);
17943			var len = t.length >>> 0;
17944			if (len === 0)
17945				return -1;
17946
17947			var n = len;
17948			if (arguments.length > 1) {
17949				n = Number(arguments[1]);
17950				if (n != n)
17951					n = 0;
17952				else if (n != 0 && n != (1 / 0) && n != -(1 / 0))
17953					n = (n > 0 || -1) * floor(abs(n));
17954			}
17955
17956			var k = n >= 0 ? min(n, len - 1) : len - abs(n);
17957
17958			for (; k >= 0; k--) {
17959				if (k in t && t[k] === searchElement)
17960					return k;
17961			}
17962			return -1;
17963		};
17964	}
17965})(jQuery, this);
17966
17967/*!
17968 * lightgallery | 2.5.0 | June 13th 2022
17969 * http://www.lightgalleryjs.com/
17970 * Copyright (c) 2020 Sachin Neravath;
17971 * @license GPLv3
17972 */
17973
17974(function (global, factory) {
17975	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
17976	typeof define === 'function' && define.amd ? define(factory) :
17977	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lightGallery = factory());
17978}(this, (function () { 'use strict';
17979
17980	/*! *****************************************************************************
17981	Copyright (c) Microsoft Corporation.
17982
17983	Permission to use, copy, modify, and/or distribute this software for any
17984	purpose with or without fee is hereby granted.
17985
17986	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
17987	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17988	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
17989	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17990	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17991	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17992	PERFORMANCE OF THIS SOFTWARE.
17993	***************************************************************************** */
17994
17995	var __assign = function() {
17996		__assign = Object.assign || function __assign(t) {
17997			for (var s, i = 1, n = arguments.length; i < n; i++) {
17998				s = arguments[i];
17999				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
18000			}
18001			return t;
18002		};
18003		return __assign.apply(this, arguments);
18004	};
18005
18006	function __spreadArrays() {
18007		for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
18008		for (var r = Array(s), k = 0, i = 0; i < il; i++)
18009			for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
18010				r[k] = a[j];
18011		return r;
18012	}
18013
18014	/**
18015	 * List of lightGallery events
18016	 * All events should be documented here
18017	 * Below interfaces are used to build the website documentations
18018	 * */
18019	var lGEvents = {
18020		afterAppendSlide: 'lgAfterAppendSlide',
18021		init: 'lgInit',
18022		hasVideo: 'lgHasVideo',
18023		containerResize: 'lgContainerResize',
18024		updateSlides: 'lgUpdateSlides',
18025		afterAppendSubHtml: 'lgAfterAppendSubHtml',
18026		beforeOpen: 'lgBeforeOpen',
18027		afterOpen: 'lgAfterOpen',
18028		slideItemLoad: 'lgSlideItemLoad',
18029		beforeSlide: 'lgBeforeSlide',
18030		afterSlide: 'lgAfterSlide',
18031		posterClick: 'lgPosterClick',
18032		dragStart: 'lgDragStart',
18033		dragMove: 'lgDragMove',
18034		dragEnd: 'lgDragEnd',
18035		beforeNextSlide: 'lgBeforeNextSlide',
18036		beforePrevSlide: 'lgBeforePrevSlide',
18037		beforeClose: 'lgBeforeClose',
18038		afterClose: 'lgAfterClose',
18039		rotateLeft: 'lgRotateLeft',
18040		rotateRight: 'lgRotateRight',
18041		flipHorizontal: 'lgFlipHorizontal',
18042		flipVertical: 'lgFlipVertical',
18043		autoplay: 'lgAutoplay',
18044		autoplayStart: 'lgAutoplayStart',
18045		autoplayStop: 'lgAutoplayStop',
18046	};
18047
18048	var lightGalleryCoreSettings = {
18049		mode: 'lg-slide',
18050		easing: 'ease',
18051		speed: 400,
18052		licenseKey: '0000-0000-000-0000',
18053		height: '100%',
18054		width: '100%',
18055		addClass: '',
18056		startClass: 'lg-start-zoom',
18057		backdropDuration: 300,
18058		container: '',
18059		startAnimationDuration: 400,
18060		zoomFromOrigin: true,
18061		hideBarsDelay: 0,
18062		showBarsAfter: 10000,
18063		slideDelay: 0,
18064		supportLegacyBrowser: true,
18065		allowMediaOverlap: false,
18066		videoMaxSize: '1280-720',
18067		loadYouTubePoster: true,
18068		defaultCaptionHeight: 0,
18069		ariaLabelledby: '',
18070		ariaDescribedby: '',
18071		resetScrollPosition: true,
18072		hideScrollbar: false,
18073		closable: true,
18074		swipeToClose: true,
18075		closeOnTap: true,
18076		showCloseIcon: true,
18077		showMaximizeIcon: false,
18078		loop: true,
18079		escKey: true,
18080		keyPress: true,
18081		trapFocus: true,
18082		controls: true,
18083		slideEndAnimation: true,
18084		hideControlOnEnd: false,
vendor: 17,869 bytes, lines 18085-18704
18085		mousewheel: false,
18086		getCaptionFromTitleOrAlt: true,
18087		appendSubHtmlTo: '.lg-sub-html',
18088		subHtmlSelectorRelative: false,
18089		preload: 2,
18090		numberOfSlideItemsInDom: 10,
18091		selector: '',
18092		selectWithin: '',
18093		nextHtml: '',
18094		prevHtml: '',
18095		index: 0,
18096		iframeWidth: '100%',
18097		iframeHeight: '100%',
18098		iframeMaxWidth: '100%',
18099		iframeMaxHeight: '100%',
18100		download: true,
18101		counter: true,
18102		appendCounterTo: '.lg-toolbar',
18103		swipeThreshold: 50,
18104		enableSwipe: true,
18105		enableDrag: true,
18106		dynamic: false,
18107		dynamicEl: [],
18108		extraProps: [],
18109		exThumbImage: '',
18110		isMobile: undefined,
18111		mobileSettings: {
18112			controls: false,
18113			showCloseIcon: false,
18114			download: false,
18115		},
18116		plugins: [],
18117		strings: {
18118			closeGallery: 'Close gallery',
18119			toggleMaximize: 'Toggle maximize',
18120			previousSlide: 'Previous slide',
18121			nextSlide: 'Next slide',
18122			download: 'Download',
18123			playVideo: 'Play video',
18124		},
18125	};
18126
18127	function initLgPolyfills() {
18128		(function () {
18129			if (typeof window.CustomEvent === 'function')
18130				return false;
18131			function CustomEvent(event, params) {
18132				params = params || {
18133					bubbles: false,
18134					cancelable: false,
18135					detail: null,
18136				};
18137				var evt = document.createEvent('CustomEvent');
18138				evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
18139				return evt;
18140			}
18141			window.CustomEvent = CustomEvent;
18142		})();
18143		(function () {
18144			if (!Element.prototype.matches) {
18145				Element.prototype.matches =
18146					Element.prototype.msMatchesSelector ||
18147						Element.prototype.webkitMatchesSelector;
18148			}
18149		})();
18150	}
18151	var lgQuery = /** @class */ (function () {
18152		function lgQuery(selector) {
18153			this.cssVenderPrefixes = [
18154				'TransitionDuration',
18155				'TransitionTimingFunction',
18156				'Transform',
18157				'Transition',
18158			];
18159			this.selector = this._getSelector(selector);
18160			this.firstElement = this._getFirstEl();
18161			return this;
18162		}
18163		lgQuery.generateUUID = function () {
18164			return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
18165				var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;
18166				return v.toString(16);
18167			});
18168		};
18169		lgQuery.prototype._getSelector = function (selector, context) {
18170			if (context === void 0) { context = document; }
18171			if (typeof selector !== 'string') {
18172				return selector;
18173			}
18174			context = context || document;
18175			var fl = selector.substring(0, 1);
18176			if (fl === '#') {
18177				return context.querySelector(selector);
18178			}
18179			else {
18180				return context.querySelectorAll(selector);
18181			}
18182		};
18183		lgQuery.prototype._each = function (func) {
18184			if (!this.selector) {
18185				return this;
18186			}
18187			if (this.selector.length !== undefined) {
18188				[].forEach.call(this.selector, func);
18189			}
18190			else {
18191				func(this.selector, 0);
18192			}
18193			return this;
18194		};
18195		lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) {
18196			// prettier-ignore
18197			var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) {
18198				return group1.toUpperCase();
18199			});
18200			if (this.cssVenderPrefixes.indexOf(property) !== -1) {
18201				el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value;
18202				el.style['webkit' + property] = value;
18203				el.style['moz' + property] = value;
18204				el.style['ms' + property] = value;
18205				el.style['o' + property] = value;
18206			}
18207			else {
18208				el.style[property] = value;
18209			}
18210		};
18211		lgQuery.prototype._getFirstEl = function () {
18212			if (this.selector && this.selector.length !== undefined) {
18213				return this.selector[0];
18214			}
18215			else {
18216				return this.selector;
18217			}
18218		};
18219		lgQuery.prototype.isEventMatched = function (event, eventName) {
18220			var eventNamespace = eventName.split('.');
18221			return event
18222				.split('.')
18223				.filter(function (e) { return e; })
18224				.every(function (e) {
18225				return eventNamespace.indexOf(e) !== -1;
18226			});
18227		};
18228		lgQuery.prototype.attr = function (attr, value) {
18229			if (value === undefined) {
18230				if (!this.firstElement) {
18231					return '';
18232				}
18233				return this.firstElement.getAttribute(attr);
18234			}
18235			this._each(function (el) {
18236				el.setAttribute(attr, value);
18237			});
18238			return this;
18239		};
18240		lgQuery.prototype.find = function (selector) {
18241			return $LG(this._getSelector(selector, this.selector));
18242		};
18243		lgQuery.prototype.first = function () {
18244			if (this.selector && this.selector.length !== undefined) {
18245				return $LG(this.selector[0]);
18246			}
18247			else {
18248				return $LG(this.selector);
18249			}
18250		};
18251		lgQuery.prototype.eq = function (index) {
18252			return $LG(this.selector[index]);
18253		};
18254		lgQuery.prototype.parent = function () {
18255			return $LG(this.selector.parentElement);
18256		};
18257		lgQuery.prototype.get = function () {
18258			return this._getFirstEl();
18259		};
18260		lgQuery.prototype.removeAttr = function (attributes) {
18261			var attrs = attributes.split(' ');
18262			this._each(function (el) {
18263				attrs.forEach(function (attr) { return el.removeAttribute(attr); });
18264			});
18265			return this;
18266		};
18267		lgQuery.prototype.wrap = function (className) {
18268			if (!this.firstElement) {
18269				return this;
18270			}
18271			var wrapper = document.createElement('div');
18272			wrapper.className = className;
18273			this.firstElement.parentNode.insertBefore(wrapper, this.firstElement);
18274			this.firstElement.parentNode.removeChild(this.firstElement);
18275			wrapper.appendChild(this.firstElement);
18276			return this;
18277		};
18278		lgQuery.prototype.addClass = function (classNames) {
18279			if (classNames === void 0) { classNames = ''; }
18280			this._each(function (el) {
18281				// IE doesn't support multiple arguments
18282				classNames.split(' ').forEach(function (className) {
18283					if (className) {
18284						el.classList.add(className);
18285					}
18286				});
18287			});
18288			return this;
18289		};
18290		lgQuery.prototype.removeClass = function (classNames) {
18291			this._each(function (el) {
18292				// IE doesn't support multiple arguments
18293				classNames.split(' ').forEach(function (className) {
18294					if (className) {
18295						el.classList.remove(className);
18296					}
18297				});
18298			});
18299			return this;
18300		};
18301		lgQuery.prototype.hasClass = function (className) {
18302			if (!this.firstElement) {
18303				return false;
18304			}
18305			return this.firstElement.classList.contains(className);
18306		};
18307		lgQuery.prototype.hasAttribute = function (attribute) {
18308			if (!this.firstElement) {
18309				return false;
18310			}
18311			return this.firstElement.hasAttribute(attribute);
18312		};
18313		lgQuery.prototype.toggleClass = function (className) {
18314			if (!this.firstElement) {
18315				return this;
18316			}
18317			if (this.hasClass(className)) {
18318				this.removeClass(className);
18319			}
18320			else {
18321				this.addClass(className);
18322			}
18323			return this;
18324		};
18325		lgQuery.prototype.css = function (property, value) {
18326			var _this = this;
18327			this._each(function (el) {
18328				_this._setCssVendorPrefix(el, property, value);
18329			});
18330			return this;
18331		};
18332		// Need to pass separate namespaces for separate elements
18333		lgQuery.prototype.on = function (events, listener) {
18334			var _this = this;
18335			if (!this.selector) {
18336				return this;
18337			}
18338			events.split(' ').forEach(function (event) {
18339				if (!Array.isArray(lgQuery.eventListeners[event])) {
18340					lgQuery.eventListeners[event] = [];
18341				}
18342				lgQuery.eventListeners[event].push(listener);
18343				_this.selector.addEventListener(event.split('.')[0], listener);
18344			});
18345			return this;
18346		};
18347		// @todo - test this
18348		lgQuery.prototype.once = function (event, listener) {
18349			var _this = this;
18350			this.on(event, function () {
18351				_this.off(event);
18352				listener(event);
18353			});
18354			return this;
18355		};
18356		lgQuery.prototype.off = function (event) {
18357			var _this = this;
18358			if (!this.selector) {
18359				return this;
18360			}
18361			Object.keys(lgQuery.eventListeners).forEach(function (eventName) {
18362				if (_this.isEventMatched(event, eventName)) {
18363					lgQuery.eventListeners[eventName].forEach(function (listener) {
18364						_this.selector.removeEventListener(eventName.split('.')[0], listener);
18365					});
18366					lgQuery.eventListeners[eventName] = [];
18367				}
18368			});
18369			return this;
18370		};
18371		lgQuery.prototype.trigger = function (event, detail) {
18372			if (!this.firstElement) {
18373				return this;
18374			}
18375			var customEvent = new CustomEvent(event.split('.')[0], {
18376				detail: detail || null,
18377			});
18378			this.firstElement.dispatchEvent(customEvent);
18379			return this;
18380		};
18381		// Does not support IE
18382		lgQuery.prototype.load = function (url) {
18383			var _this = this;
18384			fetch(url)
18385				.then(function (res) { return res.text(); })
18386				.then(function (html) {
18387				_this.selector.innerHTML = html;
18388			});
18389			return this;
18390		};
18391		lgQuery.prototype.html = function (html) {
18392			if (html === undefined) {
18393				if (!this.firstElement) {
18394					return '';
18395				}
18396				return this.firstElement.innerHTML;
18397			}
18398			this._each(function (el) {
18399				el.innerHTML = html;
18400			});
18401			return this;
18402		};
18403		lgQuery.prototype.append = function (html) {
18404			this._each(function (el) {
18405				if (typeof html === 'string') {
18406					el.insertAdjacentHTML('beforeend', html);
18407				}
18408				else {
18409					el.appendChild(html);
18410				}
18411			});
18412			return this;
18413		};
18414		lgQuery.prototype.prepend = function (html) {
18415			this._each(function (el) {
18416				el.insertAdjacentHTML('afterbegin', html);
18417			});
18418			return this;
18419		};
18420		lgQuery.prototype.remove = function () {
18421			this._each(function (el) {
18422				el.parentNode.removeChild(el);
18423			});
18424			return this;
18425		};
18426		lgQuery.prototype.empty = function () {
18427			this._each(function (el) {
18428				el.innerHTML = '';
18429			});
18430			return this;
18431		};
18432		lgQuery.prototype.scrollTop = function (scrollTop) {
18433			if (scrollTop !== undefined) {
18434				document.body.scrollTop = scrollTop;
18435				document.documentElement.scrollTop = scrollTop;
18436				return this;
18437			}
18438			else {
18439				return (window.pageYOffset ||
18440					document.documentElement.scrollTop ||
18441					document.body.scrollTop ||
18442					0);
18443			}
18444		};
18445		lgQuery.prototype.scrollLeft = function (scrollLeft) {
18446			if (scrollLeft !== undefined) {
18447				document.body.scrollLeft = scrollLeft;
18448				document.documentElement.scrollLeft = scrollLeft;
18449				return this;
18450			}
18451			else {
18452				return (window.pageXOffset ||
18453					document.documentElement.scrollLeft ||
18454					document.body.scrollLeft ||
18455					0);
18456			}
18457		};
18458		lgQuery.prototype.offset = function () {
18459			if (!this.firstElement) {
18460				return {
18461					left: 0,
18462					top: 0,
18463				};
18464			}
18465			var rect = this.firstElement.getBoundingClientRect();
18466			var bodyMarginLeft = $LG('body').style().marginLeft;
18467			// Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value
18468			return {
18469				left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(),
18470				top: rect.top + this.scrollTop(),
18471			};
18472		};
18473		lgQuery.prototype.style = function () {
18474			if (!this.firstElement) {
18475				return {};
18476			}
18477			return (this.firstElement.currentStyle ||
18478				window.getComputedStyle(this.firstElement));
18479		};
18480		// Width without padding and border even if box-sizing is used.
18481		lgQuery.prototype.width = function () {
18482			var style = this.style();
18483			return (this.firstElement.clientWidth -
18484				parseFloat(style.paddingLeft) -
18485				parseFloat(style.paddingRight));
18486		};
18487		// Height without padding and border even if box-sizing is used.
18488		lgQuery.prototype.height = function () {
18489			var style = this.style();
18490			return (this.firstElement.clientHeight -
18491				parseFloat(style.paddingTop) -
18492				parseFloat(style.paddingBottom));
18493		};
18494		lgQuery.eventListeners = {};
18495		return lgQuery;
18496	}());
18497	function $LG(selector) {
18498		initLgPolyfills();
18499		return new lgQuery(selector);
18500	}
18501
18502	var defaultDynamicOptions = [
18503		'src',
18504		'sources',
18505		'subHtml',
18506		'subHtmlUrl',
18507		'html',
18508		'video',
18509		'poster',
18510		'slideName',
18511		'responsive',
18512		'srcset',
18513		'sizes',
18514		'iframe',
18515		'downloadUrl',
18516		'download',
18517		'width',
18518		'facebookShareUrl',
18519		'tweetText',
18520		'iframeTitle',
18521		'twitterShareUrl',
18522		'pinterestShareUrl',
18523		'pinterestText',
18524		'fbHtml',
18525		'disqusIdentifier',
18526		'disqusUrl',
18527	];
18528	// Convert html data-attribute to camalcase
18529	function convertToData(attr) {
18530		// FInd a way for lgsize
18531		if (attr === 'href') {
18532			return 'src';
18533		}
18534		attr = attr.replace('data-', '');
18535		attr = attr.charAt(0).toLowerCase() + attr.slice(1);
18536		attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
18537		return attr;
18538	}
18539	var utils = {
18540		/**
18541		 * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option
18542		 */
18543		//Uncode edit ##START##
18544		getSize: function (el, container, spacing, defaultLgSize, galleryItem) {
18545		// getSize: function (el, container, spacing, defaultLgSize) {
18546		//Uncode edit ##END##
18547			if (spacing === void 0) { spacing = 0; }
18548			var LGel = $LG(el);
18549			var lgSize = LGel.attr('data-lg-size') || defaultLgSize;
18550			//Uncode edit ##START##
18551			if ( typeof galleryItem.size && galleryItem.size != null ) {
18552				lgSize = galleryItem.size;
18553			}
18554			//Uncode edit ##END##
18555			if (!lgSize) {
18556				return;
18557			}
18558			var isResponsiveSizes = lgSize.split(',');
18559			// if at-least two viewport sizes are available
18560			if (isResponsiveSizes[1]) {
18561				var wWidth = window.innerWidth;
18562				for (var i = 0; i < isResponsiveSizes.length; i++) {
18563					var size_1 = isResponsiveSizes[i];
18564					var responsiveWidth = parseInt(size_1.split('-')[2], 10);
18565					if (responsiveWidth > wWidth) {
18566						lgSize = size_1;
18567						break;
18568					}
18569					// take last item as last option
18570					if (i === isResponsiveSizes.length - 1) {
18571						lgSize = size_1;
18572					}
18573				}
18574			}
18575			var size = lgSize.split('-');
18576			var width = parseInt(size[0], 10);
18577			var height = parseInt(size[1], 10);
18578			var cWidth = container.width();
18579			var cHeight = container.height() - spacing;
18580			var maxWidth = Math.min(cWidth, width);
18581			var maxHeight = Math.min(cHeight, height);
18582			var ratio = Math.min(maxWidth / width, maxHeight / height);
18583			return { width: width * ratio, height: height * ratio };
18584		},
18585		/**
18586		 * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option
18587		 * @param {jQuery Element}
18588		 * @returns {String} Transform CSS string
18589		 */
18590		getTransform: function (el, container, top, bottom, imageSize) {
18591			if (!imageSize) {
18592				return;
18593			}
18594			var LGel = $LG(el).find('img').first();
18595			if (!LGel.get()) {
18596				return;
18597			}
18598			var containerRect = container.get().getBoundingClientRect();
18599			var wWidth = containerRect.width;
18600			// using innerWidth to include mobile safari bottom bar
18601			var wHeight = container.height() - (top + bottom);
18602			var elWidth = LGel.width();
18603			var elHeight = LGel.height();
18604			var elStyle = LGel.style();
18605			var x = (wWidth - elWidth) / 2 -
18606				LGel.offset().left +
18607				(parseFloat(elStyle.paddingLeft) || 0) +
18608				(parseFloat(elStyle.borderLeft) || 0) +
18609				$LG(window).scrollLeft() +
18610				containerRect.left;
18611			var y = (wHeight - elHeight) / 2 -
18612				LGel.offset().top +
18613				(parseFloat(elStyle.paddingTop) || 0) +
18614				(parseFloat(elStyle.borderTop) || 0) +
18615				$LG(window).scrollTop() +
18616				top;
18617			var scX = elWidth / imageSize.width;
18618			var scY = elHeight / imageSize.height;
18619			var transform = 'translate3d(' +
18620				(x *= -1) +
18621				'px, ' +
18622				(y *= -1) +
18623				'px, 0) scale3d(' +
18624				scX +
18625				', ' +
18626				scY +
18627				', 1)';
18628			return transform;
18629		},
18630		getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) {
18631			var title = iframeTitle ? 'title="' + iframeTitle + '"' : '';
18632			return "<div class=\"lg-video-cont lg-has-iframe\" style=\"width:" + iframeWidth + "; max-width:" + iframeMaxWidth + "; height: " + iframeHeight + "; max-height:" + iframeMaxHeight + "\">\n                    <iframe class=\"lg-object\" frameborder=\"0\" " + title + " src=\"" + src + "\"  allowfullscreen=\"true\"></iframe>\n                </div>";
18633		},
18634		getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) {
18635			var srcsetAttr = srcset ? "srcset=\"" + srcset + "\"" : '';
18636			var sizesAttr = sizes ? "sizes=\"" + sizes + "\"" : '';
18637			var imgMarkup = "<img " + altAttr + " " + srcsetAttr + "  " + sizesAttr + " class=\"lg-object lg-image\" data-index=\"" + index + "\" src=\"" + src + "\" />";
18638			var sourceTag = '';
18639			if (sources) {
18640				var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources;
18641				sourceTag = sourceObj.map(function (source) {
18642					var attrs = '';
18643					Object.keys(source).forEach(function (key) {
18644						// Do not remove the first space as it is required to separate the attributes
18645						attrs += " " + key + "=\"" + source[key] + "\"";
18646					});
18647					return "<source " + attrs + "></source>";
18648				});
18649			}
18650			return "" + sourceTag + imgMarkup;
18651		},
18652		// Get src from responsive src
18653		getResponsiveSrc: function (srcItms) {
18654			var rsWidth = [];
18655			var rsSrc = [];
18656			var src = '';
18657			for (var i = 0; i < srcItms.length; i++) {
18658				var _src = srcItms[i].split(' ');
18659				// Manage empty space
18660				if (_src[0] === '') {
18661					_src.splice(0, 1);
18662				}
18663				rsSrc.push(_src[0]);
18664				rsWidth.push(_src[1]);
18665			}
18666			var wWidth = window.innerWidth;
18667			for (var j = 0; j < rsWidth.length; j++) {
18668				if (parseInt(rsWidth[j], 10) > wWidth) {
18669					src = rsSrc[j];
18670					break;
18671				}
18672			}
18673			return src;
18674		},
18675		isImageLoaded: function (img) {
18676			if (!img)
18677				return false;
18678			// During the onload event, IE correctly identifies any images that
18679			// weren’t downloaded as not complete. Others should too. Gecko-based
18680			// browsers act like NS4 in that they report this incorrectly.
18681			if (!img.complete) {
18682				return false;
18683			}
18684			// However, they do have two very useful properties: naturalWidth and
18685			// naturalHeight. These give the true size of the image. If it failed
18686			// to load, either of these should be zero.
18687			if (img.naturalWidth === 0) {
18688				return false;
18689			}
18690			// No other way of checking: assume it’s ok.
18691			return true;
18692		},
18693		getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) {
18694			var videoClass = '';
18695			if (_isVideo && _isVideo.youtube) {
18696				videoClass = 'lg-has-youtube';
18697			}
18698			else if (_isVideo && _isVideo.vimeo) {
18699				videoClass = 'lg-has-vimeo';
18700			}
18701			else {
18702				videoClass = 'lg-has-html5';
18703			}
18704			return "<div class=\"lg-video-cont " + videoClass + "\" style=\"" + videoContStyle + "\">\n                <div class=\"lg-video-play-button\">
18704\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>";
18705		},
18706		getFocusableElements: function (container) {
18707			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])');
18708			var visibleElements = [].filter.call(elements, function (element) {
18709				var style = window.getComputedStyle(element);
18710				return style.display !== 'none' && style.visibility !== 'hidden';
18711			});
18712			return visibleElements;
18713		},
18714		/**
18715		 * @desc Create dynamic elements array from gallery items when dynamic option is false
18716		 * It helps to avoid frequent DOM interaction
18717		 * and avoid multiple checks for dynamic elments
18718		 *
18719		 * @returns {Array} dynamicEl
18720		 */
18721		getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) {
18722			var dynamicElements = [];
18723			var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps);
18724			[].forEach.call(items, function (item) {
18725				var dynamicEl = {};
18726				for (var i = 0; i < item.attributes.length; i++) {
18727					var attr = item.attributes[i];
18728					if (attr.specified) {
18729						var dynamicAttr = convertToData(attr.name);
18730						var label = '';
18731						if (availableDynamicOptions.indexOf(dynamicAttr) > -1) {
18732							label = dynamicAttr;
18733						}
18734						if (label) {
18735							dynamicEl[label] = attr.value;
18736						}
18737					}
18738				}
18739				var currentItem = $LG(item);
18740				var alt = currentItem.find('img').first().attr('alt') || currentItem.attr('data-alt');
18741				var title = currentItem.attr('title');
18742				//Uncode edit ##START##
18743				// var thumb = exThumbImage
18744				var thumb = exThumbImage && currentItem.attr(exThumbImage)
18745				//Uncode edit ##END##
18746					? currentItem.attr(exThumbImage)
18747					: currentItem.find('img').first().attr('src');
18748				dynamicEl.thumb = thumb;
18749				//Uncode edit ##START##
18750				if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) {
18751					// dynamicEl.subHtml = title || alt || '';
18752					dynamicEl.subHtml = title || '';
18753				}
18754				// dynamicEl.alt = alt || title || '';
18755				dynamicEl.alt = alt || title;
18756				var inlineType = currentItem.attr('data-type');
18757				dynamicEl.type = inlineType;
18758				//Uncode edit ##END##
18759				dynamicElements.push(dynamicEl);
18760			});
18761			return dynamicElements;
18762		},
18763		isMobile: function () {
18764			return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
18765		},
18766		/**
18767		 * @desc Check the given src is video
18768		 * @param {String} src
18769		 * @return {Object} video type
18770		 * Ex:{ youtube  :  ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] }
18771		 *
18772		 * @todo - this information can be moved to dynamicEl to avoid frequent calls
18773		 */
18774		isVideo: function (src, isHTML5VIdeo, index) {
18775			if (!src || src.match(/\.(mp4|m4v|ogg|webm)$/) ) {
18776				if (isHTML5VIdeo) {
18777					return {
18778						html5: true,
18779					};
18780				}
18781				else {
18782					console.warn('lightGallery :- data-src is not provided on slide item ' +
18783						(index + 1) +
18784						'. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/');
18785					return;
18786				}
18787			}
18788			var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com|be-nocookie\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)([\&|?][\S]*)*/i);
18789			var vimeo = src.match(/\/\/(?:www\.)?(?:player\.)?vimeo.com\/(?:video\/)?([0-9a-z\-_]+)(.*)?/i);
18790			var wistia = src.match(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/(medias|embed)\/([0-9a-z\-_]+)(.*)/);
18791			if (youtube) {
18792				return {
18793					youtube: youtube,
18794				};
18795			}
18796			else if (vimeo) {
18797				return {
18798					vimeo: vimeo,
18799				};
18800			}
18801			else if (wistia) {
18802				return {
18803					wistia: wistia,
18804				};
18805			}
18806		},
18807	};
18808
18809	// @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio
18810	// @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html
18811	// Unique id for each gallery
18812	var lgId = 0;
18813	var LightGallery = /** @class */ (function () {
18814		function LightGallery(element, options) {
18815			this.lgOpened = false;
vendor: 26,259 bytes, lines 18816-19495
18816			this.index = 0;
18817			// lightGallery modules
18818			this.plugins = [];
18819			// false when lightGallery load first slide content;
18820			this.lGalleryOn = false;
18821			// True when a slide animation is in progress
18822			this.lgBusy = false;
18823			this.currentItemsInDom = [];
18824			// Scroll top value before lightGallery is opened
18825			this.prevScrollTop = 0;
18826			this.bodyPaddingRight = 0;
18827			this.isDummyImageRemoved = false;
18828			this.dragOrSwipeEnabled = false;
18829			this.mediaContainerPosition = {
18830				top: 0,
18831				bottom: 0,
18832			};
18833			if (!element) {
18834				return this;
18835			}
18836			lgId++;
18837			this.lgId = lgId;
18838			this.el = element;
18839			this.LGel = $LG(element);
18840			this.generateSettings(options);
18841			this.buildModules();
18842			// When using dynamic mode, ensure dynamicEl is an array
18843			if (this.settings.dynamic &&
18844				this.settings.dynamicEl !== undefined &&
18845				!Array.isArray(this.settings.dynamicEl)) {
18846				throw 'When using dynamic mode, you must also define dynamicEl as an Array.';
18847			}
18848			this.galleryItems = this.getItems();
18849			this.normalizeSettings();
18850			// Gallery items
18851			this.init();
18852			//Uncode edit ##START##
18853			// this.validateLicense();
18854			//Uncode edit ##END##
18855			return this;
18856		}
18857		LightGallery.prototype.generateSettings = function (options) {
18858			// lightGallery settings
18859			this.settings = __assign(__assign({}, lightGalleryCoreSettings), options);
18860			if (this.settings.isMobile &&
18861				typeof this.settings.isMobile === 'function'
18862				? this.settings.isMobile()
18863				: utils.isMobile()) {
18864				var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings);
18865				this.settings = __assign(__assign({}, this.settings), mobileSettings);
18866			}
18867		};
18868		LightGallery.prototype.normalizeSettings = function () {
18869			if (this.settings.slideEndAnimation) {
18870				this.settings.hideControlOnEnd = false;
18871			}
18872			if (!this.settings.closable) {
18873				this.settings.swipeToClose = false;
18874			}
18875			// And reset it on close to get the correct value next time
18876			this.zoomFromOrigin = this.settings.zoomFromOrigin;
18877			// At the moment, Zoom from image doesn't support dynamic options
18878			// @todo add zoomFromOrigin support for dynamic images
18879			if (this.settings.dynamic) {
18880				this.zoomFromOrigin = false;
18881			}
18882			if (!this.settings.container) {
18883				this.settings.container = document.body;
18884			}
18885			// settings.preload should not be grater than $item.length
18886			this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length);
18887		};
18888		LightGallery.prototype.init = function () {
18889			var _this = this;
18890			this.addSlideVideoInfo(this.galleryItems);
18891			this.buildStructure();
18892			this.LGel.trigger(lGEvents.init, {
18893				instance: this,
18894			});
18895			if (this.settings.keyPress) {
18896				this.keyPress();
18897			}
18898			setTimeout(function () {
18899				_this.enableDrag();
18900				_this.enableSwipe();
18901				_this.triggerPosterClick();
18902			}, 50);
18903			this.arrow();
18904			if (this.settings.mousewheel) {
18905				this.mousewheel();
18906			}
18907			if (!this.settings.dynamic) {
18908				this.openGalleryOnItemClick();
18909			}
18910		};
18911		LightGallery.prototype.openGalleryOnItemClick = function () {
18912			var _this = this;
18913			var _loop_1 = function (index) {
18914				var element = this_1.items[index];
18915				var $element = $LG(element);
18916				// Using different namespace for click because click event should not unbind if selector is same object('this')
18917				// @todo manage all event listners - should have namespace that represent element
18918				var uuid = lgQuery.generateUUID();
18919				$element
18920					.attr('data-lg-id', uuid)
18921					.on("click.lgcustom-item-" + uuid, function (e) {
18922					e.preventDefault();
18923					var currentItemIndex = _this.settings.index || index;
18924					_this.openGallery(currentItemIndex, element);
18925				});
18926			};
18927			var this_1 = this;
18928			// Using for loop instead of using bubbling as the items can be any html element.
18929			for (var index = 0; index < this.items.length; index++) {
18930				_loop_1(index);
18931			}
18932		};
18933		/**
18934		 * Module constructor
18935		 * Modules are build incrementally.
18936		 * Gallery should be opened only once all the modules are initialized.
18937		 * use moduleBuildTimeout to make sure this
18938		 */
18939		LightGallery.prototype.buildModules = function () {
18940			var _this = this;
18941			this.settings.plugins.forEach(function (plugin) {
18942				_this.plugins.push(new plugin(_this, $LG));
18943			});
18944		};
18945		LightGallery.prototype.validateLicense = function () {
18946			if (!this.settings.licenseKey) {
18947				console.warn('Please provide a valid license key');
18948			}
18949			else if (this.settings.licenseKey === '0000-0000-000-0000') {
18950				console.warn("lightGallery: " + this.settings.licenseKey + " license key is not valid for production use");
18951			}
18952		};
18953		LightGallery.prototype.getSlideItem = function (index) {
18954			return $LG(this.getSlideItemId(index));
18955		};
18956		LightGallery.prototype.getSlideItemId = function (index) {
18957			return "#lg-item-" + this.lgId + "-" + index;
18958		};
18959		LightGallery.prototype.getIdName = function (id) {
18960			return id + "-" + this.lgId;
18961		};
18962		LightGallery.prototype.getElementById = function (id) {
18963			return $LG("#" + this.getIdName(id));
18964		};
18965		LightGallery.prototype.manageSingleSlideClassName = function () {
18966			if (this.galleryItems.length < 2) {
18967				this.outer.addClass('lg-single-item');
18968			}
18969			else {
18970				this.outer.removeClass('lg-single-item');
18971			}
18972		};
18973		LightGallery.prototype.buildStructure = function () {
18974			var _this = this;
18975			var container = this.$container && this.$container.get();
18976			if (container) {
18977				return;
18978			}
18979			var controls = '';
18980			var subHtmlCont = '';
18981			// Create controls
18982			if (this.settings.controls) {
18983				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>";
18984			}
18985			if (this.settings.appendSubHtmlTo !== '.lg-item') {
18986				subHtmlCont =
18987					'<div class="lg-sub-html" role="status" aria-live="polite"></div>';
18988			}
18989			var addClasses = '';
18990			if (this.settings.allowMediaOverlap) {
18991				// Do not remove space before last single quote
18992				addClasses += 'lg-media-overlap ';
18993			}
18994			var ariaLabelledby = this.settings.ariaLabelledby
18995				? 'aria-labelledby="' + this.settings.ariaLabelledby + '"'
18996				: '';
18997			var ariaDescribedby = this.settings.ariaDescribedby
18998				? 'aria-describedby="' + this.settings.ariaDescribedby + '"'
18999				: '';
19000			var containerClassName = "lg-container " + this.settings.addClass + " " + (document.body !== this.settings.container ? 'lg-inline' : '');
19001			var closeIcon = this.settings.closable && this.settings.showCloseIcon
19002				? "<button type=\"button\" aria-label=\"" + this.settings.strings['closeGallery'] + "\" id=\"" + this.getIdName('lg-close') + "\" class=\"lg-close lg-icon\"></button>"
19003				: '';
19004			var maximizeIcon = this.settings.showMaximizeIcon
19005				? "<button type=\"button\" aria-label=\"" + this.settings.strings['toggleMaximize'] + "\" id=\"" + this.getIdName('lg-maximize') + "\" class=\"lg-maximize lg-icon\"></button>"
19006				: '';
19007			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'
19008				? subHtmlCont
19009				: '') + "\n                <div id=\"" + this.getIdName('lg-components') + "\" class=\"lg-components\">\n                    " + (this.settings.appendSubHtmlTo === '.lg-sub-html'
19010				? subHtmlCont
19011				: '') + "\n                </div>\n            </div>\n        </div>\n        ";
19012			$LG(this.settings.container).append(template);
19013			if (document.body !== this.settings.container) {
19014				$LG(this.settings.container).css('position', 'relative');
19015			}
19016			this.outer = this.getElementById('lg-outer');
19017			this.$lgComponents = this.getElementById('lg-components');
19018			this.$backdrop = this.getElementById('lg-backdrop');
19019			this.$container = this.getElementById('lg-container');
19020			this.$inner = this.getElementById('lg-inner');
19021			this.$content = this.getElementById('lg-content');
19022			this.$toolbar = this.getElementById('lg-toolbar');
19023			this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms');
19024			var outerClassNames = this.settings.mode + " ";
19025			this.manageSingleSlideClassName();
19026			if (this.settings.enableDrag) {
19027				outerClassNames += 'lg-grab ';
19028			}
19029			this.outer.addClass(outerClassNames);
19030			this.$inner.css('transition-timing-function', this.settings.easing);
19031			this.$inner.css('transition-duration', this.settings.speed + 'ms');
19032			if (this.settings.download) {
19033				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>");
19034			}
19035			this.counter();
19036			$LG(window).on("resize.lg.global" + this.lgId + " orientationchange.lg.global" + this.lgId, function () {
19037				_this.refreshOnResize();
19038			});
19039			this.hideBars();
19040			this.manageCloseGallery();
19041			this.toggleMaximize();
19042			this.initModules();
19043		};
19044		LightGallery.prototype.refreshOnResize = function () {
19045			if (this.lgOpened) {
19046				var currentGalleryItem = this.galleryItems[this.index];
19047				var __slideVideoInfo = currentGalleryItem.__slideVideoInfo;
19048				this.mediaContainerPosition = this.getMediaContainerPosition();
19049				var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom;
19050				//Uncode edit ##START##
19051				this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]);
19052				// this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize);
19053				//Uncode edit ##END##
19054				if (__slideVideoInfo) {
19055					this.resizeVideoSlide(this.index, this.currentImageSize);
19056				}
19057				if (this.zoomFromOrigin && !this.isDummyImageRemoved) {
19058					var imgStyle = this.getDummyImgStyles(this.currentImageSize);
19059					this.outer
19060						.find('.lg-current .lg-dummy-img')
19061						.first()
19062						.attr('style', imgStyle);
19063				}
19064				this.LGel.trigger(lGEvents.containerResize);
19065			}
19066		};
19067		LightGallery.prototype.resizeVideoSlide = function (index, imageSize) {
19068			var lgVideoStyle = this.getVideoContStyle(imageSize);
19069			var currentSlide = this.getSlideItem(index);
19070			currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle);
19071		};
19072		/**
19073		 * Update slides dynamically.
19074		 * Add, edit or delete slides dynamically when lightGallery is opened.
19075		 * Modify the current gallery items and pass it via updateSlides method
19076		 * @note
19077		 * - Do not mutate existing lightGallery items directly.
19078		 * - Always pass new list of gallery items
19079		 * - You need to take care of thumbnails outside the gallery if any
19080		 * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method.
19081		 * @param items Gallery items
19082		 * @param index After the update operation, which slide gallery should navigate to
19083		 * @category lGPublicMethods
19084		 * @example
19085		 * const plugin = lightGallery();
19086		 *
19087		 * // Adding slides dynamically
19088		 * let galleryItems = [
19089		 * // Access existing lightGallery items
19090		 * // galleryItems are automatically generated internally from the gallery HTML markup
19091		 * // or directly from galleryItems when dynamic gallery is used
19092		 *   ...plugin.galleryItems,
19093		 *     ...[
19094		 *       {
19095		 *         src: 'img/img-1.png',
19096		 *           thumb: 'img/thumb1.png',
19097		 *         },
19098		 *     ],
19099		 *   ];
19100		 *   plugin.updateSlides(
19101		 *     galleryItems,
19102		 *     plugin.index,
19103		 *   );
19104		 *
19105		 *
19106		 * // Remove slides dynamically
19107		 * galleryItems = JSON.parse(
19108		 *   JSON.stringify(updateSlideInstance.galleryItems),
19109		 * );
19110		 * galleryItems.shift();
19111		 * updateSlideInstance.updateSlides(galleryItems, 1);
19112		 * @see <a href="/demos/update-slides/">Demo</a>
19113		 */
19114		LightGallery.prototype.updateSlides = function (items, index) {
19115			if (this.index > items.length - 1) {
19116				this.index = items.length - 1;
19117			}
19118			if (items.length === 1) {
19119				this.index = 0;
19120			}
19121			if (!items.length) {
19122				this.closeGallery();
19123				return;
19124			}
19125			var currentSrc = this.galleryItems[index].src;
19126			this.galleryItems = items;
19127			this.updateControls();
19128			this.$inner.empty();
19129			this.currentItemsInDom = [];
19130			var _index = 0;
19131			// Find the current index based on source value of the slide
19132			this.galleryItems.some(function (galleryItem, itemIndex) {
19133				if (galleryItem.src === currentSrc) {
19134					_index = itemIndex;
19135					return true;
19136				}
19137				return false;
19138			});
19139			this.currentItemsInDom = this.organizeSlideItems(_index, -1);
19140			this.loadContent(_index, true);
19141			this.getSlideItem(_index).addClass('lg-current');
19142			this.index = _index;
19143			this.updateCurrentCounter(_index);
19144			this.LGel.trigger(lGEvents.updateSlides);
19145		};
19146		// Get gallery items based on multiple conditions
19147		LightGallery.prototype.getItems = function () {
19148			// Gallery items
19149			this.items = [];
19150			if (!this.settings.dynamic) {
19151				if (this.settings.selector === 'this') {
19152					this.items.push(this.el);
19153				}
19154				else if (this.settings.selector) {
19155					if (typeof this.settings.selector === 'string') {
19156						if (this.settings.selectWithin) {
19157							var selectWithin = $LG(this.settings.selectWithin);
19158							this.items = selectWithin
19159								.find(this.settings.selector)
19160								.get();
19161						}
19162						else {
19163							this.items = this.el.querySelectorAll(this.settings.selector);
19164						}
19165					}
19166					else {
19167						this.items = this.settings.selector;
19168					}
19169				}
19170				else {
19171					this.items = this.el.children;
19172				}
19173				return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage);
19174			}
19175			else {
19176				return this.settings.dynamicEl || [];
19177			}
19178		};
19179		LightGallery.prototype.shouldHideScrollbar = function () {
19180			return (this.settings.hideScrollbar &&
19181				document.body === this.settings.container);
19182		};
19183		LightGallery.prototype.hideScrollbar = function () {
19184			if (!this.shouldHideScrollbar()) {
19185				return;
19186			}
19187			this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight);
19188			var bodyRect = document.documentElement.getBoundingClientRect();
19189			var scrollbarWidth = window.innerWidth - bodyRect.width;
19190			$LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px');
19191			$LG(document.body).addClass('lg-overlay-open');
19192		};
19193		LightGallery.prototype.resetScrollBar = function () {
19194			if (!this.shouldHideScrollbar()) {
19195				return;
19196			}
19197			$LG(document.body).css('padding-right', this.bodyPaddingRight + 'px');
19198			$LG(document.body).removeClass('lg-overlay-open');
19199		};
19200		/**
19201		 * Open lightGallery.
19202		 * Open gallery with specific slide by passing index of the slide as parameter.
19203		 * @category lGPublicMethods
19204		 * @param {Number} index  - index of the slide
19205		 * @param {HTMLElement} element - Which image lightGallery should zoom from
19206		 *
19207		 * @example
19208		 * const $dynamicGallery = document.getElementById('dynamic-gallery-demo');
19209		 * const dynamicGallery = lightGallery($dynamicGallery, {
19210		 *     dynamic: true,
19211		 *     dynamicEl: [
19212		 *         {
19213		 *              src: 'img/1.jpg',
19214		 *              thumb: 'img/thumb-1.jpg',
19215		 *              subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>',
19216		 *         },
19217		 *         ...
19218		 *     ],
19219		 * });
19220		 * $dynamicGallery.addEventListener('click', function () {
19221		 *     // Starts with third item.(Optional).
19222		 *     // This is useful if you want use dynamic mode with
19223		 *     // custom thumbnails (thumbnails outside gallery),
19224		 *     dynamicGallery.openGallery(2);
19225		 * });
19226		 *
19227		 */
19228		LightGallery.prototype.openGallery = function (index, element) {
19229			var _this = this;
19230			if (index === void 0) { index = this.settings.index; }
19231			// prevent accidental double execution
19232			if (this.lgOpened)
19233				return;
19234			this.lgOpened = true;
19235			this.outer.removeClass('lg-hide-items');
19236			this.hideScrollbar();
19237			// Add display block, but still has opacity 0
19238			this.$container.addClass('lg-show');
19239			var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index);
19240			this.currentItemsInDom = itemsToBeInsertedToDom;
19241			var items = '';
19242			itemsToBeInsertedToDom.forEach(function (item) {
19243				items = items + ("<div id=\"" + item + "\" class=\"lg-item\"></div>");
19244			});
19245			this.$inner.append(items);
19246			this.addHtml(index);
19247			var transform = '';
19248			this.mediaContainerPosition = this.getMediaContainerPosition();
19249			var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
19250			if (!this.settings.allowMediaOverlap) {
19251				this.setMediaContainerPosition(top, bottom);
19252			}
19253			var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo;
19254			if (this.zoomFromOrigin && element) {
19255				//Uncode edit ##START##
19256				this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]);
19257				// this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize);
19258				//Uncode edit ##END##
19259				transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize);
19260			}
19261			if (!this.zoomFromOrigin || !transform) {
19262				this.outer.addClass(this.settings.startClass);
19263				this.getSlideItem(index).removeClass('lg-complete');
19264			}
19265			var timeout = this.settings.zoomFromOrigin
19266				? 100
19267				: this.settings.backdropDuration;
19268			setTimeout(function () {
19269				_this.outer.addClass('lg-components-open');
19270			}, timeout);
19271			this.index = index;
19272			//Uncode edit ##START##
19273			// this.LGel.trigger(lGEvents.beforeOpen);
19274			this.LGel.trigger(lGEvents.beforeOpen, {
19275				galleryItems: this.galleryItems,
19276				items: this.items,
19277				outer: this.outer,
19278			});
19279			//Uncode edit ##END##
19280			// add class lg-current to remove initial transition
19281			this.getSlideItem(index).addClass('lg-current');
19282			this.lGalleryOn = false;
19283			// Store the current scroll top value to scroll back after closing the gallery..
19284			this.prevScrollTop = $LG(window).scrollTop();
19285			setTimeout(function () {
19286				// Need to check both zoomFromOrigin and transform values as we need to set set the
19287				// default opening animation if user missed to add the lg-size attribute
19288				if (_this.zoomFromOrigin && transform) {
19289					var currentSlide_1 = _this.getSlideItem(index);
19290					currentSlide_1.css('transform', transform);
19291					setTimeout(function () {
19292						currentSlide_1
19293							.addClass('lg-start-progress lg-start-end-progress')
19294							.css('transition-duration', _this.settings.startAnimationDuration + 'ms');
19295						_this.outer.addClass('lg-zoom-from-image');
19296					});
19297					setTimeout(function () {
19298						currentSlide_1.css('transform', 'translate3d(0, 0, 0)');
19299					}, 100);
19300				}
19301				setTimeout(function () {
19302					_this.$backdrop.addClass('in');
19303					_this.$container.addClass('lg-show-in');
19304				}, 10);
19305				setTimeout(function () {
19306					if (_this.settings.trapFocus &&
19307						document.body === _this.settings.container) {
19308						_this.trapFocus();
19309					}
19310				}, _this.settings.backdropDuration + 50);
19311				// lg-visible class resets gallery opacity to 1
19312				if (!_this.zoomFromOrigin || !transform) {
19313					setTimeout(function () {
19314						_this.outer.addClass('lg-visible');
19315					}, _this.settings.backdropDuration);
19316				}
19317				// initiate slide function
19318				_this.slide(index, false, false, false);
19319				_this.LGel.trigger(lGEvents.afterOpen);
19320			});
19321			if (document.body === this.settings.container) {
19322				$LG('html').addClass('lg-on');
19323			}
19324		};
19325		/**
19326		 * Note - Changing the position of the media on every slide transition creates a flickering effect.
19327		 * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption.
19328		 * if you have dynamic captions for each media,
19329		 * you can provide an appropriate height for the captions via allowMediaOverlap option
19330		 */
19331		LightGallery.prototype.getMediaContainerPosition = function () {
19332			if (this.settings.allowMediaOverlap) {
19333				return {
19334					top: 0,
19335					bottom: 0,
19336				};
19337			}
19338			var top = this.$toolbar.get().clientHeight || 0;
19339			var subHtml = this.outer.find('.lg-components .lg-sub-html').get();
19340			var captionHeight = this.settings.defaultCaptionHeight ||
19341				(subHtml && subHtml.clientHeight) ||
19342				0;
19343			var thumbContainer = this.outer.find('.lg-thumb-outer').get();
19344			var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0;
19345			var bottom = thumbHeight + captionHeight;
19346			//Uncode edit ##START##
19347			bottom = bottom < 55 ? 55 : bottom;
19348			//Uncode edit ##END##
19349			return {
19350				top: top,
19351				bottom: bottom,
19352			};
19353		};
19354		LightGallery.prototype.setMediaContainerPosition = function (top, bottom) {
19355			if (top === void 0) { top = 0; }
19356			if (bottom === void 0) { bottom = 0; }
19357			this.$content.css('top', top + 'px').css('bottom', bottom + 'px');
19358		};
19359		LightGallery.prototype.hideBars = function () {
19360			var _this = this;
19361			// Hide controllers if mouse doesn't move for some period
19362			setTimeout(function () {
19363				_this.outer.removeClass('lg-hide-items');
19364				if (_this.settings.hideBarsDelay > 0) {
19365					_this.outer.on('mousemove.lg click.lg touchstart.lg', function () {
19366						_this.outer.removeClass('lg-hide-items');
19367						clearTimeout(_this.hideBarTimeout);
19368						// Timeout will be cleared on each slide movement also
19369						_this.hideBarTimeout = setTimeout(function () {
19370							_this.outer.addClass('lg-hide-items');
19371						}, _this.settings.hideBarsDelay);
19372					});
19373					_this.outer.trigger('mousemove.lg');
19374				}
19375			}, this.settings.showBarsAfter);
19376		};
19377		LightGallery.prototype.initPictureFill = function ($img) {
19378			if (this.settings.supportLegacyBrowser) {
19379				try {
19380					picturefill({
19381						elements: [$img.get()],
19382					});
19383				}
19384				catch (e) {
19385					console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.');
19386				}
19387			}
19388		};
19389		/**
19390		 *  @desc Create image counter
19391		 *  Ex: 1/10
19392		 */
19393		LightGallery.prototype.counter = function () {
19394			if (this.settings.counter) {
19395				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>";
19396				this.outer.find(this.settings.appendCounterTo).append(counterHtml);
19397			}
19398		};
19399		/**
19400		 *  @desc add sub-html into the slide
19401		 *  @param {Number} index - index of the slide
19402		 */
19403		LightGallery.prototype.addHtml = function (index) {
19404			var subHtml;
19405			var subHtmlUrl;
19406			if (this.galleryItems[index].subHtmlUrl) {
19407				subHtmlUrl = this.galleryItems[index].subHtmlUrl;
19408			}
19409			else {
19410				subHtml = this.galleryItems[index].subHtml;
19411			}
19412			if (!subHtmlUrl) {
19413				if (subHtml) {
19414					// get first letter of sub-html
19415					// if first letter starts with . or # get the html form the jQuery object
19416					var fL = subHtml.substring(0, 1);
19417					if (fL === '.' || fL === '#') {
19418						if (this.settings.subHtmlSelectorRelative &&
19419							!this.settings.dynamic) {
19420							subHtml = $LG(this.items)
19421								.eq(index)
19422								.find(subHtml)
19423								.first()
19424								.html();
19425						}
19426						else {
19427							subHtml = $LG(subHtml).first().html();
19428						}
19429					}
19430				}
19431				else {
19432					subHtml = '';
19433				}
19434			}
19435			if (this.settings.appendSubHtmlTo !== '.lg-item') {
19436				if (subHtmlUrl) {
19437					this.outer.find('.lg-sub-html').load(subHtmlUrl);
19438				}
19439				else {
19440					this.outer.find('.lg-sub-html').html(subHtml);
19441				}
19442			}
19443			else {
19444				var currentSlide = $LG(this.getSlideItemId(index));
19445				if (subHtmlUrl) {
19446					currentSlide.load(subHtmlUrl);
19447				}
19448				else {
19449					currentSlide.append("<div class=\"lg-sub-html\">" + subHtml + "</div>");
19450				}
19451			}
19452			// Add lg-empty-html class if title doesn't exist
19453			if (typeof subHtml !== 'undefined' && subHtml !== null) {
19454				if (subHtml === '') {
19455					this.outer
19456						.find(this.settings.appendSubHtmlTo)
19457						.addClass('lg-empty-html');
19458				}
19459				else {
19460					this.outer
19461						.find(this.settings.appendSubHtmlTo)
19462						.removeClass('lg-empty-html');
19463				}
19464			}
19465			this.LGel.trigger(lGEvents.afterAppendSubHtml, {
19466				index: index,
19467			});
19468		};
19469		/**
19470		 *  @desc Preload slides
19471		 *  @param {Number} index - index of the slide
19472		 * @todo preload not working for the first slide, Also, should work for the first and last slide as well
19473		 */
19474		LightGallery.prototype.preload = function (index) {
19475			for (var i = 1; i <= this.settings.preload; i++) {
19476				if (i >= this.galleryItems.length - index) {
19477					break;
19478				}
19479				this.loadContent(index + i, false);
19480			}
19481			for (var j = 1; j <= this.settings.preload; j++) {
19482				if (index - j < 0) {
19483					break;
19484				}
19485				this.loadContent(index - j, false);
19486			}
19487		};
19488		LightGallery.prototype.getDummyImgStyles = function (imageSize) {
19489			if (!imageSize)
19490				return '';
19491			return "width:" + imageSize.width + "px;\n                margin-left: -" + imageSize.width / 2 + "px;\n                margin-top: -" + imageSize.height / 2 + "px;\n                height:" + imageSize.height + "px";
19492		};
19493		LightGallery.prototype.getVideoContStyle = function (imageSize) {
19494			if (!imageSize)
19495				return '';
19496			return "width:" + imageSize.width + "px;\n                height:" + imageSize.height + "px";
19497		};
19498		LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) {
19499			var $currentItem;
19500			if (!this.settings.dynamic) {
19501				$currentItem = $LG(this.items).eq(index);
19502			}
19503			if ($currentItem) {
19504				var _dummyImgSrc = void 0;
19505				if (!this.settings.exThumbImage) {
19506					_dummyImgSrc = $currentItem.find('img').first().attr('src');
19507				}
19508				else {
19509					_dummyImgSrc = $currentItem.attr(this.settings.exThumbImage);
19510				}
19511				if (!_dummyImgSrc)
19512					return '';
19513				var imgStyle = this.getDummyImgStyles(this.currentImageSize);
19514				var dummyImgContent = "<img " + alt + " style=\"" + imgStyle + "\" class=\"lg-dummy-img\" src=\"" + _dummyImgSrc + "\" />";
19515				$currentSlide.addClass('lg-first-slide');
19516				this.outer.addClass('lg-first-slide-loading');
19517				return dummyImgContent;
19518			}
19519			return '';
19520		};
19521		LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) {
19522			var currentGalleryItem = this.galleryItems[index];
19523			var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
19524			// Use the thumbnail as dummy image which will be resized to actual image size and
19525			// displayed on top of actual image
19526			var imgContent = '';
19527			var altAttr = alt ? 'alt="' + alt + '"' : '';
19528			if (this.isFirstSlideWithZoomAnimation()) {
19529				imgContent = this.getDummyImageContent($currentSlide, index, altAttr);
19530			}
19531			else {
19532				imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources);
19533			}
19534			var imgMarkup = "<picture class=\"lg-img-wrap\"> " + imgContent + "</picture>";
19535			$currentSlide.prepend(imgMarkup);
19536		};
19537		LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) {
19538			var mediaObject = $slide.find('.lg-object').first();
19539			if (utils.isImageLoaded(mediaObject.get()) ||
19540				isHTML5VideoWithoutPoster) {
19541				onLoad();
19542			}
19543			else {
19544				mediaObject.on('load.lg error.lg', function () {
19545					onLoad && onLoad();
19546				});
19547				mediaObject.on('error.lg', function () {
19548					onError && onError();
19549				});
19550			}
19551		};
19552		/**
19553		 *
19554		 * @param $el Current slide item
19555		 * @param index
19556		 * @param delay Delay is 0 except first time
19557		 * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin
19558		 * @param isFirstSlide
19559		 */
19560		LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) {
19561			var _this = this;
19562			//Uncode edit ##START##
19563			var $item = _this.galleryItems[index],
19564				type = $item.type;
19565
19566			if ( typeof $item.src !== 'undefined' ) {
19567				var inline_id = $item.src.replace('#', ''),
19568					$inline = document.getElementById(inline_id),
19569					inline_html;
19570
19571				if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) {
19572					inline_html = $inline.innerHTML;
19573				} else {
19574					inline_html = '';
19575				}
19576			}
19577			//Uncode edit ##END##
19578			this.onSlideObjectLoad(currentSlide, true, function () {
19579				_this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide);
19580			}, function () {
19581				currentSlide.addClass('lg-complete lg-complete_');
19582				//Uncode edit ##START##
19583				// currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>');
19584				if ( inline_html !== '' ) {
19585					currentSlide.html(inline_html);
19586				} else {
19587					currentSlide.html('<span class="lg-error-msg">Oops... Failed to load content...</span>');
19588				}
19589				//Uncode edit ##END##
19590			});
19591		};
19592		LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) {
19593			var _this = this;
19594			var currentGalleryItem = this.galleryItems[index];
19595			// Adding delay for video slides without poster for better performance and user experience
19596			// Videos should start playing once once the gallery is completely loaded
19597			var _speed = isFirstSlide &&
vendor: 3,676 bytes, lines 19598-19686
19598				this.getSlideType(currentGalleryItem) === 'video' &&
19599				!currentGalleryItem.poster
19600				? speed
19601				: 0;
19602			setTimeout(function () {
19603				$currentSlide.addClass('lg-complete lg-complete_');
19604				_this.LGel.trigger(lGEvents.slideItemLoad, {
19605					index: index,
19606					delay: delay || 0,
19607					isFirstSlide: isFirstSlide,
19608				});
19609			}, _speed);
19610		};
19611		LightGallery.prototype.isFirstSlideWithZoomAnimation = function () {
19612			return !!(!this.lGalleryOn &&
19613				this.zoomFromOrigin &&
19614				this.currentImageSize);
19615		};
19616		// Add video slideInfo
19617		LightGallery.prototype.addSlideVideoInfo = function (items) {
19618			var _this = this;
19619			items.forEach(function (element, index) {
19620				element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index);
19621				if (element.__slideVideoInfo &&
19622					_this.settings.loadYouTubePoster &&
19623					!element.poster &&
19624					element.__slideVideoInfo.youtube) {
19625					element.poster = "//img.youtube.com/vi/" + element.__slideVideoInfo.youtube[1] + "/maxresdefault.jpg";
19626				}
19627			});
19628		};
19629		/**
19630		 *  Load slide content into slide.
19631		 *  This is used to load content into slides that is not visible too
19632		 *  @param {Number} index - index of the slide.
19633		 *  @param {Boolean} rec - if true call loadcontent() function again.
19634		 */
19635		LightGallery.prototype.loadContent = function (index, rec) {
19636			var _this = this;
19637			var currentGalleryItem = this.galleryItems[index];
19638			var $currentSlide = $LG(this.getSlideItemId(index));
19639			var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;
19640			var src = currentGalleryItem.src;
19641			var video = currentGalleryItem.video;
19642			var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video;
19643			if (currentGalleryItem.responsive) {
19644				var srcDyItms = currentGalleryItem.responsive.split(',');
19645				src = utils.getResponsiveSrc(srcDyItms) || src;
19646			}
19647			var videoInfo = currentGalleryItem.__slideVideoInfo;
19648			var lgVideoStyle = '';
19649			var iframe = !!currentGalleryItem.iframe;
19650			var isFirstSlide = !this.lGalleryOn;
19651			// delay for adding complete class. it is 0 except first time.
19652			var delay = 0;
19653			if (isFirstSlide) {
19654				if (this.zoomFromOrigin && this.currentImageSize) {
19655					delay = this.settings.startAnimationDuration + 10;
19656				}
19657				else {
19658					delay = this.settings.backdropDuration + 10;
19659				}
19660			}
19661			if (!$currentSlide.hasClass('lg-loaded')) {
19662				if (videoInfo) {
19663					var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom;
19664					//Uncode edit ##START##
19665					var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]);
19666					// var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize);
19667					//Uncode edit ##END##
19668					lgVideoStyle = this.getVideoContStyle(videoSize);
19669				}
19670				if (iframe) {
19671					var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle);
19672					$currentSlide.prepend(markup);
19673				}
19674				else if (poster) {
19675					var dummyImg = '';
19676					var hasStartAnimation = isFirstSlide &&
19677						this.zoomFromOrigin &&
19678						this.currentImageSize;
19679					if (hasStartAnimation) {
19680						dummyImg = this.getDummyImageContent($currentSlide, index, '');
19681					}
19682					var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo);
19683					$currentSlide.prepend(markup);
19684				}
19685				//Uncode edit ##START##
19686				// else if (videoInfo) {
19687				else if (videoInfo || this.getSlideType(currentGalleryItem) === 'audio') {
19688					if (! _html5Video) {
19689						var markup = "<div class=\"lg-video-cont \" style=\"" + lgVideoStyle + "\"></div>";
19690					}
19691					//Uncode edit ##END##
19692					$currentSlide.prepend(markup);
19693				}
19694				else {
19695					//Uncode edit ##START##
19696					var $item = _this.galleryItems[index],
19697						type = $item.type;
19698
19699					if ( typeof $item.src !== 'undefined' ) {
19700						var inline_id = $item.src.replace('#', ''),
19701							$inline = document.getElementById(inline_id),
19702							inline_html;
19703
19704						if ( type === 'inline' && inline_id != null && typeof $inline !== 'undefined' ) {
19705							inline_html = $inline.innerHTML;
19706						} else {
19707							inline_html = '';
19708						}
19709					}
19710					if ( inline_html !== '' ) {
19711						$currentSlide.html(inline_html);
19712					} else {
19713						this.setImgMarkup(src, $currentSlide, index);
19714						if (srcset || sources) {
19715							var $img = $currentSlide.find('.lg-object');
19716							this.initPictureFill($img);
19717						}
19718					}
19719					/*this.setImgMarkup(src, $currentSlide, index);
19720					if (srcset || sources) {
19721						var $img = $currentSlide.find('.lg-object');
19722						this.initPictureFill($img);
19723					}*/
19724					//Uncode edit ##END##
19725				}
19726				if (poster || videoInfo) {
19727					this.LGel.trigger(lGEvents.hasVideo, {
19728						index: index,
19729						src: src,
19730						html5Video: _html5Video,
19731						hasPoster: !!poster,
19732					});
19733				}
19734				this.LGel.trigger(lGEvents.afterAppendSlide, { index: index });
19735				if (this.lGalleryOn &&
19736					this.settings.appendSubHtmlTo === '.lg-item') {
19737					this.addHtml(index);
19738				}
19739			}
19740			// For first time add some delay for displaying the start animation.
19741			var _speed = 0;
19742			// Do not change the delay value because it is required for zoom plugin.
19743			// If gallery opened from direct url (hash) speed value should be 0
19744			if (delay && !$LG(document.body).hasClass('lg-from-hash')) {
19745				_speed = delay;
19746			}
19747			// Only for first slide and zoomFromOrigin is enabled
19748			if (this.isFirstSlideWithZoomAnimation()) {
19749				setTimeout(function () {
19750					$currentSlide
19751						.removeClass('lg-start-end-progress lg-start-progress')
19752						.removeAttr('style');
19753				}, this.settings.startAnimationDuration + 100);
19754				if (!$currentSlide.hasClass('lg-loaded')) {
19755					setTimeout(function () {
19756						if (_this.getSlideType(currentGalleryItem) === 'image') {
19757							var alt = currentGalleryItem.alt;
19758							var altAttr = alt ? 'alt="' + alt + '"' : '';
19759							$currentSlide
19760								.find('.lg-img-wrap')
19761								.append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources));
19762							if (srcset || sources) {
19763								var $img = $currentSlide.find('.lg-object');
19764								_this.initPictureFill($img);
19765							}
19766						}
19767						if (_this.getSlideType(currentGalleryItem) === 'image' ||
19768							(_this.getSlideType(currentGalleryItem) === 'video' &&
19769								poster)) {
19770							_this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false);
19771							// load remaining slides once the slide is completely loaded
19772							_this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () {
19773								_this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
19774							}, function () {
19775								_this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);
19776							});
19777						}
19778					}, this.settings.startAnimationDuration + 100);
19779				}
19780			}
19781			// SLide content has been added to dom
19782			$currentSlide.addClass('lg-loaded');
19783			if (!this.isFirstSlideWithZoomAnimation() ||
19784				(this.getSlideType(currentGalleryItem) === 'video' && !poster)) {
19785				//Uncode edit ##START##
19786				// this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster));
19787				this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!( (videoInfo && videoInfo.html5 && !poster) || this.get
vendor: 31,133 bytes, lines 19787-20711
19787SlideType(currentGalleryItem) === 'audio'));
19788				//Uncode edit ##END##
19789			}
19790			// When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling
19791			if ((!this.zoomFromOrigin || !this.currentImageSize) &&
19792				$currentSlide.hasClass('lg-complete_') &&
19793				!this.lGalleryOn) {
19794				setTimeout(function () {
19795					$currentSlide.addClass('lg-complete');
19796				}, this.settings.backdropDuration);
19797			}
19798			// Content loaded
19799			// Need to set lGalleryOn before calling preload function
19800			this.lGalleryOn = true;
19801			if (rec === true) {
19802				if (!$currentSlide.hasClass('lg-complete_')) {
19803					$currentSlide
19804						.find('.lg-object')
19805						.first()
19806						.on('load.lg error.lg', function () {
19807						_this.preload(index);
19808					});
19809				}
19810				else {
19811					this.preload(index);
19812				}
19813			}
19814		};
19815		/**
19816		 * @desc Remove dummy image content and load next slides
19817		 * Called only for the first time if zoomFromOrigin animation is enabled
19818		 * @param index
19819		 * @param $currentSlide
19820		 * @param speed
19821		 */
19822		LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) {
19823			var _this = this;
19824			setTimeout(function () {
19825				$currentSlide.find('.lg-dummy-img').remove();
19826				$currentSlide.removeClass('lg-first-slide');
19827				_this.outer.removeClass('lg-first-slide-loading');
19828				_this.isDummyImageRemoved = true;
19829				_this.preload(index);
19830			}, speed + 300);
19831		};
19832		LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) {
19833			var _this = this;
19834			if (numberOfItems === void 0) { numberOfItems = 0; }
19835			var itemsToBeInsertedToDom = [];
19836			// Minimum 2 items should be there
19837			var possibleNumberOfItems = Math.max(numberOfItems, 3);
19838			possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length);
19839			var prevIndexItem = "lg-item-" + this.lgId + "-" + prevIndex;
19840			if (this.galleryItems.length <= 3) {
19841				this.galleryItems.forEach(function (_element, index) {
19842					itemsToBeInsertedToDom.push("lg-item-" + _this.lgId + "-" + index);
19843				});
19844				return itemsToBeInsertedToDom;
19845			}
19846			if (index < (this.galleryItems.length - 1) / 2) {
19847				for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) {
19848					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
19849				}
19850				var numberOfExistingItems = itemsToBeInsertedToDom.length;
19851				for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
19852					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index + idx + 1));
19853				}
19854			}
19855			else {
19856				for (var idx = index; idx <= this.galleryItems.length - 1 &&
19857					idx < index + possibleNumberOfItems / 2; idx++) {
19858					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + idx);
19859				}
19860				var numberOfExistingItems = itemsToBeInsertedToDom.length;
19861				for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {
19862					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (index - idx - 1));
19863				}
19864			}
19865			if (this.settings.loop) {
19866				if (index === this.galleryItems.length - 1) {
19867					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + 0);
19868				}
19869				else if (index === 0) {
19870					itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + (this.galleryItems.length - 1));
19871				}
19872			}
19873			if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {
19874				itemsToBeInsertedToDom.push("lg-item-" + this.lgId + "-" + prevIndex);
19875			}
19876			return itemsToBeInsertedToDom;
19877		};
19878		LightGallery.prototype.organizeSlideItems = function (index, prevIndex) {
19879			var _this = this;
19880			var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom);
19881			itemsToBeInsertedToDom.forEach(function (item) {
19882				if (_this.currentItemsInDom.indexOf(item) === -1) {
19883					_this.$inner.append("<div id=\"" + item + "\" class=\"lg-item\"></div>");
19884				}
19885			});
19886			this.currentItemsInDom.forEach(function (item) {
19887				if (itemsToBeInsertedToDom.indexOf(item) === -1) {
19888					$LG("#" + item).remove();
19889				}
19890			});
19891			return itemsToBeInsertedToDom;
19892		};
19893		/**
19894		 * Get previous index of the slide
19895		 */
19896		LightGallery.prototype.getPreviousSlideIndex = function () {
19897			var prevIndex = 0;
19898			try {
19899				var currentItemId = this.outer
19900					.find('.lg-current')
19901					.first()
19902					.attr('id');
19903				prevIndex = parseInt(currentItemId.split('-')[3]) || 0;
19904			}
19905			catch (error) {
19906				prevIndex = 0;
19907			}
19908			return prevIndex;
19909		};
19910		LightGallery.prototype.setDownloadValue = function (index) {
19911			if (this.settings.download) {
19912				var currentGalleryItem = this.galleryItems[index];
19913				var hideDownloadBtn = currentGalleryItem.downloadUrl === false ||
19914					currentGalleryItem.downloadUrl === 'false';
19915				if (hideDownloadBtn) {
19916					this.outer.addClass('lg-hide-download');
19917				}
19918				else {
19919					var $download = this.getElementById('lg-download');
19920					this.outer.removeClass('lg-hide-download');
19921					$download.attr('href', currentGalleryItem.downloadUrl ||
19922						currentGalleryItem.src);
19923					if (currentGalleryItem.download) {
19924						//Uncode edit ##START##
19925						if ( typeof currentGalleryItem.video !== 'undefined' && currentGalleryItem.video ) {
19926							var currentVideo = JSON.parse( currentGalleryItem.video ),
19927								download_name = currentVideo.source[0].src;
19928							$download.attr('href', download_name).removeAttr('download');
19929						} else {
19930							var download_url = currentGalleryItem.downloadUrl || currentGalleryItem.src,
19931								download_name = download_url.substring(download_url.lastIndexOf('/')+1);
19932							$download.attr('download', download_name);
19933						}
19934						// $download.attr('download', currentGalleryItem.download);
19935						//Uncode edit ##END##
19936					}
19937				}
19938			}
19939		};
19940		LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) {
19941			var _this = this;
19942			if (this.lGalleryOn) {
19943				previousSlideItem.addClass('lg-slide-progress');
19944			}
19945			setTimeout(function () {
19946				// remove all transitions
19947				_this.outer.addClass('lg-no-trans');
19948				_this.outer
19949					.find('.lg-item')
19950					.removeClass('lg-prev-slide lg-next-slide');
19951				if (direction === 'prev') {
19952					//prevslide
19953					currentSlideItem.addClass('lg-prev-slide');
19954					previousSlideItem.addClass('lg-next-slide');
19955				}
19956				else {
19957					// next slide
19958					currentSlideItem.addClass('lg-next-slide');
19959					previousSlideItem.addClass('lg-prev-slide');
19960				}
19961				// give 50 ms for browser to add/remove class
19962				setTimeout(function () {
19963					_this.outer.find('.lg-item').removeClass('lg-current');
19964					currentSlideItem.addClass('lg-current');
19965					// reset all transitions
19966					_this.outer.removeClass('lg-no-trans');
19967				}, 50);
19968			}, this.lGalleryOn ? this.settings.slideDelay : 0);
19969		};
19970		/**
19971		 * Goto a specific slide.
19972		 * @param {Number} index - index of the slide
19973		 * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
19974		 * @param {Boolean} fromThumb - true if slide function called via thumbnail click
19975		 * @param {String} direction - Direction of the slide(next/prev)
19976		 * @category lGPublicMethods
19977		 * @example
19978		 *  const plugin = lightGallery();
19979		 *  // to go to 3rd slide
19980		 *  plugin.slide(2);
19981		 *
19982		 */
19983		LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) {
19984			var _this = this;
19985			var prevIndex = this.getPreviousSlideIndex();
19986			this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);
19987			// Prevent multiple call, Required for hsh plugin
19988			if (this.lGalleryOn && prevIndex === index) {
19989				return;
19990			}
19991			var numberOfGalleryItems = this.galleryItems.length;
19992			if (!this.lgBusy) {
19993				if (this.settings.counter) {
19994					this.updateCurrentCounter(index);
19995				}
19996				var currentSlideItem = this.getSlideItem(index);
19997				var previousSlideItem_1 = this.getSlideItem(prevIndex);
19998				var currentGalleryItem = this.galleryItems[index];
19999				var videoInfo = currentGalleryItem.__slideVideoInfo;
20000				this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem));
20001				this.setDownloadValue(index);
20002				if (videoInfo) {
20003					var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom;
20004					//Uncode edit ##START##
20005					var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize, this.galleryItems[this.index]);
20006					// var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize);
20007					//Uncode edit ##END##
20008					this.resizeVideoSlide(index, videoSize);
20009				}
20010				this.LGel.trigger(lGEvents.beforeSlide, {
20011					prevIndex: prevIndex,
20012					index: index,
20013					fromTouch: !!fromTouch,
20014					fromThumb: !!fromThumb,
20015					//Uncode edit ##START##
20016					currentSlide: currentSlideItem,
20017					previousSlide: previousSlideItem_1,
20018					info: currentGalleryItem,
20019					item: this.items[index]
20020					//Uncode edit ##END##
20021				});
20022				this.lgBusy = true;
20023				clearTimeout(this.hideBarTimeout);
20024				this.arrowDisable(index);
20025				if (!direction) {
20026					if (index < prevIndex) {
20027						direction = 'prev';
20028					}
20029					else if (index > prevIndex) {
20030						direction = 'next';
20031					}
20032				}
20033				if (!fromTouch) {
20034					this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1);
20035				}
20036				else {
20037					this.outer
20038						.find('.lg-item')
20039						.removeClass('lg-prev-slide lg-current lg-next-slide');
20040					var touchPrev = void 0;
20041					var touchNext = void 0;
20042					if (numberOfGalleryItems > 2) {
20043						touchPrev = index - 1;
20044						touchNext = index + 1;
20045						if (index === 0 && prevIndex === numberOfGalleryItems - 1) {
20046							// next slide
20047							touchNext = 0;
20048							touchPrev = numberOfGalleryItems - 1;
20049						}
20050						else if (index === numberOfGalleryItems - 1 &&
20051							prevIndex === 0) {
20052							// prev slide
20053							touchNext = 0;
20054							touchPrev = numberOfGalleryItems - 1;
20055						}
20056					}
20057					else {
20058						touchPrev = 0;
20059						touchNext = 1;
20060					}
20061					if (direction === 'prev') {
20062						this.getSlideItem(touchNext).addClass('lg-next-slide');
20063					}
20064					else {
20065						this.getSlideItem(touchPrev).addClass('lg-prev-slide');
20066					}
20067					currentSlideItem.addClass('lg-current');
20068				}
20069				// Do not put load content in set timeout as it needs to load immediately when the gallery is opened
20070				if (!this.lGalleryOn) {
20071					this.loadContent(index, true);
20072				}
20073				else {
20074					setTimeout(function () {
20075						_this.loadContent(index, true);
20076						// Add title if this.settings.appendSubHtmlTo === lg-sub-html
20077						if (_this.settings.appendSubHtmlTo !== '.lg-item') {
20078							_this.addHtml(index);
20079						}
20080					}, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));
20081				}
20082				setTimeout(function () {
20083					_this.lgBusy = false;
20084					previousSlideItem_1.removeClass('lg-slide-progress');
20085					_this.LGel.trigger(lGEvents.afterSlide, {
20086						prevIndex: prevIndex,
20087						index: index,
20088						fromTouch: fromTouch,
20089						fromThumb: fromThumb,
20090					});
20091				}, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));
20092			}
20093			this.index = index;
20094		};
20095		LightGallery.prototype.updateCurrentCounter = function (index) {
20096			this.getElementById('lg-counter-current').html(index + 1 + '');
20097		};
20098		LightGallery.prototype.updateCounterTotal = function () {
20099			this.getElementById('lg-counter-all').html(this.galleryItems.length + '');
20100		};
20101		LightGallery.prototype.getSlideType = function (item) {
20102			if (item.__slideVideoInfo) {
20103				return 'video';
20104			}
20105			else if (item.iframe) {
20106				return 'iframe';
20107			}
20108			//Uncode edit ##START##
20109			else if (typeof item.src !== '' && item.src.search(/.mp3|.m4a/i) > -1) {
20110				return 'audio';
20111			}
20112			//Uncode edit ##END##
20113			else {
20114				return 'image';
20115			}
20116		};
20117		LightGallery.prototype.touchMove = function (startCoords, endCoords, e) {
20118			var distanceX = endCoords.pageX - startCoords.pageX;
20119			var distanceY = endCoords.pageY - startCoords.pageY;
20120			var allowSwipe = false;
20121			if (this.swipeDirection) {
20122				allowSwipe = true;
20123			}
20124			else {
20125				if (Math.abs(distanceX) > 15) {
20126					this.swipeDirection = 'horizontal';
20127					allowSwipe = true;
20128				}
20129				else if (Math.abs(distanceY) > 15) {
20130					this.swipeDirection = 'vertical';
20131					allowSwipe = true;
20132				}
20133			}
20134			if (!allowSwipe) {
20135				return;
20136			}
20137			var $currentSlide = this.getSlideItem(this.index);
20138			if (this.swipeDirection === 'horizontal') {
20139				e === null || e === void 0 ? void 0 : e.preventDefault();
20140				// reset opacity and transition duration
20141				this.outer.addClass('lg-dragging');
20142				// move current slide
20143				this.setTranslate($currentSlide, distanceX, 0);
20144				// move next and prev slide with current slide
20145				var width = $currentSlide.get().offsetWidth;
20146				var slideWidthAmount = (width * 15) / 100;
20147				var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100);
20148				this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0);
20149				this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0);
20150			}
20151			else if (this.swipeDirection === 'vertical') {
20152				if (this.settings.swipeToClose) {
20153					e === null || e === void 0 ? void 0 : e.preventDefault();
20154					this.$container.addClass('lg-dragging-vertical');
20155					var opacity = 1 - Math.abs(distanceY) / window.innerHeight;
20156					this.$backdrop.css('opacity', opacity);
20157					var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2);
20158					this.setTranslate($currentSlide, 0, distanceY, scale, scale);
20159					if (Math.abs(distanceY) > 100) {
20160						this.outer
20161							.addClass('lg-hide-items')
20162							.removeClass('lg-components-open');
20163					}
20164				}
20165			}
20166		};
20167		LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) {
20168			var _this = this;
20169			var distance;
20170			// keep slide animation for any mode while dragg/swipe
20171			if (this.settings.mode !== 'lg-slide') {
20172				this.outer.addClass('lg-slide');
20173			}
20174			// set transition duration
20175			setTimeout(function () {
20176				_this.$container.removeClass('lg-dragging-vertical');
20177				_this.outer
20178					.removeClass('lg-dragging lg-hide-items')
20179					.addClass('lg-components-open');
20180				var triggerClick = true;
20181				if (_this.swipeDirection === 'horizontal') {
20182					distance = endCoords.pageX - startCoords.pageX;
20183					var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX);
20184					if (distance < 0 &&
20185						distanceAbs > _this.settings.swipeThreshold) {
20186						_this.goToNextSlide(true);
20187						triggerClick = false;
20188					}
20189					else if (distance > 0 &&
20190						distanceAbs > _this.settings.swipeThreshold) {
20191						_this.goToPrevSlide(true);
20192						triggerClick = false;
20193					}
20194				}
20195				else if (_this.swipeDirection === 'vertical') {
20196					distance = Math.abs(endCoords.pageY - startCoords.pageY);
20197					if (_this.settings.closable &&
20198						_this.settings.swipeToClose &&
20199						distance > 100) {
20200						_this.closeGallery();
20201						return;
20202					}
20203					else {
20204						_this.$backdrop.css('opacity', 1);
20205					}
20206				}
20207				_this.outer.find('.lg-item').removeAttr('style');
20208				if (triggerClick &&
20209					Math.abs(endCoords.pageX - startCoords.pageX) < 5) {
20210					// Trigger click if distance is less than 5 pix
20211					var target = $LG(event.target);
20212					if (_this.isPosterElement(target)) {
20213						_this.LGel.trigger(lGEvents.posterClick);
20214					}
20215				}
20216				_this.swipeDirection = undefined;
20217			});
20218			// remove slide class once drag/swipe is completed if mode is not slide
20219			setTimeout(function () {
20220				if (!_this.outer.hasClass('lg-dragging') &&
20221					_this.settings.mode !== 'lg-slide') {
20222					_this.outer.removeClass('lg-slide');
20223				}
20224			}, this.settings.speed + 100);
20225		};
20226		LightGallery.prototype.enableSwipe = function () {
20227			var _this = this;
20228			var startCoords = {};
20229			var endCoords = {};
20230			var isMoved = false;
20231			var isSwiping = false;
20232			if (this.settings.enableSwipe) {
20233				this.$inner.on('touchstart.lg', function (e) {
20234					_this.dragOrSwipeEnabled = true;
20235					var $item = _this.getSlideItem(_this.index);
20236					if (($LG(e.target).hasClass('lg-item') ||
20237						$item.get().contains(e.target)) &&
20238						!_this.outer.hasClass('lg-zoomed') &&
20239						!_this.lgBusy &&
20240						e.targetTouches.length === 1) {
20241						isSwiping = true;
20242						_this.touchAction = 'swipe';
20243						_this.manageSwipeClass();
20244						startCoords = {
20245							pageX: e.targetTouches[0].pageX,
20246							pageY: e.targetTouches[0].pageY,
20247						};
20248					}
20249				});
20250				this.$inner.on('touchmove.lg', function (e) {
20251					if (isSwiping &&
20252						_this.touchAction === 'swipe' &&
20253						e.targetTouches.length === 1) {
20254						endCoords = {
20255							pageX: e.targetTouches[0].pageX,
20256							pageY: e.targetTouches[0].pageY,
20257						};
20258						_this.touchMove(startCoords, endCoords, e);
20259						isMoved = true;
20260					}
20261				});
20262				this.$inner.on('touchend.lg', function (event) {
20263					if (_this.touchAction === 'swipe') {
20264						if (isMoved) {
20265							isMoved = false;
20266							_this.touchEnd(endCoords, startCoords, event);
20267						}
20268						else if (isSwiping) {
20269							var target = $LG(event.target);
20270							if (_this.isPosterElement(target)) {
20271								_this.LGel.trigger(lGEvents.posterClick);
20272							}
20273						}
20274						_this.touchAction = undefined;
20275						isSwiping = false;
20276					}
20277				});
20278			}
20279		};
20280		LightGallery.prototype.enableDrag = function () {
20281			var _this = this;
20282			var startCoords = {};
20283			var endCoords = {};
20284			var isDraging = false;
20285			var isMoved = false;
20286			if (this.settings.enableDrag) {
20287				this.outer.on('mousedown.lg', function (e) {
20288					_this.dragOrSwipeEnabled = true;
20289					var $item = _this.getSlideItem(_this.index);
20290					if ($LG(e.target).hasClass('lg-item') ||
20291						$item.get().contains(e.target)) {
20292						if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) {
20293							e.preventDefault();
20294							if (!_this.lgBusy) {
20295								_this.manageSwipeClass();
20296								startCoords = {
20297									pageX: e.pageX,
20298									pageY: e.pageY,
20299								};
20300								isDraging = true;
20301								// ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
20302								_this.outer.get().scrollLeft += 1;
20303								_this.outer.get().scrollLeft -= 1;
20304								// *
20305								_this.outer
20306									.removeClass('lg-grab')
20307									.addClass('lg-grabbing');
20308								_this.LGel.trigger(lGEvents.dragStart);
20309							}
20310						}
20311					}
20312				});
20313				$LG(window).on("mousemove.lg.global" + this.lgId, function (e) {
20314					if (isDraging && _this.lgOpened) {
20315						isMoved = true;
20316						endCoords = {
20317							pageX: e.pageX,
20318							pageY: e.pageY,
20319						};
20320						_this.touchMove(startCoords, endCoords);
20321						_this.LGel.trigger(lGEvents.dragMove);
20322					}
20323				});
20324				$LG(window).on("mouseup.lg.global" + this.lgId, function (event) {
20325					if (!_this.lgOpened) {
20326						return;
20327					}
20328					var target = $LG(event.target);
20329					if (isMoved) {
20330						isMoved = false;
20331						_this.touchEnd(endCoords, startCoords, event);
20332						_this.LGel.trigger(lGEvents.dragEnd);
20333					}
20334					else if (_this.isPosterElement(target)) {
20335						_this.LGel.trigger(lGEvents.posterClick);
20336					}
20337					// Prevent execution on click
20338					if (isDraging) {
20339						isDraging = false;
20340						_this.outer.removeClass('lg-grabbing').addClass('lg-grab');
20341					}
20342				});
20343			}
20344		};
20345		LightGallery.prototype.triggerPosterClick = function () {
20346			var _this = this;
20347			this.$inner.on('click.lg', function (event) {
20348				if (!_this.dragOrSwipeEnabled &&
20349					_this.isPosterElement($LG(event.target))) {
20350					_this.LGel.trigger(lGEvents.posterClick);
20351				}
20352			});
20353		};
20354		LightGallery.prototype.manageSwipeClass = function () {
20355			var _touchNext = this.index + 1;
20356			var _touchPrev = this.index - 1;
20357			if (this.settings.loop && this.galleryItems.length > 2) {
20358				if (this.index === 0) {
20359					_touchPrev = this.galleryItems.length - 1;
20360				}
20361				else if (this.index === this.galleryItems.length - 1) {
20362					_touchNext = 0;
20363				}
20364			}
20365			this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');
20366			if (_touchPrev > -1) {
20367				this.getSlideItem(_touchPrev).addClass('lg-prev-slide');
20368			}
20369			this.getSlideItem(_touchNext).addClass('lg-next-slide');
20370		};
20371		/**
20372		 * Go to next slide
20373		 * @param {Boolean} fromTouch - true if slide function called via touch event
20374		 * @category lGPublicMethods
20375		 * @example
20376		 *  const plugin = lightGallery();
20377		 *  plugin.goToNextSlide();
20378		 * @see <a href="/demos/methods/">Demo</a>
20379		 */
20380		LightGallery.prototype.goToNextSlide = function (fromTouch) {
20381			var _this = this;
20382			var _loop = this.settings.loop;
20383			if (fromTouch && this.galleryItems.length < 3) {
20384				_loop = false;
20385			}
20386			if (!this.lgBusy) {
20387				if (this.index + 1 < this.galleryItems.length) {
20388					this.index++;
20389					this.LGel.trigger(lGEvents.beforeNextSlide, {
20390						index: this.index,
20391					});
20392					this.slide(this.index, !!fromTouch, false, 'next');
20393				}
20394				else {
20395					if (_loop) {
20396						this.index = 0;
20397						this.LGel.trigger(lGEvents.beforeNextSlide, {
20398							index: this.index,
20399						});
20400						this.slide(this.index, !!fromTouch, false, 'next');
20401					}
20402					else if (this.settings.slideEndAnimation && !fromTouch) {
20403						this.outer.addClass('lg-right-end');
20404						setTimeout(function () {
20405							_this.outer.removeClass('lg-right-end');
20406						}, 400);
20407					}
20408				}
20409			}
20410		};
20411		/**
20412		 * Go to previous slides
20413		 * @param {Boolean} fromTouch - true if slide function called via touch event
20414		 * @category lGPublicMethods
20415		 * @example
20416		 *  const plugin = lightGallery({});
20417		 *  plugin.goToPrevSlide();
20418		 * @see <a href="/demos/methods/">Demo</a>
20419		 *
20420		 */
20421		LightGallery.prototype.goToPrevSlide = function (fromTouch) {
20422			var _this = this;
20423			var _loop = this.settings.loop;
20424			if (fromTouch && this.galleryItems.length < 3) {
20425				_loop = false;
20426			}
20427			if (!this.lgBusy) {
20428				if (this.index > 0) {
20429					this.index--;
20430					this.LGel.trigger(lGEvents.beforePrevSlide, {
20431						index: this.index,
20432						fromTouch: fromTouch,
20433					});
20434					this.slide(this.index, !!fromTouch, false, 'prev');
20435				}
20436				else {
20437					if (_loop) {
20438						this.index = this.galleryItems.length - 1;
20439						this.LGel.trigger(lGEvents.beforePrevSlide, {
20440							index: this.index,
20441							fromTouch: fromTouch,
20442						});
20443						this.slide(this.index, !!fromTouch, false, 'prev');
20444					}
20445					else if (this.settings.slideEndAnimation && !fromTouch) {
20446						this.outer.addClass('lg-left-end');
20447						setTimeout(function () {
20448							_this.outer.removeClass('lg-left-end');
20449						}, 400);
20450					}
20451				}
20452			}
20453		};
20454		LightGallery.prototype.keyPress = function () {
20455			var _this = this;
20456			$LG(window).on("keydown.lg.global" + this.lgId, function (e) {
20457				if (_this.lgOpened &&
20458					_this.settings.escKey === true &&
20459					e.keyCode === 27) {
20460					e.preventDefault();
20461					if (_this.settings.allowMediaOverlap &&
20462						_this.outer.hasClass('lg-can-toggle') &&
20463						_this.outer.hasClass('lg-components-open')) {
20464						_this.outer.removeClass('lg-components-open');
20465					}
20466					else {
20467						_this.closeGallery();
20468					}
20469				}
20470				if (_this.lgOpened && _this.galleryItems.length > 1) {
20471					if (e.keyCode === 37) {
20472						e.preventDefault();
20473						_this.goToPrevSlide();
20474					}
20475					if (e.keyCode === 39) {
20476						e.preventDefault();
20477						_this.goToNextSlide();
20478					}
20479				}
20480			});
20481		};
20482		LightGallery.prototype.arrow = function () {
20483			var _this = this;
20484			this.getElementById('lg-prev').on('click.lg', function () {
20485				_this.goToPrevSlide();
20486			});
20487			this.getElementById('lg-next').on('click.lg', function () {
20488				_this.goToNextSlide();
20489			});
20490		};
20491		LightGallery.prototype.arrowDisable = function (index) {
20492			// Disable arrows if settings.hideControlOnEnd is true
20493			if (!this.settings.loop && this.settings.hideControlOnEnd) {
20494				var $prev = this.getElementById('lg-prev');
20495				var $next = this.getElementById('lg-next');
20496				if (index + 1 === this.galleryItems.length) {
20497					$next.attr('disabled', 'disabled').addClass('disabled');
20498				}
20499				else {
20500					$next.removeAttr('disabled').removeClass('disabled');
20501				}
20502				if (index === 0) {
20503					$prev.attr('disabled', 'disabled').addClass('disabled');
20504				}
20505				else {
20506					$prev.removeAttr('disabled').removeClass('disabled');
20507				}
20508			}
20509		};
20510		LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) {
20511			if (scaleX === void 0) { scaleX = 1; }
20512			if (scaleY === void 0) { scaleY = 1; }
20513			$el.css('transform', 'translate3d(' +
20514				xValue +
20515				'px, ' +
20516				yValue +
20517				'px, 0px) scale3d(' +
20518				scaleX +
20519				', ' +
20520				scaleY +
20521				', 1)');
20522		};
20523		LightGallery.prototype.mousewheel = function () {
20524			var _this = this;
20525			var lastCall = 0;
20526			this.outer.on('wheel.lg', function (e) {
20527				if (!e.deltaY || _this.galleryItems.length < 2) {
20528					return;
20529				}
20530				e.preventDefault();
20531				var now = new Date().getTime();
20532				if (now - lastCall < 1000) {
20533					return;
20534				}
20535				lastCall = now;
20536				if (e.deltaY > 0) {
20537					_this.goToNextSlide();
20538				}
20539				else if (e.deltaY < 0) {
20540					_this.goToPrevSlide();
20541				}
20542			});
20543		};
20544		LightGallery.prototype.isSlideElement = function (target) {
20545			return (target.hasClass('lg-outer') ||
20546				target.hasClass('lg-item') ||
20547				target.hasClass('lg-img-wrap'));
20548		};
20549		LightGallery.prototype.isPosterElement = function (target) {
20550			var playButton = this.getSlideItem(this.index)
20551				.find('.lg-video-play-button')
20552				.get();
20553			return (target.hasClass('lg-video-poster') ||
20554				target.hasClass('lg-video-play-button') ||
20555				(playButton && playButton.contains(target.get())));
20556		};
20557		/**
20558		 * Maximize minimize inline gallery.
20559		 * @category lGPublicMethods
20560		 */
20561		LightGallery.prototype.toggleMaximize = function () {
20562			var _this = this;
20563			this.getElementById('lg-maximize').on('click.lg', function () {
20564				_this.$container.toggleClass('lg-inline');
20565				_this.refreshOnResize();
20566			});
20567		};
20568		LightGallery.prototype.invalidateItems = function () {
20569			for (var index = 0; index < this.items.length; index++) {
20570				var element = this.items[index];
20571				var $element = $LG(element);
20572				$element.off("click.lgcustom-item-" + $element.attr('data-lg-id'));
20573			}
20574		};
20575		LightGallery.prototype.trapFocus = function () {
20576			var _this = this;
20577			this.$container.get().focus({
20578				preventScroll: true,
20579			});
20580			$LG(window).on("keydown.lg.global" + this.lgId, function (e) {
20581				if (!_this.lgOpened) {
20582					return;
20583				}
20584				var isTabPressed = e.key === 'Tab' || e.keyCode === 9;
20585				if (!isTabPressed) {
20586					return;
20587				}
20588				var focusableEls = utils.getFocusableElements(_this.$container.get());
20589				var firstFocusableEl = focusableEls[0];
20590				var lastFocusableEl = focusableEls[focusableEls.length - 1];
20591				if (e.shiftKey) {
20592					if (document.activeElement === firstFocusableEl) {
20593						lastFocusableEl.focus();
20594						e.preventDefault();
20595					}
20596				}
20597				else {
20598					if (document.activeElement === lastFocusableEl) {
20599						firstFocusableEl.focus();
20600						e.preventDefault();
20601					}
20602				}
20603			});
20604		};
20605		LightGallery.prototype.manageCloseGallery = function () {
20606			var _this = this;
20607			if (!this.settings.closable)
20608				return;
20609			var mousedown = false;
20610			this.getElementById('lg-close').on('click.lg', function () {
20611				_this.closeGallery();
20612			});
20613			if (this.settings.closeOnTap) {
20614				// If you drag the slide and release outside gallery gets close on chrome
20615				// for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
20616				this.outer.on('mousedown.lg', function (e) {
20617					var target = $LG(e.target);
20618					if (_this.isSlideElement(target)) {
20619						mousedown = true;
20620					}
20621					else {
20622						mousedown = false;
20623					}
20624				});
20625				this.outer.on('mousemove.lg', function () {
20626					mousedown = false;
20627				});
20628				this.outer.on('mouseup.lg', function (e) {
20629					var target = $LG(e.target);
20630					if (_this.isSlideElement(target) && mousedown) {
20631						if (!_this.outer.hasClass('lg-dragging')) {
20632							_this.closeGallery();
20633						}
20634					}
20635				});
20636			}
20637		};
20638		/**
20639		 * Close lightGallery if it is opened.
20640		 *
20641		 * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery
20642		 * @return returns the estimated time to close gallery completely including the close animation duration
20643		 * @category lGPublicMethods
20644		 * @example
20645		 *  const plugin = lightGallery();
20646		 *  plugin.closeGallery();
20647		 *
20648		 */
20649		LightGallery.prototype.closeGallery = function (force) {
20650			var _this = this;
20651			if (!this.lgOpened || (!this.settings.closable && !force)) {
20652				return 0;
20653			}
20654			this.LGel.trigger(lGEvents.beforeClose);
20655			if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {
20656				$LG(window).scrollTop(this.prevScrollTop);
20657			}
20658			var currentItem = this.items[this.index];
20659			var transform;
20660			if (this.zoomFromOrigin && currentItem) {
20661				var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom;
20662				var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster;
20663				//Uncode edit ##START##
20664				var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize, this.galleryItems[this.index]);
20665				// var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize);
20666				//Uncode edit ##END##
20667				transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize);
20668			}
20669			if (this.zoomFromOrigin && transform) {
20670				this.outer.addClass('lg-closing lg-zoom-from-image');
20671				this.getSlideItem(this.index)
20672					.addClass('lg-start-end-progress')
20673					.css('transition-duration', this.settings.startAnimationDuration + 'ms')
20674					.css('transform', transform);
20675			}
20676			else {
20677				this.outer.addClass('lg-hide-items');
20678				// lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true
20679				// If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts
20680				this.outer.removeClass('lg-zoom-from-image');
20681			}
20682			// Unbind all events added by lightGallery
20683			// @todo
20684			//this.$el.off('.lg.tm');
20685			this.destroyModules();
20686			this.lGalleryOn = false;
20687			this.isDummyImageRemoved = false;
20688			this.zoomFromOrigin = this.settings.zoomFromOrigin;
20689			clearTimeout(this.hideBarTimeout);
20690			this.hideBarTimeout = false;
20691			$LG('html').removeClass('lg-on');
20692			this.outer.removeClass('lg-visible lg-components-open');
20693			// Resetting opacity to 0 isd required as  vertical swipe to close function adds inline opacity.
20694			this.$backdrop.removeClass('in').css('opacity', 0);
20695			var removeTimeout = this.zoomFromOrigin && transform
20696				? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration)
20697				: this.settings.backdropDuration;
20698			this.$container.removeClass('lg-show-in');
20699			// Once the closign animation is completed and gallery is invisible
20700			setTimeout(function () {
20701				if (_this.zoomFromOrigin && transform) {
20702					_this.outer.removeClass('lg-zoom-from-image');
20703				}
20704				_this.$container.removeClass('lg-show');
20705				// Reset scrollbar
20706				_this.resetScrollBar();
20707				// Need to remove inline opacity as it is used in the stylesheet as well
20708				_this.$backdrop
20709					.removeAttr('style')
20710					.css('transition-duration', _this.settings.backdropDuration + 'ms');
20711				_this.outer.removeClass("lg-closing " + _this.settings.startClass);
vendor: 6,259 bytes, lines 20712-20915
20712				_this.getSlideItem(_this.index).removeClass('lg-start-end-progress');
20713				_this.$inner.empty();
20714				if (_this.lgOpened) {
20715					_this.LGel.trigger(lGEvents.afterClose, {
20716						instance: _this,
20717					});
20718				}
20719				if (_this.$container.get()) {
20720					_this.$container.get().blur();
20721				}
20722				_this.lgOpened = false;
20723			}, removeTimeout + 100);
20724			return removeTimeout + 100;
20725		};
20726		LightGallery.prototype.initModules = function () {
20727			this.plugins.forEach(function (module) {
20728				try {
20729					module.init();
20730				}
20731				catch (err) {
20732					console.warn("lightGallery:- make sure lightGallery module is properly initiated");
20733				}
20734			});
20735		};
20736		LightGallery.prototype.destroyModules = function (destroy) {
20737			this.plugins.forEach(function (module) {
20738				try {
20739					if (destroy) {
20740						module.destroy();
20741					}
20742					else {
20743						module.closeGallery && module.closeGallery();
20744					}
20745				}
20746				catch (err) {
20747					console.warn("lightGallery:- make sure lightGallery module is properly destroyed");
20748				}
20749			});
20750		};
20751		/**
20752		 * Refresh lightGallery with new set of children.
20753		 *
20754		 * @description This is useful to update the gallery when the child elements are changed without calling destroy method.
20755		 *
20756		 * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery
20757		 * @see <a href="/demos/dynamic-mode/">Demo</a>
20758		 * @category lGPublicMethods
20759		 * @example
20760		 *  const plugin = lightGallery();
20761		 *  // Delete or add children, then call
20762		 *  plugin.refresh();
20763		 *
20764		 */
20765		LightGallery.prototype.refresh = function (galleryItems) {
20766			if (!this.settings.dynamic) {
20767				this.invalidateItems();
20768			}
20769			if (galleryItems) {
20770				this.galleryItems = galleryItems;
20771			}
20772			else {
20773				this.galleryItems = this.getItems();
20774			}
20775			this.updateControls();
20776			this.openGalleryOnItemClick();
20777			this.LGel.trigger(lGEvents.updateSlides);
20778		};
20779		LightGallery.prototype.updateControls = function () {
20780			this.addSlideVideoInfo(this.galleryItems);
20781			this.updateCounterTotal();
20782			this.manageSingleSlideClassName();
20783		};
20784		/**
20785		 * Destroy lightGallery.
20786		 * Destroy lightGallery and its plugin instances completely
20787		 *
20788		 * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.
20789		 * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.
20790		 * You can use refresh method most of the times.
20791		 * @category lGPublicMethods
20792		 * @example
20793		 *  const plugin = lightGallery();
20794		 *  plugin.destroy();
20795		 *
20796		 */
20797		LightGallery.prototype.destroy = function () {
20798			var _this = this;
20799			var closeTimeout = this.closeGallery(true);
20800			setTimeout(function () {
20801				_this.destroyModules(true);
20802				if (!_this.settings.dynamic) {
20803					_this.invalidateItems();
20804				}
20805				$LG(window).off(".lg.global" + _this.lgId);
20806				_this.LGel.off('.lg');
20807				_this.$container.remove();
20808			}, closeTimeout);
20809			return closeTimeout;
20810		};
20811		return LightGallery;
20812	}());
20813
20814	function lightGallery(el, options) {
20815		return new LightGallery(el, options);
20816	}
20817
20818	return lightGallery;
20819
20820})));
20821
20822/*!
20823 * lightgallery | 2.5.0 | June 13th 2022
20824 * http://www.lightgalleryjs.com/
20825 * Copyright (c) 2020 Sachin Neravath;
20826 * @license GPLv3
20827 */
20828
20829(function (global, factory) {
20830	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
20831	typeof define === 'function' && define.amd ? define(factory) :
20832	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgZoom = factory());
20833}(this, (function () { 'use strict';
20834
20835	/*! *****************************************************************************
20836	Copyright (c) Microsoft Corporation.
20837
20838	Permission to use, copy, modify, and/or distribute this software for any
20839	purpose with or without fee is hereby granted.
20840
20841	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
20842	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20843	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
20844	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
20845	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
20846	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20847	PERFORMANCE OF THIS SOFTWARE.
20848	***************************************************************************** */
20849
20850	var __assign = function() {
20851		__assign = Object.assign || function __assign(t) {
20852			for (var s, i = 1, n = arguments.length; i < n; i++) {
20853				s = arguments[i];
20854				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
20855			}
20856			return t;
20857		};
20858		return __assign.apply(this, arguments);
20859	};
20860
20861	var zoomSettings = {
20862		scale: 1,
20863		zoom: true,
20864		actualSize: true,
20865		showZoomInOutIcons: false,
20866		actualSizeIcons: {
20867			zoomIn: 'lg-zoom-in',
20868			zoomOut: 'lg-zoom-out',
20869		},
20870		enableZoomAfter: 300,
20871		zoomPluginStrings: {
20872			zoomIn: 'Zoom in',
20873			zoomOut: 'Zoom out',
20874			viewActualSize: 'View actual size',
20875		},
20876	};
20877
20878	/**
20879	 * List of lightGallery events
20880	 * All events should be documented here
20881	 * Below interfaces are used to build the website documentations
20882	 * */
20883	var lGEvents = {
20884		afterAppendSlide: 'lgAfterAppendSlide',
20885		init: 'lgInit',
20886		hasVideo: 'lgHasVideo',
20887		containerResize: 'lgContainerResize',
20888		updateSlides: 'lgUpdateSlides',
20889		afterAppendSubHtml: 'lgAfterAppendSubHtml',
20890		beforeOpen: 'lgBeforeOpen',
20891		afterOpen: 'lgAfterOpen',
20892		slideItemLoad: 'lgSlideItemLoad',
20893		beforeSlide: 'lgBeforeSlide',
20894		afterSlide: 'lgAfterSlide',
20895		posterClick: 'lgPosterClick',
20896		dragStart: 'lgDragStart',
20897		dragMove: 'lgDragMove',
20898		dragEnd: 'lgDragEnd',
20899		beforeNextSlide: 'lgBeforeNextSlide',
20900		beforePrevSlide: 'lgBeforePrevSlide',
20901		beforeClose: 'lgBeforeClose',
20902		afterClose: 'lgAfterClose',
20903		rotateLeft: 'lgRotateLeft',
20904		rotateRight: 'lgRotateRight',
20905		flipHorizontal: 'lgFlipHorizontal',
20906		flipVertical: 'lgFlipVertical',
20907		autoplay: 'lgAutoplay',
20908		autoplayStart: 'lgAutoplayStart',
20909		autoplayStop: 'lgAutoplayStop',
20910	};
20911
20912	var Zoom = /** @class */ (function () {
20913		function Zoom(instance, $LG) {
20914			// get lightGallery core plugin instance
20915			this.core = instance;
20916			this.$LG = $LG;
20917			this.settings = __assign(__assign({}, zoomSettings), this.core.settings);
20918			return this;
20919		}
20920		// Append Zoom controls. Actual size, Zoom-in, Zoom-out
20921		Zoom.prototype.buildTemplates = function () {
20922			var zoomIcons = this.settings.showZoomInOutIcons
20923				? "<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>"
20924				: '';
20925			if (this.settings.actualSize) {
20926				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>";
20927			}
20928			this.core.outer.addClass('lg-use-transition-for-zoom');
20929			this.core.$toolbar.first().append(zoomIcons);
20930		};
20931		/**
20932		 * @desc Enable zoom option only once the image is completely loaded
20933		 * If zoomFromOrigin is true, Zoom is enabled once the dummy image has been inserted
20934		 *
20935		 * Zoom styles are defined under lg-zoomable CSS class.
20936		 */
20937		Zoom.prototype.enableZoom = function (event) {
20938			var _this = this;
20939			// delay will be 0 except first time
20940			var _speed = this.settings.enableZoomAfter + event.detail.delay;
20941			// set _speed value 0 if gallery opened from direct url and if it is first slide
20942			if (this.$LG('body').first().hasClass('lg-from-hash') &&
20943				event.detail.delay) {
20944				// will execute only once
20945				_speed = 0;
20946			}
20947			else {
20948				// Remove lg-from-hash to enable starting animation.
20949				this.$LG('body').first().removeClass('lg-from-hash');
20950			}
20951			this.zoomableTimeout = setTimeout(function () {
20952				if (!_this.isImageSlide()) {
20953					return;
20954				}
20955				_this.core.getSlideItem(event.detail.index).addClass('lg-zoomable');
20956				if (event.detail.index === _this.core.index) {
20957					_this.setZoomEssentials();
20958				}
20959			}, _speed + 30);
20960		};
20961		Zoom.prototype.enableZoomOnSlideItemLoad = function () {
20962			// Add zoomable class
20963			this.core.LGel.on(lGEvents.slideItemLoad + ".zoom", this.enableZoom.bind(this));
20964		};
20965		Zoom.prototype.getModifier = function (rotateValue, axis, el) {
20966			var originalRotate = rotateValue;
20967			rotateValue = Math.abs(rotateValue);
20968			var transformValues = this.getCurrentTransform(el);
20969			if (!transformValues) {
20970				return 1;
20971			}
20972			var modifier = 1;
20973			if (axis === 'X') {
20974				var flipHorizontalValue = Math.sign(parseFloat(transformValues[0]));
20975				if (rotateValue === 0 || rotateValue === 180) {
20976					modifier = 1;
20977				}
20978				else if (rotateValue === 90) {
20979					if ((originalRotate === -90 && flipHorizontalValue === 1) ||
20980						(originalRotate === 90 && flipHorizontalValue === -1)) {
20981						modifier = -1;
20982					}
20983					else {
20984						modifier = 1;
20985					}
20986				}
20987				modifier = modifier * flipHorizontalValue;
20988			}
20989			else {
20990				var flipVerticalValue = Math.sign(parseFloat(transformValues[3]));
20991				if (rotateValue === 0 || rotateValue === 180) {
20992					modifier = 1;
20993				}
20994				else if (rotateValue === 90) {
20995					var sinX = parseFloat(transformValues[1]);
20996					var sinMinusX = parseFloat(transformValues[2]);
20997					modifier = Math.sign(sinX * sinMinusX * originalRotate * flipVerticalValue);
20998				}
20999				modifier = modifier * flipVerticalValue;
21000			}
21001			return modifier;
21002		};
21003		Zoom.prototype.getImageSize = function ($image, rotateValue, axis) {
21004			var imageSizes = {
21005				y: 'offsetHeight',
21006				x: 'offsetWidth',
21007			};
21008			if (Math.abs(rotateValue) === 90) {
21009				// Swap axis
21010				if (axis === 'x') {
21011					axis = 'y';
21012				}
21013				else {
21014					axis = 'x';
21015				}
21016			}
21017			return $image[imageSizes[axis]];
21018		};
21019		Zoom.prototype.getDragCords = function (e, rotateValue) {
21020			if (rotateValue === 90) {
21021				return {
21022					x: e.pageY,
21023					y: e.pageX,
21024				};
21025			}
21026			else {
21027				return {
21028					x: e.pageX,
21029					y: e.pageY,
21030				};
21031			}
21032		};
21033		Zoom.prototype.getSwipeCords = function (e, rotateValue) {
21034			var x = e.targetTouches[0].pageX;
21035			var y = e.targetTouches[0].pageY;
21036			if (rotateValue === 90) {
21037				return {
21038					x: y,
21039					y: x,
21040				};
21041			}
21042			else {
21043				return {
21044					x: x,
21045					y: y,
21046				};
21047			}
21048		};
21049		Zoom.prototype.getDragAllowedAxises = function (rotateValue, scale) {
21050			scale = scale || this.scale || 1;
21051			var allowY = this.imageYSize * scale > this.containerRect.height;
21052			var allowX = this.imageXSize * scale > this.containerRect.width;
21053			if (rotateValue === 90) {
21054				return {
21055					allowX: allowY,
21056					allowY: allowX,
21057				};
21058			}
21059			else {
21060				return {
21061					allowX: allowX,
21062					allowY: allowY,
21063				};
21064			}
21065		};
21066		/**
21067		 *
21068		 * @param {Element} el
21069		 * @return matrix(cos(X), sin(X), -sin(X), cos(X), 0, 0);
21070		 * Get the current transform value
21071		 */
21072		Zoom.prototype.getCurrentTransform = function (el) {
21073			if (!el) {
21074				return;
21075			}
21076			var st = window.getComputedStyle(el, null);
21077			var tm = st.getPropertyValue('-webkit-transform') ||
21078				st.getPropertyValue('-moz-transform') ||
21079				st.getPropertyValue('-ms-transform') ||
21080				st.getPropertyValue('-o-transform') ||
21081				st.getPropertyValue('transform') ||
21082				'none';
21083			if (tm !== 'none') {
21084				return tm.split('(')[1].split(')')[0].split(',');
21085			}
21086			return;
21087		};
21088		Zoom.prototype.getCurrentRotation = function (el) {
21089			if (!el) {
21090				return 0;
21091			}
21092			var values = this.getCurrentTransform(el);
21093			if (values) {
21094				return Math.round(Math.atan2(parseFloat(values[1]), parseFloat(values[0])) *
21095					(180 / Math.PI));
21096				// If you want rotate in 360
21097				//return (angle < 0 ? angle + 360 : angle);
21098			}
21099			return 0;
21100		};
21101		Zoom.prototype.setZoomEssentials = function () {
21102			var $image = this.core
21103				.getSlideItem(this.core.index)
21104				.find('.lg-image')
21105				.first();
21106			var rotateEl = this.core
21107				.getSlideItem(this.core.index)
21108				.find('.lg-img-rotate')
21109				.first()
21110				.get();
21111			this.rotateValue = this.getCurrentRotation(rotateEl);
21112			this.imageYSize = this.getImageSize($image.get(), this.rotateValue, 'y');
21113			this.imageXSize = this.getImageSize($image.get(), this.rotateValue, 'x');
21114			this.containerRect = this.core.outer.get().getBoundingClientRect();
21115			this.modifierX = this.getModifier(this.rotateValue, 'X', rotateEl);
21116			this.modifierY = this.getModifier(this.rotateValue, 'Y', rotateEl);
21117		};
21118		/**
21119		 * @desc Image zoom
21120		 * Translate the wrap and scale the image to get better user experience
21121		 *
21122		 * @param {String} scale - Zoom decrement/increment value
21123		 */
21124		Zoom.prototype.zoomImage = function (scale) {
21125			// Find offset manually to avoid issue after zoom
21126			var offsetX = (this.containerRect.width - this.imageXSize) / 2 +
21127				this.containerRect.left;
21128			var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
21129			var topBottomSpacing = Math.abs(top - bottom) / 2;
21130			var offsetY = (this.containerRect.height -
21131				this.imageYSize -
21132				topBottomSpacing * this.modifierX) /
21133				2 +
21134				this.scrollTop +
21135				this.containerRect.top;
21136			var originalX;
21137			var originalY;
21138			if (scale === 1) {
21139				this.positionChanged = false;
21140			}
21141			var dragAllowedAxises = this.getDragAllowedAxises(Math.abs(this.rotateValue), scale);
21142			var allowY = dragAllowedAxises.allowY, allowX = dragAllowedAxises.allowX;
21143			if (this.positionChanged) {
21144				originalX = this.left / (this.scale - 1);
21145				originalY = this.top / (this.scale - 1);
21146				this.pageX = Math.abs(originalX) + offsetX;
21147				this.pageY = Math.abs(originalY) + offsetY;
21148				this.positionChanged = false;
21149			}
21150			var possibleSwipeCords = this.getPossibleSwipeDragCords(this.rotateValue, scale);
21151			var _x = offsetX - this.pageX;
21152			var _y = offsetY - this.pageY;
21153			var x = (scale - 1) * _x;
21154			var y = (scale - 1) * _y;
21155			if (allowX) {
21156				if (this.isBeyondPossibleLeft(x, possibleSwipeCords.minX)) {
21157					x = possibleSwipeCords.minX;
21158				}
21159				else if (this.isBeyondPossibleRight(x, possibleSwipeCords.maxX)) {
21160					x = possibleSwipeCords.maxX;
21161				}
21162			}
21163			else {
21164				if (scale > 1) {
21165					if (x < possibleSwipeCords.minX) {
21166						x = possibleSwipeCords.minX;
21167					}
21168					else if (x > possibleSwipeCords.maxX) {
21169						x = possibleSwipeCords.maxX;
21170					}
21171				}
21172			}
21173			if (allowY) {
21174				if (this.isBeyondPossibleTop(y, possibleSwipeCords.minY)) {
21175					y = possibleSwipeCords.minY;
21176				}
21177				else if (this.isBeyondPossibleBottom(y, possibleSwipeCords.maxY)) {
21178					y = possibleSwipeCords.maxY;
21179				}
21180			}
21181			else {
21182				// If the translate value based on index of beyond the viewport, utilize the available space to prevent image being cut out
21183				if (scale > 1) {
21184					//If image goes beyond viewport top, use the minim possible translate value
21185					if (y < possibleSwipeCords.minY) {
21186						y = possibleSwipeCords.minY;
21187					}
21188					else if (y > possibleSwipeCords.maxY) {
21189						y = possibleSwipeCords.maxY;
21190					}
21191				}
21192			}
21193			this.setZoomStyles({
21194				x: x,
21195				y: y,
21196				scale: scale,
21197			});
21198		};
21199		/**
21200		 * @desc apply scale3d to image and translate to image wrap
21201		 * @param {style} X,Y and scale
21202		 */
21203		Zoom.prototype.setZoomStyles = function (style) {
21204			var $image = this.core
21205				.getSlideItem(this.core.index)
21206				.find('.lg-image')
21207				.first();
21208			var $dummyImage = this.core.outer
21209				.find('.lg-current .lg-dummy-img')
21210				.first();
21211			var $imageWrap = $image.parent();
21212			this.scale = style.scale;
21213			$image.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');
21214			$dummyImage.css('transform', 'scale3d(' + style.scale + ', ' + style.scale + ', 1)');
21215			var transform = 'translate3d(' + style.x + 'px, ' + style.y + 'px, 0)';
21216			$imageWrap.css('transform', transform);
21217			this.left = style.x;
21218			this.top = style.y;
21219		};
21220		/**
21221		 * @param index - Index of the current slide
21222		 * @param event - event will be available only if the function is called on clicking/taping the imags
21223		 */
21224		Zoom.prototype.setActualSize = function (index, event) {
21225			var _this = this;
21226			// Allow zoom only on image
21227			if (!this.isImageSlide() ||
21228				this.core.outer.hasClass('lg-first-slide-loading')) {
21229				return;
21230			}
21231			var scale = this.getCurrentImageActualSizeScale();
21232			if (this.core.outer.hasClass('lg-zoomed')) {
21233				this.scale = 1;
21234			}
21235			else {
21236				this.scale = this.getScale(scale);
21237			}
21238			this.setPageCords(event);
21239			this.beginZoom(this.scale);
21240			this.zoomImage(this.scale);
21241			setTimeout(function () {
21242				_this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');
21243			}, 10);
21244		};
21245		Zoom.prototype.getNaturalWidth = function (index) {
21246			var $image = this.core.getSlideItem(index).find('.lg-image').first();
21247			var naturalWidth = this.core.galleryItems[index].width;
21248			return naturalWidth
21249				? parseFloat(naturalWidth)
21250				: $image.get().naturalWidth;
21251		};
21252		Zoom.prototype.getActualSizeScale = function (naturalWidth, width) {
21253			var _scale;
21254			var scale;
21255			if (naturalWidth > width) {
21256				_scale = naturalWidth / width;
21257				scale = _scale || 2;
21258			}
21259			else {
21260				scale = 1;
21261			}
21262			return scale;
21263		};
21264		Zoom.prototype.getCurrentImageActualSizeScale = function () {
21265			var $image = this.core
21266				.getSlideItem(this.core.index)
21267				.find('.lg-image')
21268				.first();
21269			var width = $image.get().offsetWidth;
21270			var naturalWidth = this.getNaturalWidth(this.core.index) || width;
21271			return this.getActualSizeScale(naturalWidth, width);
21272		};
21273		Zoom.prototype.getPageCords = function (event) {
21274			var cords = {};
21275			if (event) {
21276				cords.x = event.pageX || event.targetTouches[0].pageX;
21277				cords.y = event.pageY || event.targetTouches[0].pageY;
21278			}
21279			else {
21280				var containerRect = this.core.outer.get().getBoundingClientRect();
21281				cords.x = containerRect.width / 2 + containerRect.left;
21282				cords.y =
21283					containerRect.height / 2 + this.scrollTop + containerRect.top;
21284			}
21285			return cords;
21286		};
21287		Zoom.prototype.setPageCords = function (event) {
21288			var pageCords = this.getPageCords(event);
21289			this.pageX = pageCords.x;
21290			this.pageY = pageCords.y;
21291		};
21292		// If true, zoomed - in else zoomed out
21293		Zoom.prototype.beginZoom = function (scale) {
21294			this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');
21295			if (scale > 1) {
21296				this.core.outer.addClass('lg-zoomed');
21297				var $actualSize = this.core.getElementById('lg-actual-size');
21298				$actualSize
21299					.removeClass(this.settings.actualSizeIcons.zoomIn)
21300					.addClass(this.settings.actualSizeIcons.zoomOut);
21301			}
21302			else {
21303				this.resetZoom();
21304			}
21305			return scale > 1;
21306		};
21307		Zoom.prototype.getScale = function (scale) {
21308			var actualSizeScale = this.getCurrentImageActualSizeScale();
21309			if (scale < 1) {
21310				scale = 1;
21311			}
21312			else if (scale > actualSizeScale) {
21313				scale = actualSizeScale;
21314			}
21315			return scale;
21316		};
21317		Zoom.prototype.init = function () {
21318			var _this = this;
21319			if (!this.settings.zoom) {
21320				return;
21321			}
21322			this.buildTemplates();
21323			this.enableZoomOnSlideItemLoad();
21324			var tapped = null;
21325			this.core.outer.on('dblclick.lg', function (event) {
21326				if (!_this.$LG(event.target).hasClass('lg-image')) {
21327					return;
21328				}
21329				_this.setActualSize(_this.core.index, event);
21330			});
21331			this.core.outer.on('touchstart.lg', function (event) {
21332				var $target = _this.$LG(event.target);
21333				if (event.targetTouches.length === 1 &&
21334					$target.hasClass('lg-image')) {
21335					if (!tapped) {
21336						tapped = setTimeout(function () {
21337							tapped = null;
21338						}, 300);
21339					}
21340					else {
21341						clearTimeout(tapped);
21342						tapped = null;
21343						event.preventDefault();
21344						_this.setActualSize(_this.core.index, event);
21345					}
21346				}
21347			});
21348			// Update zoom on resize and orientationchange
21349			this.core.LGel.on(lGEvents.containerResize + ".zoom " + lGEvents.rotateRight + ".zoom " + lGEvents.rotateLeft + ".zoom " + lGEvents.flipHorizontal + ".zoom " + lGEvents.flipVertical + ".zoom", function () {
21350				if (!_this.core.lgOpened || !_this.isImageSlide())
21351					return;
21352				_this.setPageCords();
21353				_this.setZoomEssentials();
21354				_this.zoomImage(_this.scale);
21355			});
21356			// Update zoom on resize and orientationchange
21357			this.$LG(window).on("scroll.lg.zoom.global" + this.core.lgId, function () {
21358				if (!_this.core.lgOpened)
21359					return;
21360				_this.scrollTop = _this.$LG(window).scrollTop();
21361			});
21362			this.core.getElementById('lg-zoom-out').on('click.lg', function () {
21363				if (_this.core.outer.find('.lg-current .lg-image').get()) {
21364					_this.scale -= _this.settings.scale;
21365					_this.scale = _this.getScale(_this.scale);
21366					_this.beginZoom(_this.scale);
21367					_this.zoomImage(_this.scale);
21368				}
21369			});
21370			this.core.getElementById('lg-zoom-in').on('click.lg', function () {
21371				_this.zoomIn();
21372			});
21373			this.core.getElementById('lg-actual-size').on('click.lg', function () {
21374				_this.setActualSize(_this.core.index);
21375			});
21376			this.core.LGel.on(lGEvents.beforeOpen + ".zoom", function () {
21377				_this.core.outer.find('.lg-item').removeClass('lg-zoomable');
21378			});
21379			this.core.LGel.on(lGEvents.afterOpen + ".zoom", function () {
21380				_this.scrollTop = _this.$LG(window).scrollTop();
21381				// Set the initial value center
21382				_this.pageX = _this.core.outer.width() / 2;
21383				_this.pageY = _this.core.outer.height() / 2 + _this.scrollTop;
21384				_this.scale = 1;
21385			});
21386			// Reset zoom on slide change
21387			this.core.LGel.on(lGEvents.afterSlide + ".zoom", function (event) {
21388				var prevIndex = event.detail.prevIndex;
21389				_this.scale = 1;
21390				_this.positionChanged = false;
21391				_this.resetZoom(prevIndex);
21392				if (_this.isImageSlide()) {
21393					_this.setZoomEssentials();
21394				}
21395			});
21396			// Drag option after zoom
21397			this.zoomDrag();
21398			this.pinchZoom();
21399			this.zoomSwipe();
21400			// Store the zoomable timeout value just to clear it while closing
21401			this.zoomableTimeout = false;
21402			this.positionChanged = false;
21403		};
21404		Zoom.prototype.zoomIn = function (scale) {
21405			// Allow zoom only on image
21406			if (!this.isImageSlide()) {
21407				return;
21408			}
21409			if (scale) {
21410				this.scale = scale;
21411			}
21412			else {
21413				this.scale += this.settings.scale;
21414			}
21415			this.scale = this.getScale(this.scale);
21416			this.beginZoom(this.scale);
21417			this.zoomImage(this.scale);
21418		};
21419		// Reset zoom effect
21420		Zoom.prototype.resetZoom = function (index) {
21421			this.core.outer.removeClass('lg-zoomed lg-zoom-drag-transition');
21422			var $actualSize = this.core.getElementById('lg-actual-size');
21423			var $item = this.core.getSlideItem(index !== undefined ? index : this.core.index);
21424			$actualSize
21425				.removeClass(this.settings.actualSizeIcons.zoomOut)
21426				.addClass(this.settings.actualSizeIcons.zoomIn);
21427			$item.find('.lg-img-wrap').first().removeAttr('style');
21428			$item.find('.lg-image').first().removeAttr('style');
21429			this.scale = 1;
21430			this.left = 0;
21431			this.top = 0;
21432			// Reset pagx pagy values to center
21433			this.setPageCords();
21434		};
21435		Zoom.prototype.getTouchDistance = function (e) {
21436			return Math.sqrt((e.targetTouches[0].pageX - e.targetTouches[1].pageX) *
21437				(e.targetTouches[0].pageX - e.targetTouches[1].pageX) +
21438				(e.targetTouches[0].pageY - e.targetTouches[1].pageY) *
21439					(e.targetTouches[0].pageY - e.targetTouches[1].pageY));
21440		};
21441		Zoom.prototype.pinchZoom = function () {
21442			var _this = this;
21443			var startDist = 0;
21444			var pinchStarted = false;
21445			var initScale = 1;
21446			var $item = this.core.getSlideItem(this.core.index);
21447			this.core.$inner.on('touchstart.lg', function (e) {
21448				$item = _this.core.getSlideItem(_this.core.index);
21449				if (!_this.isImageSlide()) {
21450					return;
21451				}
21452				if (e.targetTouches.length === 2 &&
21453					!_this.core.outer.hasClass('lg-first-slide-loading') &&
21454					(_this.$LG(e.target).hasClass('lg-item') ||
21455						$item.get().contains(e.target))) {
21456					initScale = _this.scale || 1;
21457					_this.core.outer.removeClass('lg-zoom-drag-transition lg-zoom-dragging');
21458					_this.core.touchAction = 'pinch';
21459					startDist = _this.getTouchDistance(e);
21460				}
21461			});
21462			this.core.$inner.on('touchmove.lg', function (e) {
21463				if (e.targetTouches.length === 2 &&
21464					_this.core.touchAction === 'pinch' &&
21465					(_this.$LG(e.target).hasClass('lg-item') ||
21466						$item.get().contains(e.target))) {
21467					e.preventDefault();
21468					var endDist = _this.getTouchDistance(e);
21469					var distance = startDist - endDist;
21470					if (!pinchStarted && Math.abs(distance) > 5) {
21471						pinchStarted = true;
21472					}
21473					if (pinchStarted) {
21474						_this.scale = Math.max(1, initScale + -distance * 0.008);
21475						_this.zoomImage(_this.scale);
21476					}
21477				}
21478			});
21479			this.core.$inner.on('touchend.lg', function (e) {
21480				if (_this.core.touchAction === 'pinch' &&
21481					(_this.$LG(e.target).hasClass('lg-item') ||
21482						$item.get().contains(e.target))) {
21483					pinchStarted = false;
21484					startDist = 0;
21485					if (_this.scale <= 1) {
21486						_this.resetZoom();
21487					}
21488					else {
21489						_this.scale = _this.getScale(_this.scale);
21490						_this.zoomImage(_this.scale);
21491						_this.core.outer.addClass('lg-zoomed');
21492					}
21493					_this.core.touchAction = undefined;
21494				}
21495			});
21496		};
21497		Zoom.prototype.touchendZoom = function (startCoords, endCoords, allowX, allowY, touchDuration, rotateValue) {
21498			var distanceXnew = endCoords.x - startCoords.x;
21499			var distanceYnew = endCoords.y - startCoords.y;
21500			var speedX = Math.abs(distanceXnew) / touchDuration + 1;
21501			var speedY = Math.abs(distanceYnew) / touchDuration + 1;
21502			if (speedX > 2) {
21503				speedX += 1;
21504			}
21505			if (speedY > 2) {
21506				speedY += 1;
21507			}
21508			distanceXnew = distanceXnew * speedX;
21509			distanceYnew = distanceYnew * speedY;
21510			var _LGel = this.core
21511				.getSlideItem(this.core.index)
21512				.find('.lg-img-wrap')
21513				.first();
21514			var distance = {};
21515			distance.x = this.left + distanceXnew * this.modifierX;
21516			distance.y = this.top + distanceYnew * this.modifierY;
21517			var possibleSwipeCords = this.getPossibleSwipeDragCords(rotateValue);
21518			if (Math.abs(distanceXnew) > 15 || Math.abs(distanceYnew) > 15) {
21519				if (allowY) {
21520					if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
21521						distance.y = possibleSwipeCords.minY;
21522					}
21523					else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
21524						distance.y = possibleSwipeCords.maxY;
21525					}
21526				}
21527				if (allowX) {
21528					if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
21529						distance.x = possibleSwipeCords.minX;
21530					}
21531					else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
21532						distance.x = possibleSwipeCords.maxX;
21533					}
21534				}
21535				if (allowY) {
21536					this.top = distance.y;
21537				}
21538				else {
21539					distance.y = this.top;
21540				}
21541				if (allowX) {
21542					this.left = distance.x;
21543				}
21544				else {
21545					distance.x = this.left;
21546				}
21547				this.setZoomSwipeStyles(_LGel, distance);
21548				this.positionChanged = true;
21549			}
21550		};
21551		Zoom.prototype.getZoomSwipeCords = function (startCoords, endCoords, allowX, allowY, possibleSwipeCords) {
21552			var distance = {};
21553			if (allowY) {
21554				distance.y =
21555					this.top + (endCoords.y - startCoords.y) * this.modifierY;
21556				if (this.isBeyondPossibleTop(distance.y, possibleSwipeCords.minY)) {
21557					var diffMinY = possibleSwipeCords.minY - distance.y;
21558					distance.y = possibleSwipeCords.minY - diffMinY / 6;
21559				}
21560				else if (this.isBeyondPossibleBottom(distance.y, possibleSwipeCords.maxY)) {
21561					var diffMaxY = distance.y - possibleSwipeCords.maxY;
21562					distance.y = possibleSwipeCords.maxY + diffMaxY / 6;
21563				}
21564			}
21565			else {
21566				distance.y = this.top;
21567			}
21568			if (allowX) {
21569				distance.x =
21570					this.left + (endCoords.x - startCoords.x) * this.modifierX;
21571				if (this.isBeyondPossibleLeft(distance.x, possibleSwipeCords.minX)) {
21572					var diffMinX = possibleSwipeCords.minX - distance.x;
21573					distance.x = possibleSwipeCords.minX - diffMinX / 6;
21574				}
21575				else if (this.isBeyondPossibleRight(distance.x, possibleSwipeCords.maxX)) {
21576					var difMaxX = distance.x - possibleSwipeCords.maxX;
21577					distance.x = possibleSwipeCords.maxX + difMaxX / 6;
21578				}
21579			}
21580			else {
21581				distance.x = this.left;
21582			}
21583			return distance;
21584		};
21585		Zoom.prototype.isBeyondPossibleLeft = function (x, minX) {
21586			return x >= minX;
21587		};
21588		Zoom.prototype.isBeyondPossibleRight = function (x, maxX) {
21589			return x <= maxX;
21590		};
21591		Zoom.prototype.isBeyondPossibleTop = function (y, minY) {
21592			return y >= minY;
21593		};
21594		Zoom.prototype.isBeyondPossibleBottom = function (y, maxY) {
21595			return y <= maxY;
21596		};
21597		Zoom.prototype.isImageSlide = function () {
21598			var currentItem = this.core.galleryItems[this.core.index];
21599			return this.core.getSlideType(currentItem) === 'image';
21600		};
21601		Zoom.prototype.getPossibleSwipeDragCords = function (rotateValue, scale) {
21602			var dataScale = scale || this.scale || 1;
21603			var elDataScale = Math.abs(dataScale);
21604			var _a = this.core.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
21605			var topBottomSpacing = Math.abs(top - bottom) / 2;
21606			var minY = (this.imageYSize - this.containerRect.height) / 2 +
21607				topBottomSpacing * this.modifierX;
21608			var maxY = this.containerRect.height - this.imageYSize * elDataScale + minY;
21609			var minX = (this.imageXSize - this.containerRect.width) / 2;
21610			var maxX = this.containerRect.width - this.imageXSize * elDataScale + minX;
21611			var possibleSwipeCords = {
21612				minY: minY,
21613				maxY: maxY,
21614				minX: minX,
21615				maxX: maxX,
21616			};
21617			if (Math.abs(rotateValue) === 90) {
21618				possibleSwipeCords = {
21619					minY: minX,
21620					maxY: maxX,
21621					minX: minY,
21622					maxX: maxY,
21623				};
21624			}
21625			return possibleSwipeCords;
21626		};
21627		Zoom.prototype.setZoomSwipeStyles = function (LGel, distance) {
21628			LGel.css('transform', 'translate3d(' + distance.x + 'px, ' + distance.y + 'px, 0)');
21629		};
21630		Zoom.prototype.zoomSwipe = function () {
21631			var _this = this;
21632			var startCoords = {};
21633			var endCoords = {};
21634			var isMoved = false;
21635			// Allow x direction drag
21636			var allowX = false;
21637			// Allow Y direction drag
21638			var allowY = false;
21639			var startTime = new Date();
21640			var endTime = new Date();
21641			var possibleSwipeCords;
21642			var _LGel;
21643			var $item = this.core.getSlideItem(this.core.index);
21644			this.core.$inner.on('touchstart.lg', function (e) {
21645				// Allow zoom only on image
21646				if (!_this.isImageSlide()) {
21647					return;
21648				}
21649				$item = _this.core.getSlideItem(_this.core.index);
21650				if ((_this.$LG(e.target).hasClass('lg-item') ||
21651					$item.get().contains(e.target)) &&
21652					e.targetTouches.length === 1 &&
21653					_this.core.outer.hasClass('lg-zoomed')) {
21654					e.preventDefault();
21655					startTime = new Date();
21656					_this.core.touchAction = 'zoomSwipe';
21657					_LGel = _this.core
21658						.getSlideItem(_this.core.index)
21659						.find('.lg-img-wrap')
21660						.first();
21661					var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue));
21662					allowY = dragAllowedAxises.allowY;
21663					allowX = dragAllowedAxises.allowX;
21664					if (allowX || allowY) {
21665						startCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue));
21666					}
21667					possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue);
21668					// reset opacity and transition duration
21669					_this.core.outer.addClass('lg-zoom-dragging lg-zoom-drag-transition');
21670				}
21671			});
21672			this.core.$inner.on('touchmove.lg', function (e) {
21673				if (e.targetTouches.length === 1 &&
21674					_this.core.touchAction === 'zoomSwipe' &&
21675					(_this.$LG(e.target).hasClass('lg-item') ||
21676						$item.get().contains(e.target))) {
21677					e.preventDefault();
21678					_this.core.touchAction = 'zoomSwipe';
21679					endCoords = _this.getSwipeCords(e, Math.abs(_this.rotateValue));
21680					var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);
21681					if (Math.abs(endCoords.x - startCoords.x) > 15 ||
21682						Math.abs(endCoords.y - startCoords.y) > 15) {
21683						isMoved = true;
21684						_this.setZoomSwipeStyles(_LGel, distance);
21685					}
21686				}
21687			});
21688			this.core.$inner.on('touchend.lg', function (e) {
21689				if (_this.core.touchAction === 'zoomSwipe' &&
21690					(_this.$LG(e.target).hasClass('lg-item') ||
21691						$item.get().contains(e.target))) {
21692					_this.core.touchAction = undefined;
21693					_this.core.outer.removeClass('lg-zoom-dragging');
21694					if (!isMoved) {
21695						return;
21696					}
21697					isMoved = false;
21698					endTime = new Date();
21699					var touchDuration = endTime.valueOf() - startTime.valueOf();
21700					_this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue);
21701				}
21702			});
21703		};
21704		Zoom.prototype.zoomDrag = function () {
21705			var _this = this;
21706			var startCoords = {};
21707			var endCoords = {};
21708			var isDragging = false;
21709			var isMoved = false;
21710			// Allow x direction drag
21711			var allowX = false;
21712			// Allow Y direction drag
21713			var allowY = false;
21714			var startTime;
21715			var endTime;
21716			var possibleSwipeCords;
21717			var _LGel;
21718			this.core.outer.on('mousedown.lg.zoom', function (e) {
21719				// Allow zoom only on image
21720				if (!_this.isImageSlide()) {
21721					return;
21722				}
21723				var $item = _this.core.getSlideItem(_this.core.index);
21724				if (_this.$LG(e.target).hasClass('lg-item') ||
21725					$item.get().contains(e.target)) {
21726					startTime = new Date();
21727					_LGel = _this.core
21728						.getSlideItem(_this.core.index)
21729						.find('.lg-img-wrap')
21730						.first();
21731					var dragAllowedAxises = _this.getDragAllowedAxises(Math.abs(_this.rotateValue));
21732					allowY = dragAllowedAxises.allowY;
21733					allowX = dragAllowedAxises.allowX;
21734					if (_this.core.outer.hasClass('lg-zoomed')) {
21735						if (_this.$LG(e.target).hasClass('lg-object') &&
21736							(allowX || allowY)) {
21737							e.preventDefault();
21738							startCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
21739							possibleSwipeCords = _this.getPossibleSwipeDragCords(_this.rotateValue);
21740							isDragging = true;
21741							// ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
21742							_this.core.outer.get().scrollLeft += 1;
21743							_this.core.outer.get().scrollLeft -= 1;
21744							_this.core.outer
21745								.removeClass('lg-grab')
21746								.addClass('lg-grabbing lg-zoom-drag-transition lg-zoom-dragging');
21747							// reset opacity and transition duration
21748						}
21749					}
21750				}
21751			});
21752			this.$LG(window).on("mousemove.lg.zoom.global" + this.core.lgId, function (e) {
21753				if (isDragging) {
21754					isMoved = true;
21755					endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
21756					var distance = _this.getZoomSwipeCords(startCoords, endCoords, allowX, allowY, possibleSwipeCords);
21757					_this.setZoomSwipeStyles(_LGel, distance);
21758				}
21759			});
21760			this.$LG(window).on("mouseup.lg.zoom.global" + this.core.lgId, function (e) {
21761				if (isDragging) {
21762					endTime = new Date();
21763					isDragging = false;
21764					_this.core.outer.removeClass('lg-zoom-dragging');
21765					// Fix for chrome mouse move on click
21766					if (isMoved &&
21767						(startCoords.x !== endCoords.x ||
21768							startCoords.y !== endCoords.y)) {
21769						endCoords = _this.getDragCords(e, Math.abs(_this.rotateValue));
21770						var touchDuration = endTime.valueOf() - startTime.valueOf();
21771						_this.touchendZoom(startCoords, endCoords, allowX, allowY, touchDuration, _this.rotateValue);
21772					}
21773					isMoved = false;
21774				}
21775				_this.core.outer.removeClass('lg-grabbing').addClass('lg-grab');
21776			});
21777		};
21778		Zoom.prototype.closeGallery = function () {
21779			this.resetZoom();
21780		};
21781		Zoom.prototype.destroy = function () {
21782			// Unbind all events added by lightGallery zoom plugin
21783			this.$LG(window).off(".lg.zoom.global" + this.core.lgId);
21784			this.core.LGel.off('.lg.zoom');
21785			this.core.LGel.off('.zoom');
21786			clearTimeout(this.zoomableTimeout);
21787			this.zoomableTimeout = false;
21788		};
21789		return Zoom;
21790	}());
21791
21792	return Zoom;
21793
21794})));
21795/*!
21796 * lightgallery | 2.5.0 | June 13th 2022
21797 * http://www.lightgalleryjs.com/
21798 * Copyright (c) 2020 Sachin Neravath;
21799 * @license GPLv3
21800 */
21801
21802(function (global, factory) {
21803	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
21804	typeof define === 'function' && define.amd ? define(factory) :
21805	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgFullscreen = factory());
21806}(this, (function () { 'use strict';
21807
21808	/*! *****************************************************************************
21809	Copyright (c) Microsoft Corporation.
21810
21811	Permission to use, copy, modify, and/or distribute this software for any
21812	purpose with or without fee is hereby granted.
21813
21814	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
21815	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21816	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
21817	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21818	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21819	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21820	PERFORMANCE OF THIS SOFTWARE.
21821	***************************************************************************** */
21822
21823	var __assign = function() {
21824		__assign = Object.assign || function __assign(t) {
21825			for (var s, i = 1, n = arguments.length; i < n; i++) {
21826				s = arguments[i];
21827				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
21828			}
21829			return t;
21830		};
21831		return __assign.apply(this, arguments);
21832	};
21833
21834	var fullscreenSettings = {
21835		fullScreen: true,
21836		fullscreenPluginStrings: {
21837			toggleFullscreen: 'Toggle Fullscreen',
21838		},
21839	};
21840
21841	var FullScreen = /** @class */ (function () {
21842		function FullScreen(instance, $LG) {
21843			// get lightGallery core plugin instance
21844			this.core = instance;
21845			this.$LG = $LG;
21846			// extend module default settings with lightGallery core settings
21847			this.settings = __assign(__assign({}, fullscreenSettings), this.core.settings);
21848			return this;
21849		}
21850		FullScreen.prototype.init = function () {
21851			var fullScreen = '';
21852			if (this.settings.fullScreen) {
21853				// check for fullscreen browser support
21854				if (!document.fullscreenEnabled &&
21855					!document.webkitFullscreenEnabled &&
21856					!document.mozFullScreenEnabled &&
21857					!document.msFullscreenEnabled) {
21858					return;
21859				}
21860				else {
21861					fullScreen = "<button type=\"button\" aria-label=\"" + this.settings.fullscreenPluginStrings['toggleFullscreen'] + "\" class=\"lg-fullscreen lg-icon\"></button>";
21862					this.core.$toolbar.append(fullScreen);
21863					this.fullScreen();
21864				}
21865			}
21866		};
21867		FullScreen.prototype.isFullScreen = function () {
21868			return (document.fullscreenElement ||
21869				document.mozFullScreenElement ||
21870				document.webkitFullscreenElement ||
21871				document.msFullscreenElement);
21872		};
21873		FullScreen.prototype.requestFullscreen = function () {
21874			var el = document.documentElement;
21875			if (el.requestFullscreen) {
21876				el.requestFullscreen();
21877			}
21878			else if (el.msRequestFullscreen) {
21879				el.msRequestFullscreen();
21880			}
21881			else if (el.mozRequestFullScreen) {
21882				el.mozRequestFullScreen();
21883			}
21884			else if (el.webkitRequestFullscreen) {
21885				el.webkitRequestFullscreen();
21886			}
21887		};
21888		FullScreen.prototype.exitFullscreen = function () {
21889			if (document.exitFullscreen) {
21890				document.exitFullscreen();
21891			}
21892			else if (document.msExitFullscreen) {
21893				document.msExitFullscreen();
21894			}
21895			else if (document.mozCancelFullScreen) {
21896				document.mozCancelFullScreen();
21897			}
21898			else if (document.webkitExitFullscreen) {
21899				document.webkitExitFullscreen();
21900			}
21901		};
21902		// https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode
21903		FullScreen.prototype.fullScreen = function () {
21904			var _this = this;
21905			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 () {
21906				if (!_this.core.lgOpened)
21907					return;
21908				_this.core.outer.toggleClass('lg-fullscreen-on');
21909			});
21910			this.core.outer
21911				.find('.lg-fullscreen')
21912				.first()
21913				.on('click.lg', function () {
21914				if (_this.isFullScreen()) {
21915					_this.exitFullscreen();
21916				}
21917				else {
21918					_this.requestFullscreen();
21919				}
21920			});
21921		};
21922		FullScreen.prototype.closeGallery = function () {
21923			// exit from fullscreen if activated
21924			if (this.isFullScreen()) {
21925				this.exitFullscreen();
21926			}
21927		};
21928		FullScreen.prototype.destroy = function () {
21929			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);
21930		};
21931		return FullScreen;
21932	}());
21933
21934	return FullScreen;
21935
21936})));
21937
21938/*!
21939 * lightgallery | 2.5.0 | June 13th 2022
21940 * http://www.lightgalleryjs.com/
21941 * Copyright (c) 2020 Sachin Neravath;
21942 * @license GPLv3
21943 */
21944
21945(function (global, factory) {
21946	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
21947	typeof define === 'function' && define.amd ? define(factory) :
21948	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgHash = factory());
21949}(this, (function () { 'use strict';
21950
21951	/*! *****************************************************************************
21952	Copyright (c) Microsoft Corporation.
21953
21954	Permission to use, copy, modify, and/or distribute this software for any
21955	purpose with or without fee is hereby granted.
21956
21957	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
21958	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
21959	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
21960	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21961	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21962	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21963	PERFORMANCE OF THIS SOFTWARE.
21964	***************************************************************************** */
21965
21966	var __assign = function() {
21967		__assign = Object.assign || function __assign(t) {
21968			for (var s, i = 1, n = arguments.length; i < n; i++) {
21969				s = arguments[i];
21970				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
21971			}
21972			return t;
21973		};
21974		return __assign.apply(this, arguments);
21975	};
21976
21977	/**
21978	 * List of lightGallery events
21979	 * All events should be documented here
21980	 * Below interfaces are used to build the website documentations
21981	 * */
21982	var lGEvents = {
21983		afterAppendSlide: 'lgAfterAppendSlide',
21984		init: 'lgInit',
21985		hasVideo: 'lgHasVideo',
21986		containerResize: 'lgContainerResize',
21987		updateSlides: 'lgUpdateSlides',
21988		afterAppendSubHtml: 'lgAfterAppendSubHtml',
21989		beforeOpen: 'lgBeforeOpen',
21990		afterOpen: 'lgAfterOpen',
21991		slideItemLoad: 'lgSlideItemLoad',
21992		beforeSlide: 'lgBeforeSlide',
21993		afterSlide: 'lgAfterSlide',
21994		posterClick: 'lgPosterClick',
21995		dragStart: 'lgDragStart',
21996		dragMove: 'lgDragMove',
21997		dragEnd: 'lgDragEnd',
21998		beforeNextSlide: 'lgBeforeNextSlide',
21999		beforePrevSlide: 'lgBeforePrevSlide',
22000		beforeClose: 'lgBeforeClose',
22001		afterClose: 'lgAfterClose',
22002		rotateLeft: 'lgRotateLeft',
22003		rotateRight: 'lgRotateRight',
22004		flipHorizontal: 'lgFlipHorizontal',
22005		flipVertical: 'lgFlipVertical',
22006		autoplay: 'lgAutoplay',
22007		autoplayStart: 'lgAutoplayStart',
22008		autoplayStop: 'lgAutoplayStop',
22009	};
22010
22011	var hashSettings = {
22012		hash: true,
22013		galleryId: '1',
22014		customSlideName: false,
22015	};
22016
22017	var Hash = /** @class */ (function () {
22018		function Hash(instance, $LG) {
22019			// get lightGallery core plugin instance
22020			this.core = instance;
22021			this.$LG = $LG;
22022			// extend module default settings with lightGallery core settings
22023			this.settings = __assign(__assign({}, hashSettings), this.core.settings);
22024			return this;
22025		}
22026		Hash.prototype.init = function () {
22027			var _this = this;
22028			if (!this.settings.hash) {
22029				return;
22030			}
22031			this.oldHash = window.location.hash;
22032			setTimeout(function () {
22033				_this.buildFromHash();
22034			}, 100);
22035			// Change hash value on after each slide transition
22036			this.core.LGel.on(lGEvents.afterSlide + ".hash", this.onAfterSlide.bind(this));
22037			this.core.LGel.on(lGEvents.afterClose + ".hash", this.onCloseAfter.bind(this));
22038			// Listen hash change and change the slide according to slide value
22039			this.$LG(window).on("hashchange.lg.hash.global" + this.core.lgId, this.onHashchange.bind(this));
22040		};
22041		Hash.prototype.onAfterSlide = function (event) {
22042			var slideName = this.core.galleryItems[event.detail.index].slideName;
22043			slideName = this.settings.customSlideName
22044				? slideName || event.detail.index
22045				: event.detail.index;
22046			if (history.replaceState) {
22047				history.replaceState(null, '', window.location.pathname +
22048					window.location.search +
22049					'#lg=' +
22050					this.settings.galleryId +
22051					'&slide=' +
22052					slideName);
22053			}
22054			else {
22055				window.location.hash =
22056					'lg=' + this.settings.galleryId + '&slide=' + slideName;
22057			}
22058		};
22059		/**
22060		 * Get index of the slide from custom slideName. Has to be a public method. Used in hash plugin
22061		 * @param {String} hash
22062		 * @returns {Number} Index of the slide.
22063		 */
22064		Hash.prototype.getIndexFromUrl = function (hash) {
22065			if (hash === void 0) { hash = window.location.hash; }
22066			var slideName = hash.split('&slide=')[1];
22067			var _idx = 0;
22068			if (this.settings.customSlideName) {
22069				for (var index = 0; index < this.core.galleryItems.length; index++) {
22070					var dynamicEl = this.core.galleryItems[index];
22071					if (dynamicEl.slideName === slideName) {
22072						_idx = index;
22073						break;
22074					}
22075				}
22076			}
22077			else {
22078				_idx = parseInt(slideName, 10);
22079			}
22080			return isNaN(_idx) ? 0 : _idx;
22081		};
22082		// Build Gallery if gallery id exist in the URL
22083		Hash.prototype.buildFromHash = function () {
22084			// if dynamic option is enabled execute immediately
22085			var _hash = window.location.hash;
22086			//Uncode edit ##START##
22087			// if (_hash.indexOf('lg=' + this.settings.galleryId) > 0) {
22088			if (_hash.indexOf('lg=' + this.settings.galleryId + '&') > 0) {
22089			//Uncode edit ##END##
22090				// This class is used to remove the initial animation if galleryId present in the URL
22091				this.$LG(document.body).addClass('lg-from-hash');
22092				var index = this.getIndexFromUrl(_hash);
22093				this.core.openGallery(index);
22094				return true;
22095			}
22096		};
22097		Hash.prototype.onCloseAfter = function () {
22098			// Reset to old hash value
22099			if (this.oldHash &&
22100				this.oldHash.indexOf('lg=' + this.settings.galleryId) < 0) {
22101				if (history.replaceState) {
22102					history.replaceState(null, '', this.oldHash);
22103				}
22104				else {
22105					window.location.hash = this.oldHash;
22106				}
22107			}
22108			else {
22109				if (history.replaceState) {
22110					history.replaceState(null, document.title, window.location.pathname + window.location.search);
22111				}
22112				else {
22113					window.location.hash = '';
22114				}
22115			}
22116		};
22117		Hash.prototype.onHashchange = function () {
22118			if (!this.core.lgOpened)
22119				return;
22120			var _hash = window.location.hash;
22121			var index = this.getIndexFromUrl(_hash);
22122			// it galleryId doesn't exist in the url close the gallery
22123			if (_hash.indexOf('lg=' + this.settings.galleryId) > -1) {
22124				this.core.slide(index, false, false);
22125			}
22126			else if (this.core.lGalleryOn) {
22127				this.core.closeGallery();
22128			}
22129		};
22130		Hash.prototype.closeGallery = function () {
22131			if (this.settings.hash) {
22132				this.$LG(document.body).removeClass('lg-from-hash');
22133			}
22134		};
22135		Hash.prototype.destroy = function () {
22136			this.core.LGel.off('.lg.hash');
22137			this.core.LGel.off('.hash');
22138			this.$LG(window).off("hashchange.lg.hash.global" + this.core.lgId);
22139		};
22140		return Hash;
22141	}());
22142
22143	return Hash;
22144
22145})));
22146/*!
22147 * lightgallery | 2.5.0 | June 13th 2022
22148 * http://www.lightgalleryjs.com/
22149 * Copyright (c) 2020 Sachin Neravath;
22150 * @license GPLv3
22151 */
22152
22153(function (global, factory) {
22154	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
22155	typeof define === 'function' && define.amd ? define(factory) :
22156	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgShare = factory());
22157}(this, (function () { 'use strict';
22158
22159	/*! *****************************************************************************
22160	Copyright (c) Microsoft Corporation.
22161
22162	Permission to use, copy, modify, and/or distribute this software for any
22163	purpose with or without fee is hereby granted.
22164
22165	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22166	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22167	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22168	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22169	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22170	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22171	PERFORMANCE OF THIS SOFTWARE.
22172	***************************************************************************** */
22173
22174	var __assign = function() {
22175		__assign = Object.assign || function __assign(t) {
22176			for (var s, i = 1, n = arguments.length; i < n; i++) {
22177				s = arguments[i];
22178				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
22179			}
22180			return t;
22181		};
22182		return __assign.apply(this, arguments);
22183	};
22184
22185	function __spreadArrays() {
22186		for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
22187		for (var r = Array(s), k = 0, i = 0; i < il; i++)
22188			for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
22189				r[k] = a[j];
22190		return r;
22191	}
22192
22193	var shareSettings = {
22194		share: true,
22195		facebook: true,
22196		facebookDropdownText: 'Facebook',
22197		twitter: true,
22198		twitterDropdownText: 'Twitter',
22199		pinterest: true,
22200		pinterestDropdownText: 'Pinterest',
22201		additionalShareOptions: [],
22202		sharePluginStrings: { share: 'Share' },
22203	};
22204
22205	function getFacebookShareLink(galleryItem) {
22206		var facebookBaseUrl = '//www.facebook.com/sharer/sharer.php?u=';
22207		return (facebookBaseUrl +
22208			encodeURIComponent(galleryItem.facebookShareUrl || window.location.href));
22209	}
22210
22211	function getTwitterShareLink(galleryItem) {
22212		var twitterBaseUrl = '//twitter.com/intent/tweet?text=';
22213		var url = encodeURIComponent(galleryItem.twitterShareUrl || window.location.href);
22214		var text = galleryItem.tweetText;
22215		return twitterBaseUrl + text + '&url=' + url;
22216	}
22217
22218	function getPinterestShareLink(galleryItem) {
22219		var pinterestBaseUrl = 'http://www.pinterest.com/pin/create/button/?url=';
22220		var description = galleryItem.pinterestText;
22221		var media = encodeURIComponent(galleryItem.src);
22222		var url = encodeURIComponent(galleryItem.pinterestShareUrl || window.location.href);
22223		return (pinterestBaseUrl +
22224			url +
22225			'&media=' +
22226			media +
22227			'&description=' +
22228			description);
22229	}
22230
22231	/**
22232	 * List of lightGallery events
22233	 * All events should be documented here
22234	 * Below interfaces are used to build the website documentations
22235	 * */
22236	var lGEvents = {
22237		afterAppendSlide: 'lgAfterAppendSlide',
22238		init: 'lgInit',
22239		hasVideo: 'lgHasVideo',
22240		containerResize: 'lgContainerResize',
22241		updateSlides: 'lgUpdateSlides',
22242		afterAppendSubHtml: 'lgAfterAppendSubHtml',
22243		beforeOpen: 'lgBeforeOpen',
22244		afterOpen: 'lgAfterOpen',
22245		slideItemLoad: 'lgSlideItemLoad',
22246		beforeSlide: 'lgBeforeSlide',
22247		afterSlide: 'lgAfterSlide',
22248		posterClick: 'lgPosterClick',
22249		dragStart: 'lgDragStart',
22250		dragMove: 'lgDragMove',
22251		dragEnd: 'lgDragEnd',
22252		beforeNextSlide: 'lgBeforeNextSlide',
22253		beforePrevSlide: 'lgBeforePrevSlide',
22254		beforeClose: 'lgBeforeClose',
22255		afterClose: 'lgAfterClose',
22256		rotateLeft: 'lgRotateLeft',
22257		rotateRight: 'lgRotateRight',
22258		flipHorizontal: 'lgFlipHorizontal',
22259		flipVertical: 'lgFlipVertical',
22260		autoplay: 'lgAutoplay',
22261		autoplayStart: 'lgAutoplayStart',
22262		autoplayStop: 'lgAutoplayStop',
22263	};
22264
22265	var Share = /** @class */ (function () {
22266		function Share(instance) {
22267			this.shareOptions = [];
22268			// get lightGallery core plugin instance
22269			this.core = instance;
22270			// extend module default settings with lightGallery core settings
22271			this.settings = __assign(__assign({}, shareSettings), this.core.settings);
22272			return this;
22273		}
22274		Share.prototype.init = function () {
22275			if (!this.settings.share) {
22276				return;
22277			}
22278			this.shareOptions = __spreadArrays(this.getDefaultShareOptions(), this.settings.additionalShareOptions);
22279			this.setLgShareMarkup();
22280			this.core.outer
22281				.find('.lg-share .lg-dropdown')
22282				.append(this.getShareListHtml());
22283			this.core.LGel.on(lGEvents.afterSlide + ".share", this.onAfterSlide.bind(this));
22284		};
22285		Share.prototype.getShareListHtml = function () {
22286			var shareHtml = '';
22287			this.shareOptions.forEach(function (shareOption) {
22288				shareHtml += shareOption.dropdownHTML;
22289			});
22290			return shareHtml;
22291		};
22292		Share.prototype.setLgShareMarkup = function () {
22293			var _this = this;
22294			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>");
22295			this.core.outer.append('<div class="lg-dropdown-overlay"></div>');
22296			var $shareButton = this.core.outer.find('.lg-share');
22297			$shareButton.first().on('click.lg', function () {
22298				_this.core.outer.toggleClass('lg-dropdown-active');
22299				if (_this.core.outer.hasClass('lg-dropdown-active')) {
22300					_this.core.outer.attr('aria-expanded', true);
22301				}
22302				else {
22303					_this.core.outer.attr('aria-expanded', false);
22304				}
22305			});
22306			this.core.outer
22307				.find('.lg-dropdown-overlay')
22308				.first()
22309				.on('click.lg', function () {
22310				_this.core.outer.removeClass('lg-dropdown-active');
22311				_this.core.outer.attr('aria-expanded', false);
22312			});
22313		};
22314		Share.prototype.onAfterSlide = function (event) {
22315			var _this = this;
22316			var index = event.detail.index;
22317			var currentItem = this.core.galleryItems[index];
22318			setTimeout(function () {
22319				_this.shareOptions.forEach(function (shareOption) {
22320					var selector = shareOption.selector;
22321					_this.core.outer
22322						.find(selector)
22323						.attr('href', shareOption.generateLink(currentItem));
22324				});
22325			}, 100);
22326		};
22327		Share.prototype.getShareListItemHTML = function (type, text) {
22328			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>";
22329		};
22330		Share.prototype.getDefaultShareOptions = function () {
22331			return __spreadArrays((this.settings.facebook
22332				? [
22333					{
22334						type: 'facebook',
22335						generateLink: getFacebookShareLink,
22336						dropdownHTML: this.getShareListItemHTML('facebook', this.settings.facebookDropdownText),
22337						selector: '.lg-share-facebook',
22338					},
22339				]
22340				: []), (this.settings.twitter
22341				? [
22342					{
22343						type: 'twitter',
22344						generateLink: getTwitterShareLink,
22345						dropdownHTML: this.getShareListItemHTML('twitter', this.settings.twitterDropdownText),
22346						selector: '.lg-share-twitter',
22347					},
22348				]
22349				: []), (this.settings.pinterest
22350				? [
22351					{
22352						type: 'pinterest',
22353						generateLink: getPinterestShareLink,
22354						dropdownHTML: this.getShareListItemHTML('pinterest', this.settings.pinterestDropdownText),
22355						selector: '.lg-share-pinterest',
22356					},
22357				]
22358				: []));
22359		};
22360		Share.prototype.destroy = function () {
22361			this.core.outer.find('.lg-dropdown-overlay').remove();
22362			this.core.outer.find('.lg-share').remove();
22363			this.core.LGel.off('.lg.share');
22364			this.core.LGel.off('.share');
22365		};
22366		return Share;
22367	}());
22368
22369	return Share;
22370
22371})));
22372/*!
22373 * lightgallery | 2.5.0 | June 13th 2022
22374 * http://www.lightgalleryjs.com/
22375 * Copyright (c) 2020 Sachin Neravath;
22376 * @license GPLv3
22377 */
22378
22379(function (global, factory) {
22380	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
22381	typeof define === 'function' && define.amd ? define(factory) :
22382	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgThumbnail = factory());
22383}(this, (function () { 'use strict';
22384
22385	/*! *****************************************************************************
22386	Copyright (c) Microsoft Corporation.
22387
22388	Permission to use, copy, modify, and/or distribute this software for any
22389	purpose with or without fee is hereby granted.
22390
22391	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22392	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22393	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22394	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22395	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22396	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22397	PERFORMANCE OF THIS SOFTWARE.
22398	***************************************************************************** */
22399
22400	var __assign = function() {
22401		__assign = Object.assign || function __assign(t) {
22402			for (var s, i = 1, n = arguments.length; i < n; i++) {
22403				s = arguments[i];
22404				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
22405			}
22406			return t;
22407		};
22408		return __assign.apply(this, arguments);
22409	};
22410
22411	var thumbnailsSettings = {
22412		thumbnail: true,
22413		animateThumb: true,
22414		currentPagerPosition: 'middle',
22415		alignThumbnails: 'middle',
22416		thumbWidth: 100,
22417		thumbHeight: '80px',
22418		thumbMargin: 5,
22419		appendThumbnailsTo: '.lg-components',
22420		toggleThumb: false,
22421		enableThumbDrag: true,
22422		enableThumbSwipe: true,
22423		thumbnailSwipeThreshold: 10,
22424		loadYouTubeThumbnail: true,
22425		youTubeThumbSize: 1,
22426		thumbnailPluginStrings: {
22427			toggleThumbnails: 'Toggle thumbnails',
22428		},
22429	};
22430
22431	/**
22432	 * List of lightGallery events
22433	 * All events should be documented here
22434	 * Below interfaces are used to build the website documentations
22435	 * */
22436	var lGEvents = {
22437		afterAppendSlide: 'lgAfterAppendSlide',
22438		init: 'lgInit',
22439		hasVideo: 'lgHasVideo',
22440		containerResize: 'lgContainerResize',
22441		updateSlides: 'lgUpdateSlides',
22442		afterAppendSubHtml: 'lgAfterAppendSubHtml',
22443		beforeOpen: 'lgBeforeOpen',
22444		afterOpen: 'lgAfterOpen',
22445		slideItemLoad: 'lgSlideItemLoad',
22446		beforeSlide: 'lgBeforeSlide',
22447		afterSlide: 'lgAfterSlide',
22448		posterClick: 'lgPosterClick',
22449		dragStart: 'lgDragStart',
22450		dragMove: 'lgDragMove',
22451		dragEnd: 'lgDragEnd',
22452		beforeNextSlide: 'lgBeforeNextSlide',
22453		beforePrevSlide: 'lgBeforePrevSlide',
22454		beforeClose: 'lgBeforeClose',
22455		afterClose: 'lgAfterClose',
22456		rotateLeft: 'lgRotateLeft',
22457		rotateRight: 'lgRotateRight',
22458		flipHorizontal: 'lgFlipHorizontal',
22459		flipVertical: 'lgFlipVertical',
22460		autoplay: 'lgAutoplay',
22461		autoplayStart: 'lgAutoplayStart',
22462		autoplayStop: 'lgAutoplayStop',
22463	};
22464
22465	var Thumbnail = /** @class */ (function () {
22466		function Thumbnail(instance, $LG) {
22467			this.thumbOuterWidth = 0;
22468			this.thumbTotalWidth = 0;
22469			this.translateX = 0;
22470			this.thumbClickable = false;
22471			// get lightGallery core plugin instance
22472			this.core = instance;
22473			this.$LG = $LG;
22474			return this;
22475		}
22476		Thumbnail.prototype.init = function () {
22477			// extend module default settings with lightGallery core settings
22478			this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings);
22479			this.thumbOuterWidth = 0;
22480			this.thumbTotalWidth =
22481				this.core.galleryItems.length *
22482					(this.settings.thumbWidth + this.settings.thumbMargin);
22483			// Thumbnail animation value
22484			this.translateX = 0;
22485			this.setAnimateThumbStyles();
22486			if (!this.core.settings.allowMediaOverlap) {
22487				this.settings.toggleThumb = false;
22488			}
22489			if (this.settings.thumbnail) {
22490				this.build();
22491				if (this.settings.animateThumb) {
22492					if (this.settings.enableThumbDrag) {
22493						this.enableThumbDrag();
22494					}
22495					if (this.settings.enableThumbSwipe) {
22496						this.enableThumbSwipe();
22497					}
22498					this.thumbClickable = false;
22499				}
22500				else {
22501					this.thumbClickable = true;
22502				}
22503				this.toggleThumbBar();
22504				this.thumbKeyPress();
22505			}
22506		};
22507		Thumbnail.prototype.build = function () {
22508			var _this = this;
22509			this.setThumbMarkup();
22510			this.manageActiveClassOnSlideChange();
22511			this.$lgThumb.first().on('click.lg touchend.lg', function (e) {
22512				var $target = _this.$LG(e.target);
22513				if (!$target.hasAttribute('data-lg-item-id')) {
22514					return;
22515				}
22516				setTimeout(function () {
22517					// In IE9 and bellow touch does not support
22518					// Go to slide if browser does not support css transitions
22519					if (_this.thumbClickable && !_this.core.lgBusy) {
22520						var index = parseInt($target.attr('data-lg-item-id'));
22521						_this.core.slide(index, false, true, false);
22522					}
22523				}, 50);
22524			});
22525			//Uncode edit ##START##
22526			// this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) {
22527			this.core.LGel.on(lGEvents.beforeSlide, function (event) {
22528			//Uncode edit ##END##
22529				var index = event.detail.index;
22530				_this.animateThumb(index);
22531			});
22532			//Uncode edit ##START##
22533			// this.core.LGel.on(lGEvents.beforeOpen + ".thumb", function () {
22534			this.core.LGel.on(lGEvents.beforeOpen, function () {
22535			//Uncode edit ##END##
22536				_this.thumbOuterWidth = _this.core.outer.get().offsetWidth;
22537			});
22538			//Uncode edit ##START##
22539			// this.core.LGel.on(lGEvents.updateSlides + ".thumb", function () {
22540			this.core.LGel.on(lGEvents.updateSlides, function () {
22541			//Uncode edit ##END##
22542				_this.rebuildThumbnails();
22543			});
22544			//Uncode edit ##START##
22545			// this.core.LGel.on(lGEvents.containerResize + ".thumb", function () {
22546			this.core.LGel.on(lGEvents.containerResize, function () {
22547			//Uncode edit ##END##
22548				if (!_this.core.lgOpened)
22549					return;
22550				setTimeout(function () {
22551					_this.thumbOuterWidth = _this.core.outer.get().offsetWidth;
22552					_this.animateThumb(_this.core.index);
22553					_this.thumbOuterWidth = _this.core.outer.get().offsetWidth;
22554				}, 50);
22555			});
22556		};
22557		Thumbnail.prototype.setThumbMarkup = function () {
22558			var thumbOuterClassNames = 'lg-thumb-outer ';
22559			if (this.settings.alignThumbnails) {
22560				thumbOuterClassNames += "lg-thumb-align-" + this.settings.alignThumbnails;
22561			}
22562			var html = "<div class=\"" + thumbOuterClassNames + "\">\n        <div class=\"lg-thumb lg-group\">\n        </div>\n        </div>";
22563			this.core.outer.addClass('lg-has-thumb');
22564			if (this.settings.appendThumbnailsTo === '.lg-components') {
22565				this.core.$lgComponents.append(html);
22566			}
22567			else {
22568				this.core.outer.append(html);
22569			}
22570			this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first();
22571			this.$lgThumb = this.core.outer.find('.lg-thumb').first();
22572			if (this.settings.animateThumb) {
22573				this.core.outer
22574					.find('.lg-thumb')
22575					.css('transition-duration', this.core.settings.speed + 'ms')
22576					.css('width', this.thumbTotalWidth + 'px')
22577					.css('position', 'relative');
22578			}
22579			this.setThumbItemHtml(this.core.galleryItems);
22580		};
22581		Thumbnail.prototype.enableThumbDrag = function () {
22582			var _this = this;
22583			var thumbDragUtils = {
22584				cords: {
22585					startX: 0,
22586					endX: 0,
22587				},
22588				isMoved: false,
22589				newTranslateX: 0,
22590				startTime: new Date(),
22591				endTime: new Date(),
22592				touchMoveTime: 0,
22593			};
22594			var isDragging = false;
22595			this.$thumbOuter.addClass('lg-grab');
22596			this.core.outer
22597				.find('.lg-thumb')
22598				.first()
22599				.on('mousedown.lg.thumb', function (e) {
22600				if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
22601					// execute only on .lg-object
22602					e.preventDefault();
22603					thumbDragUtils.cords.startX = e.pageX;
22604					thumbDragUtils.startTime = new Date();
22605					_this.thumbClickable = false;
22606					isDragging = true;
22607					// ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
22608					_this.core.outer.get().scrollLeft += 1;
22609					_this.core.outer.get().scrollLeft -= 1;
22610					// *
22611					_this.$thumbOuter
22612						.removeClass('lg-grab')
22613						.addClass('lg-grabbing');
22614				}
22615			});
22616			this.$LG(window).on("mousemove.lg.thumb.global" + this.core.lgId, function (e) {
22617				if (!_this.core.lgOpened)
22618					return;
22619				if (isDragging) {
22620					thumbDragUtils.cords.endX = e.pageX;
22621					thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils);
22622				}
22623			});
22624			this.$LG(window).on("mouseup.lg.thumb.global" + this.core.lgId, function () {
22625				if (!_this.core.lgOpened)
22626					return;
22627				if (thumbDragUtils.isMoved) {
22628					thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils);
22629				}
22630				else {
22631					_this.thumbClickable = true;
22632				}
22633				if (isDragging) {
22634					isDragging = false;
22635					_this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab');
22636				}
22637			});
22638		};
22639		Thumbnail.prototype.enableThumbSwipe = function () {
22640			var _this = this;
22641			var thumbDragUtils = {
22642				cords: {
22643					startX: 0,
22644					endX: 0,
22645				},
22646				isMoved: false,
22647				newTranslateX: 0,
22648				startTime: new Date(),
22649				endTime: new Date(),
22650				touchMoveTime: 0,
22651			};
22652			this.$lgThumb.on('touchstart.lg', function (e) {
22653				if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
22654					e.preventDefault();
22655					thumbDragUtils.cords.startX = e.targetTouches[0].pageX;
22656					_this.thumbClickable = false;
22657					thumbDragUtils.startTime = new Date();
22658				}
22659			});
22660			this.$lgThumb.on('touchmove.lg', function (e) {
22661				if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
22662					e.preventDefault();
22663					thumbDragUtils.cords.endX = e.targetTouches[0].pageX;
22664					thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils);
22665				}
22666			});
22667			this.$lgThumb.on('touchend.lg', function () {
22668				if (thumbDragUtils.isMoved) {
22669					thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils);
22670				}
22671				else {
22672					_this.thumbClickable = true;
22673				}
22674			});
22675		};
22676		// Rebuild thumbnails
22677		Thumbnail.prototype.rebuildThumbnails = function () {
22678			var _this = this;
22679			// Remove transitions
22680			this.$thumbOuter.addClass('lg-rebuilding-thumbnails');
22681			setTimeout(function () {
22682				_this.thumbTotalWidth =
22683					_this.core.galleryItems.length *
22684						(_this.settings.thumbWidth + _this.settings.thumbMargin);
22685				_this.$lgThumb.css('width', _this.thumbTotalWidth + 'px');
22686				_this.$lgThumb.empty();
22687				_this.setThumbItemHtml(_this.core.galleryItems);
22688				_this.animateThumb(_this.core.index);
22689			}, 50);
22690			setTimeout(function () {
22691				_this.$thumbOuter.removeClass('lg-rebuilding-thumbnails');
22692			}, 200);
22693		};
22694		// @ts-check
22695		Thumbnail.prototype.setTranslate = function (value) {
22696			this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)');
22697		};
22698		Thumbnail.prototype.getPossibleTransformX = function (left) {
22699			if (left > this.thumbTotalWidth - this.thumbOuterWidth) {
22700				left = this.thumbTotalWidth - this.thumbOuterWidth;
22701			}
22702			if (left < 0) {
22703				left = 0;
22704			}
22705			return left;
22706		};
22707		Thumbnail.prototype.animateThumb = function (index) {
22708			this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms');
22709			if (this.settings.animateThumb) {
22710				var position = 0;
22711				switch (this.settings.currentPagerPosition) {
22712					case 'left':
22713						position = 0;
22714						break;
22715					case 'middle':
22716						position =
22717							this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2;
22718						break;
22719					case 'right':
22720						position = this.thumbOuterWidth - this.settings.thumbWidth;
22721				}
22722				this.translateX =
22723					(this.settings.thumbWidth + this.settings.thumbMargin) * index -
22724						1 -
22725						position;
22726				if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) {
22727					this.translateX = this.thumbTotalWidth - this.thumbOuterWidth;
22728				}
22729				if (this.translateX < 0) {
22730					this.translateX = 0;
22731				}
22732				this.setTranslate(this.translateX);
22733			}
22734		};
22735		Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) {
22736			thumbDragUtils.newTranslateX = this.translateX;
22737			thumbDragUtils.isMoved = true;
22738			thumbDragUtils.touchMoveTime = new Date().valueOf();
22739			thumbDragUtils.newTranslateX -=
22740				thumbDragUtils.cords.endX - thumbDragUtils.cords.startX;
22741			thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX);
22742			// move current slide
22743			this.setTranslate(thumbDragUtils.newTranslateX);
22744			this.$thumbOuter.addClass('lg-dragging');
22745			return thumbDragUtils;
22746		};
22747		Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) {
22748			thumbDragUtils.isMoved = false;
22749			thumbDragUtils.endTime = new Date();
22750			this.$thumbOuter.removeClass('lg-dragging');
22751			var touchDuration = thumbDragUtils.endTime.valueOf() -
22752				thumbDragUtils.startTime.valueOf();
22753			var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX;
22754			var speedX = Math.abs(distanceXnew) / touchDuration;
22755			// Some magical numbers
22756			// Can be improved
22757			if (speedX > 0.15 &&
22758				thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) {
22759				speedX += 1;
22760				if (speedX > 2) {
22761					speedX += 1;
22762				}
22763				speedX =
22764					speedX +
22765						speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth);
22766				this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings');
22767				distanceXnew = distanceXnew * speedX;
22768				this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew);
22769				this.setTranslate(this.translateX);
22770			}
22771			else {
22772				this.translateX = thumbDragUtils.newTranslateX;
22773			}
22774			if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) <
22775				this.settings.thumbnailSwipeThreshold) {
22776				this.thumbClickable = true;
22777			}
22778			return thumbDragUtils;
22779		};
22780		Thumbnail.prototype.getThumbHtml = function (thumb, index, alt) {
22781			var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
22782			var thumbImg,
22783				altTh = this.core.galleryItems[index].subHtml,
22784				altApp = '';
22785			if (slideVideoInfo.youtube) {
22786				if (this.settings.loadYouTubeThumbnail) {
22787					thumbImg =
22788						'//img.youtube.com/vi/' +
22789							slideVideoInfo.youtube[1] +
22790							'/' +
22791							this.settings.youTubeThumbSize +
22792							'.jpg';
22793				}
22794				else {
22795					thumbImg = thumb;
22796				}
22797			}
22798			else {
22799				thumbImg = thumb;
22800			}
22801
22802			if ( altTh ) {
22803				altTh = altTh.replace(/<\/?[^>]+(>|$)/g, "");
22804				altApp = 'alt=\"' + altTh + ' \" ';
22805			} else if ( typeof alt !== 'undefined' ) {
22806				altApp = 'alt=\"' + alt + ' \" ';
22807			}
22808
22809			if ( thumbImg ) {
22810				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>";
22811			} else {
22812				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>";
22813			}
22814		};
22815		Thumbnail.prototype.getThumbItemHtml = function (items) {
22816			var thumbList = '';
22817			for (var i = 0; i < items.length; i++) {
22818				thumbList += this.getThumbHtml(items[i].thumb, i, items[i].alt);
22819			}
22820			return thumbList;
22821		};
22822		Thumbnail.prototype.setThumbItemHtml = function (items) {
22823			var thumbList = this.getThumbItemHtml(items);
22824			this.$lgThumb.html(thumbList);
22825		};
22826		Thumbnail.prototype.setAnimateThumbStyles = function () {
22827			if (this.settings.animateThumb) {
22828				this.core.outer.addClass('lg-animate-thumb');
22829			}
22830		};
22831		// Manage thumbnail active calss
22832		Thumbnail.prototype.manageActiveClassOnSlideChange = function () {
22833			var _this = this;
22834			// manage active class for thumbnail
22835			//Uncode edit ##START##
22836			// this.core.LGel.on(lGEvents.beforeSlide + ".thumb", function (event) {
22837			this.core.LGel.on(lGEvents.beforeSlide, function (event) {
22838			//Uncode edit ##END##
22839				var $thumb = _this.core.outer.find('.lg-thumb-item');
22840				var index = event.detail.index;
22841				$thumb.removeClass('active');
22842				$thumb.eq(index).addClass('active');
22843			});
22844		};
22845		// Toggle thumbnail bar
22846		Thumbnail.prototype.toggleThumbBar = function () {
22847			var _this = this;
22848			if (this.settings.toggleThumb) {
22849				this.core.outer.addClass('lg-can-toggle');
22850				this.core.$toolbar.append('<button type="button" aria-label="' +
22851					this.settings.thumbnailPluginStrings['toggleThumbnails'] +
22852					'" class="lg-toggle-thumb lg-icon"></button>');
22853				this.core.outer
22854					.find('.lg-toggle-thumb')
22855					.first()
22856					.on('click.lg', function () {
22857					_this.core.outer.toggleClass('lg-components-open');
22858				});
22859			}
22860		};
22861		Thumbnail.prototype.thumbKeyPress = function () {
22862			var _this = this;
22863			this.$LG(window).on("keydown.lg.thumb.global" + this.core.lgId, function (e) {
22864				if (!_this.core.lgOpened || !_this.settings.toggleThumb)
22865					return;
22866				if (e.keyCode === 38) {
22867					e.preventDefault();
22868					_this.core.outer.addClass('lg-components-open');
22869				}
22870				else if (e.keyCode === 40) {
22871					e.preventDefault();
22872					_this.core.outer.removeClass('lg-components-open');
22873				}
22874			});
22875		};
22876		Thumbnail.prototype.destroy = function () {
22877			if (this.settings.thumbnail) {
22878				this.$LG(window).off(".lg.thumb.global" + this.core.lgId);
22879				this.core.LGel.off('.lg.thumb');
22880				this.core.LGel.off('.thumb');
22881				this.$thumbOuter.remove();
22882				this.core.outer.removeClass('lg-has-thumb');
22883			}
22884		};
22885		return Thumbnail;
22886	}());
22887
22888	return Thumbnail;
22889
22890})));
22891/*!
22892 * lightgallery | 2.5.0 | June 13th 2022
22893 * http://www.lightgalleryjs.com/
22894 * Copyright (c) 2020 Sachin Neravath;
22895 * @license GPLv3
22896 */
22897
22898(function (global, factory) {
22899	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
22900	typeof define === 'function' && define.amd ? define(factory) :
22901	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.lgVideo = factory());
22902}(this, (function () { 'use strict';
22903
22904	/*! *****************************************************************************
22905	Copyright (c) Microsoft Corporation.
22906
22907	Permission to use, copy, modify, and/or distribute this software for any
22908	purpose with or without fee is hereby granted.
22909
22910	THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
22911	REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
22912	AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
22913	INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22914	LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22915	OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22916	PERFORMANCE OF THIS SOFTWARE.
22917	***************************************************************************** */
22918
22919	var __assign = function() {
22920		__assign = Object.assign || function __assign(t) {
22921			for (var s, i = 1, n = arguments.length; i < n; i++) {
22922				s = arguments[i];
22923				for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
22924			}
22925			return t;
22926		};
22927		return __assign.apply(this, arguments);
22928	};
22929
22930	var videoSettings = {
22931		autoplayFirstVideo: true,
22932		youTubePlayerParams: false,
22933		vimeoPlayerParams: false,
22934		wistiaPlayerParams: false,
22935		gotoNextSlideOnVideoEnd: true,
22936		autoplayVideoOnSlide: false,
22937		videojs: false,
22938		videojsTheme: '',
22939		videojsOptions: {},
22940	};
22941
22942	/**
22943	 * List of lightGallery events
22944	 * All events should be documented here
22945	 * Below interfaces are used to build the website documentations
22946	 * */
22947	var lGEvents = {
22948		afterAppendSlide: 'lgAfterAppendSlide',
22949		init: 'lgInit',
22950		hasVideo: 'lgHasVideo',
22951		containerResize: 'lgContainerResize',
22952		updateSlides: 'lgUpdateSlides',
22953		afterAppendSubHtml: 'lgAfterAppendSubHtml',
22954		beforeOpen: 'lgBeforeOpen',
22955		afterOpen: 'lgAfterOpen',
22956		slideItemLoad: 'lgSlideItemLoad',
22957		beforeSlide: 'lgBeforeSlide',
22958		afterSlide: 'lgAfterSlide',
22959		posterClick: 'lgPosterClick',
22960		dragStart: 'lgDragStart',
22961		dragMove: 'lgDragMove',
22962		dragEnd: 'lgDragEnd',
22963		beforeNextSlide: 'lgBeforeNextSlide',
22964		beforePrevSlide: 'lgBeforePrevSlide',
22965		beforeClose: 'lgBeforeClose',
22966		afterClose: 'lgAfterClose',
22967		rotateLeft: 'lgRotateLeft',
22968		rotateRight: 'lgRotateRight',
22969		flipHorizontal: 'lgFlipHorizontal',
22970		flipVertical: 'lgFlipVertical',
22971		autoplay: 'lgAutoplay',
22972		autoplayStart: 'lgAutoplayStart',
22973		autoplayStop: 'lgAutoplayStop',
22974	};
22975
22976	var param = function (obj) {
22977		return Object.keys(obj)
22978			.map(function (k) {
22979			return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]);
22980		})
22981			.join('&');
22982	};
22983	var getVimeoURLParams = function (defaultParams, videoInfo) {
22984		if (!videoInfo || !videoInfo.vimeo)
22985			return '';
22986		var urlParams = videoInfo.vimeo[2] || '';
22987		var defaultPlayerParams = defaultParams && Object.keys(defaultParams).length !== 0
22988			? '&' + param(defaultParams)
22989			: '';
22990		// Support private video
22991		var urlWithHash = videoInfo.vimeo[0].split('/').pop() || '';
22992		var urlWithHashWithParams = urlWithHash.split('?')[0] || '';
22993		var hash = urlWithHashWithParams.split('#')[0];
22994		var isPrivate = videoInfo.vimeo[1] !== hash;
22995		if (isPrivate) {
22996			urlParams = urlParams.replace("/" + hash, '');
22997		}
22998		urlParams =
22999			urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || '';
23000		// For vimeo last params gets priority if duplicates found
23001		// Uncode edit ##START##
23002		var vimeoPlayerParams = '?autoplay=0';
23003		if ( videoInfo.autoplay !== '' ) {
23004			vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' );
23005			vimeoPlayerParams = vimeoPlayerParams.replace(new RegExp('([?&])autoplay(&|$)'), '$1$2' );
23006		} else {
23007			if ( typeof SiteParameters !== 'undefined' && typeof SiteParameters.vimeoPlayerParams !== 'undefined' && SiteParameters.vimeoPlayerParams !== '' ) {
23008				vimeoPlayerParams = SiteParameters.vimeoPlayerParams;
23009			}
23010		}
23011		if ( videoInfo.muted !== '' ) {
23012			vimeoPlayerParams += '&muted=' + (videoInfo.muted === 'yes');
23013		} else {
23014			if ( urlParams.indexOf('muted=') < 0 && vimeoPlayerParams.indexOf('muted=') < 0 ) {
23015				vimeoPlayerParams += '&muted=1';
23016			}
23017		}
23018		// var vimeoPlayerParams = "?autoplay=0&muted=1" + (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams;
23019		vimeoPlayerParams += (isPrivate ? "&h=" + hash : '') + defaultPlayerParams + urlParams;
23020		// Uncode edit ##END##
23021		return vimeoPlayerParams;
23022	};
23023
23024	/**
23025	 * Video module for lightGallery
23026	 * Supports HTML5, YouTube, Vimeo, wistia videos
23027	 *
23028	 *
23029	 * @ref Wistia
23030	 * https://wistia.com/support/integrations/wordpress(How to get url)
23031	 * https://wistia.com/support/developers/embed-options#using-embed-options
23032	 * https://wistia.com/support/developers/player-api
23033	 * https://wistia.com/support/developers/construct-an-embed-code
23034	 * http://jsfiddle.net/xvnm7xLm/
23035	 * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
23036	 * https://wistia.com/support/embed-and-share/sharing-videos
23037	 * https://private-sharing.wistia.com/medias/mwhrulrucj
23038	 *
23039	 * @ref Youtube
23040	 * https://developers.google.com/youtube/player_parameters#enablejsapi
23041	 * https://developers.google.com/youtube/iframe_api_reference
23042	 * https://developer.chrome.com/blog/autoplay/#iframe-delegation
23043	 *
23044	 * @ref Vimeo
23045	 * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url
23046	 * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode
23047	 * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters
23048	 */
23049	var Video = /** @class */ (function () {
23050		function Video(instance) {
23051			// get lightGallery core plugin instance
23052			this.core = instance;
23053			this.settings = __assign(__assign({}, videoSettings), this.core.settings);
23054			return this;
23055		}
23056		Video.prototype.init = function () {
23057			var _this = this;
23058			/**
23059			 * Event triggered when video url found without poster
23060			 * Append video HTML
23061			 * Play if autoplayFirstVideo is true
23062			 */
23063			this.core.LGel.on(lGEvents.hasVideo + ".video", this.onHasVideo.bind(this));
23064			this.core.LGel.on(lGEvents.posterClick + ".video", function () {
23065				var $el = _this.core.getSlideItem(_this.core.index);
23066				_this.loadVideoOnPosterClick($el);
23067			});
23068			this.core.LGel.on(lGEvents.slideItemLoad + ".video", this.onSlideItemLoad.bind(this));
23069			// @desc fired immediately before each slide transition.
23070			this.core.LGel.on(lGEvents.beforeSlide + ".video", this.onBeforeSlide.bind(this));
23071			// @desc fired immediately after each slide transition.
23072			this.core.LGel.on(lGEvents.afterSlide + ".video", this.onAfterSlide.bind(this));
23073		};
23074		/**
23075		 * @desc Event triggered when a slide is completely loaded
23076		 *
23077		 * @param {Event} event - lightGalley custom event
23078		 */
23079		Video.prototype.onSlideItemLoad = function (event) {
23080			var _this = this;
23081			var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index;
23082			// Should check the active slide as well as user may have moved to different slide before the first slide is loaded
23083			if (this.settings.autoplayFirstVideo &&
23084				isFirstSlide &&
23085				index === this.core.index) {
23086				// Delay is just for the transition effect on video load
23087				setTimeout(function () {
23088					_this.loadAndPlayVideo(index);
23089				}, 200);
23090			}
23091			// Should not call on first slide. should check only if the slide is active
23092			if (!isFirstSlide &&
23093				this.settings.autoplayVideoOnSlide &&
23094				index === this.core.index) {
23095					setTimeout(function () {
23096						_this.loadAndPlayVideo(index);
23097					}, 500);
23098				}
23099		};
23100		/**
23101		 * @desc Event triggered when video url or poster found
23102		 * Append video HTML is poster is not given
23103		 * Play if autoplayFirstVideo is true
23104		 *
23105		 * @param {Event} event - Javascript Event object.
23106		 */
23107		Video.prototype.onHasVideo = function (event) {
23108			var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster;
23109			if (!hasPoster) {
23110				// All functions are called separately if poster exist in loadVideoOnPosterClick function
23111				this.appendVideos(this.core.getSlideItem(index), {
23112					src: src,
23113					addClass: 'lg-object',
23114					index: index,
23115					html5Video: html5Video,
23116					// Uncode edit ##START##
23117					autoplay: event.target.getAttribute('data-lb-autoplay'),
23118					muted: event.target.getAttribute('data-lb-muted'),
23119					// Uncode edit ##END##
23120				});
23121				// Automatically navigate to next slide once video reaches the end.
23122				this.gotoNextSlideOnVideoEnd(src, index);
23123			}
23124		};
23125		/**
23126		 * @desc fired immediately before each slide transition.
23127		 * Pause the previous video
23128		 * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos.
23129		 *
23130		 * @param {Event} event - Javascript Event object.
23131		 * @param {number} prevIndex - Previous index of the slide.
23132		 * @param {number} index - Current index of the slide
23133		 */
23134		Video.prototype.onBeforeSlide = function (event) {
23135			if (this.core.lGalleryOn) {
23136				var prevIndex = event.detail.prevIndex;
23137				this.pauseVideo(prevIndex);
23138			}
23139			// Uncode edit ##START##
23140			var _a = event.detail, index = _a.index;
23141			var $slide = this.core.getSlideItem(index);
23142			
23143			var iframe = $slide.selector.querySelector('iframe');
23144			if ( iframe != null ) {
23145
23146				var data_play = iframe.getAttribute('data-autoplay');
23147				if ( typeof data_play !== 'undefined' && data_play === '1' ) {
23148					this.loadAndPlayVideo(index);
23149
23150					var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {},
23151						$videoElement = this.core.getSlideItem(index).find('.lg-video-object').first();
23152					if (videoInfo.vimeo) {
23153						var vimeoPlayer = new Vimeo.Player($videoElement.get());
23154						vimeoPlayer.on('play', function () {
23155							vimeoPlayer.setCurrentTime(0);
23156						});
23157					} else if ( videoInfo.youtube ) {
23158						try {
23159							$videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"seekTo\",\"args\":[0, true]}", '*');
23160						}
23161						catch (e) {
23162							console.warn(e);
23163						}
23164					}
23165				}
23166			}
23167			// Uncode edit ##END##
23168		};
23169		/**
23170		 * @desc fired immediately after each slide transition.
23171		 * Play video if autoplayVideoOnSlide option is enabled.
23172		 *
23173		 * @param {Event} event - Javascript Event object.
23174		 * @param {number} prevIndex - Previous index of the slide.
23175		 * @param {number} index - Current index of the slide
23176		 * @todo should check on onSlideLoad as well if video is not loaded on after slide
23177		 */
23178		Video.prototype.onAfterSlide = function (event) {
23179			var _this = this;
23180			var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex;
23181			// Do not call on first slide
23182			var $slide = this.core.getSlideItem(index);
23183			if (this.settings.autoplayVideoOnSlide && index !== prevIndex) {
23184				if ($slide.hasClass('lg-complete')) {
23185					setTimeout(function () {
23186						_this.loadAndPlayVideo(index);
23187					}, 100);
23188				}
23189			}
23190		};
23191		Video.prototype.loadAndPlayVideo = function (index) {
23192			var $slide = this.core.getSlideItem(index);
23193			var currentGalleryItem = this.core.galleryItems[index];
23194			if (currentGalleryItem.poster) {
23195				this.loadVideoOnPosterClick($slide, true);
23196			}
23197			else {
23198				//Uncode edit ##START##
23199				// this.playVideo(index);
23200				var iframe = $slide.selector.querySelector('iframe');
23201				if ( iframe != null ) {
23202					var data_play = iframe.getAttribute('data-autoplay');
23203					if ( typeof data_play !== 'undefined' ) {
23204						if ( data_play === '1' && this.core.index == index ) {
23205							this.playVideo(index);
23206						} else {
23207							this.pauseVideo(index);
23208						}
23209					}
23210				}
23211				//Uncode edit ##END##
23212			}
23213		};
23214		/**
23215		 * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
23216		 * @param {number} index - Index of the slide
23217		 */
23218		Video.prototype.playVideo = function (index) {
23219			this.controlVideo(index, 'play');
23220		};
23221		/**
23222		 * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide.
23223		 * @param {number} index - Index of the slide
23224		 */
23225		Video.prototype.pauseVideo = function (index) {
23226			this.controlVideo(index, 'pause');
23227		};
23228		// Uncode edit ##START##
23229		//Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) {
23230		Video.prototype.getVideoHtml = function (src, addClass, index, html5Video, autoplay, muted) {
23231		// Uncode edit ##END##
23232			var video = '';
23233			var videoInfo = this.core.galleryItems[index]
23234				.__slideVideoInfo || {};
23235			var currentGalleryItem = this.core.galleryItems[index];
23236			var videoTitle = currentGalleryItem.title || currentGalleryItem.alt;
23237			videoTitle = videoTitle ? 'title="' + videoTitle + '"' : '';
23238			var commonIframeProps = "allowtransparency=\"true\"\n            frameborder=\"0\"\n            scrolling=\"no\"\n            allowfullscreen\n            mozallowfullscreen\n            webkitallowfullscreen\n            oallowfullscreen\n            msallowfullscreen";
23239			if (videoInfo.youtube) {
23240				var videoId = 'lg-youtube' + index;
23241				var slideUrlParams = videoInfo.youtube[2]
23242					? videoInfo.youtube[2] + '&'
23243					: '';
23244				// For youtube first parms gets priority if duplicates found
23245				// Uncode edit ##START##
23246				// var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&autoplay=0&mute=1&enablejsapi=1";
23247				var youTubePlayerParams = "?" + slideUrlParams + "wmode=opaque&enablejsapi=1";
23248				if ( ( slideUrlParams.indexOf('autoplay=') < 0 && youTubePlayerParams.indexOf('autoplay=') < 0 ) ) {
23249					youTubePlayerParams += '&autoplay=0';
23250				}
23251				if ( slideUrlParams.indexOf('mute=') < 0 && youTubePlayerParams.indexOf('mute=') < 0 ) {
23252					youTubePlayerParams += '&mute=1';
23253				}
23254				var data_video = '';
23255				if ( autoplay !== '' ) {
23256					//youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1autoplay=' + (autoplay === 'yes' ? 1 : 0) + '$3' );
23257					youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay=(.*?)(&|$)'), '$1$3' );
23258					youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])autoplay'), '$1' );
23259					data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"';
23260				}
23261				// if ( muted !== '' ) {
23262				// 	youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1mute=' + (muted === 'yes' ? 1 : 0) + '$3' );
23263				// }
23264				youTubePlayerParams = youTubePlayerParams.replace(new RegExp('([?&])mute=(.*?)(&|$)'), '$1$3' );
23265
23266				youTubePlayerParams = youTubePlayerParams.replace('??', '?');
23267				// Uncode edit ##END##
23268				var playerParams = youTubePlayerParams +
23269					(this.settings.youTubePlayerParams
23270						? '&' + param(this.settings.youTubePlayerParams)
23271						: '');
23272				// Uncode edit ##START##
23273				// 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>";
23274				var nocookie = typeof SiteParameters.uncode_nocookie !== 'undefined' ? SiteParameters.uncode_nocookie : '';
23275				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>";
23276				var tag = document.createElement('script');
23277				tag.src = "//www.youtube.com/player_api";
23278				var firstScriptTag = document.getElementsByTagName('script')[0];
23279				firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
23280
23281				// Replace the 'ytplayer' element with an <iframe> and
23282				// YouTube player after the API code downloads.
23283				var ytIframeplayer,
23284					setMute = muted === 'yes' ? 0 : 100;
23285				window.onYouTubePlayerAPIReady = function() {
23286					ytIframeplayer = new YT.Player(videoId, {
23287						videoId: videoInfo.youtube[1],
23288						events: {
23289							'onReady': function (event) {
23290								event.target.setVolume(setMute);
23291							}
23292						}
23293					});
23294				}
23295				// Uncode edit ##END##
23296			}
23297			else if (videoInfo.vimeo) {
23298				var videoId = 'lg-vimeo' + index;
23299				// Uncode edit ##START##
23300				videoInfo.autoplay = autoplay;
23301				videoInfo.muted = muted;
23302				// Uncode edit ##END##
23303				var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo);
23304				// Uncode edit ##START##
23305				// 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>";
23306				var data_video = '';
23307				if ( autoplay !== '' ) {
23308					data_video = ' data-autoplay="' + (autoplay === 'yes' ? 1 : 0) + '"';
23309				}
23310				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>";
23311				// Uncode edit ##END##
23312			}
23313			else if (videoInfo.wistia) {
23314				var wistiaId = 'lg-wistia' + index;
23315				var playerParams = param(this.settings.wistiaPlayerParams);
23316				playerParams = playerParams ? '?' + playerParams : '';
23317				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>";
23318			}
23319			else if (videoInfo.html5) {
23320				var html5VideoMarkup = '';
23321				for (var i = 0; i < html5Video.source.length; i++) {
23322					html5VideoMarkup += "<source src=\"" + html5Video.source[i].src + "\" type=\"" + html5Video.source[i].type + "\">";
23323				}
23324				if (html5Video.tracks) {
23325					var _loop_1 = function (i) {
23326						var trackAttributes = '';
23327						var track = html5Video.tracks[i];
23328						Object.keys(track || {}
23328).forEach(function (key) {
23329							trackAttributes += key + "=\"" + track[key] + "\" ";
23330						});
23331						html5VideoMarkup += "<track " + trackAttributes + ">";
23332					};
23333					for (var i = 0; i < html5Video.tracks.length; i++) {
23334						_loop_1(i);
23335					}
23336				}
23337				var html5VideoAttrs_1 = '';
23338				var videoAttributes_1 = html5Video.attributes || {};
23339				Object.keys(videoAttributes_1 || {}).forEach(function (key) {
23340					html5VideoAttrs_1 += key + "=\"" + videoAttributes_1[key] + "\" ";
23341				});
23342				video = "<video class=\"lg-video-object lg-html5 " + (this.settings.videojs && this.settings.videojsTheme
23343					? this.settings.videojsTheme + ' '
23344					: '') + " " + (this.settings.videojs ? ' video-js' : '') + "\" " + html5VideoAttrs_1 + ">\n                " + html5VideoMarkup + "\n                Your browser does not support HTML5 video.\n            </video>";
23345			}
23346			return video;
23347		};
23348		/**
23349		 * @desc - Append videos to the slide
23350		 *
23351		 * @param {HTMLElement} el - slide element
23352		 * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo
23353		 */
23354		Video.prototype.appendVideos = function (el, videoParams) {
23355			var _a;
23356			// Uncode edit ##START##
23357			// var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video);
23358			var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video, videoParams.autoplay, videoParams.muted);
23359			// Uncode edit ##END##
23360			el.find('.lg-video-cont').append(videoHtml);
23361			var $videoElement = el.find('.lg-video-object').first();
23362			if (videoParams.html5Video) {
23363				$videoElement.on('mousedown.lg.video', function (e) {
23364					e.stopPropagation();
23365				});
23366			}
23367			if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) {
23368				try {
23369					return videojs($videoElement.get(), this.settings.videojsOptions);
23370				}
23371				catch (e) {
23372					console.warn('lightGallery:- Make sure you have included videojs');
23373				}
23374			}
23375		};
23376		Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) {
23377			var _this = this;
23378			var $videoElement = this.core
23379				.getSlideItem(index)
23380				.find('.lg-video-object')
23381				.first();
23382			var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
23383			if (this.settings.gotoNextSlideOnVideoEnd) {
23384				if (videoInfo.html5) {
23385					$videoElement.on('ended', function () {
23386						_this.core.goToNextSlide();
23387					});
23388				}
23389				else if (videoInfo.vimeo) {
23390					try {
23391						// https://github.com/vimeo/player.js/#ended
23392						new Vimeo.Player($videoElement.get()).on('ended', function () {
23393							_this.core.goToNextSlide();
23394						});
23395					}
23396					catch (e) {
23397						console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
23398					}
23399				}
23400				else if (videoInfo.wistia) {
23401					try {
23402						window._wq = window._wq || [];
23403						// @todo Event is gettign triggered multiple times
23404						window._wq.push({
23405							id: $videoElement.attr('id'),
23406							onReady: function (video) {
23407								video.bind('end', function () {
23408									_this.core.goToNextSlide();
23409								});
23410							},
23411						});
23412					}
23413					catch (e) {
23414						console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
23415					}
23416				}
23417			}
23418		};
23419		Video.prototype.controlVideo = function (index, action) {
23420			var $videoElement = this.core
23421				.getSlideItem(index)
23422				.find('.lg-video-object')
23423				.first();
23424			var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};
23425			if (!$videoElement.get())
23426				return;
23427			if (videoInfo.youtube) {
23428				try {
23429					$videoElement.get().contentWindow.postMessage("{\"event\":\"command\",\"func\":\"" + action + "Video\",\"args\":\"\"}", '*');
23430				}
23431				catch (e) {
23432					console.warn("lightGallery:- " + e);
23433				}
23434			}
23435			else if (videoInfo.vimeo) {
23436				try {
23437					new Vimeo.Player($videoElement.get())[action]();
23438				}
23439				catch (e) {
23440					console.warn('lightGallery:- Make sure you have included //github.com/vimeo/player.js');
23441				}
23442			}
23443			else if (videoInfo.html5) {
23444				if (this.settings.videojs) {
23445					try {
23446						videojs($videoElement.get())[action]();
23447					}
23448					catch (e) {
23449						console.warn('lightGallery:- Make sure you have included videojs');
23450					}
23451				}
23452				else {
23453					$videoElement.get()[action]();
23454				}
23455			}
23456			else if (videoInfo.wistia) {
23457				try {
23458					window._wq = window._wq || [];
23459					// @todo Find a way to destroy wistia player instance
23460					window._wq.push({
23461						id: $videoElement.attr('id'),
23462						onReady: function (video) {
23463							video[action]();
23464						},
23465					});
23466				}
23467				catch (e) {
23468					console.warn('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');
23469				}
23470			}
23471		};
23472		Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) {
23473			var _this = this;
23474			// check slide has poster
23475			if (!$el.hasClass('lg-video-loaded')) {
23476				// check already video element present
23477				if (!$el.hasClass('lg-has-video')) {
23478					$el.addClass('lg-has-video');
23479					var _html = void 0;
23480					var _src = this.core.galleryItems[this.core.index].src;
23481					var video = this.core.galleryItems[this.core.index].video;
23482					if (video) {
23483						_html =
23484							typeof video === 'string' ? JSON.parse(video) : video;
23485					}
23486					var videoJsPlayer_1 = this.appendVideos($el, {
23487						src: _src,
23488						addClass: '',
23489						index: this.core.index,
23490						html5Video: _html,
23491					});
23492					this.gotoNextSlideOnVideoEnd(_src, this.core.index);
23493					var $tempImg = $el.find('.lg-object').first().get();
23494					// @todo make sure it is working
23495					$el.find('.lg-video-cont').first().append($tempImg);
23496					$el.addClass('lg-video-loading');
23497					videoJsPlayer_1 &&
23498						videoJsPlayer_1.ready(function () {
23499							videoJsPlayer_1.on('loadedmetadata', function () {
23500								_this.onVideoLoadAfterPosterClick($el, _this.core.index);
23501							});
23502						});
23503					$el.find('.lg-video-object')
23504						.first()
23505						.on('load.lg error.lg loadedmetadata.lg', function () {
23506						setTimeout(function () {
23507							_this.onVideoLoadAfterPosterClick($el, _this.core.index);
23508						}, 50);
23509					});
23510				}
23511				else {
23512					this.playVideo(this.core.index);
23513				}
23514			}
23515			else if (forcePlay) {
23516				this.playVideo(this.core.index);
23517			}
23518		};
23519		Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) {
23520			$el.addClass('lg-video-loaded');
23521			this.playVideo(index);
23522		};
23523		Video.prototype.destroy = function () {
23524			this.core.LGel.off('.lg.video');
23525			this.core.LGel.off('.video');
23526		};
23527		return Video;
23528	}());
23529
23530	return Video;
23531
23532})));
23533
23534
23535/*! @vimeo/player v2.17.1 | (c) 2022 Vimeo | MIT License | https://github.com/vimeo/player.js */
23536!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:{}}
23536),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: 9,482 bytes, line 23536
23536var 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)}},{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: 11,908 bytes, lines 23536-24016
23536))}(),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});
23537
23538/**
23539 * Owl carousel
23540 * @version 2.0.0-beta.3
23541 * @author Bartosz Wojciechowski
23542 * @license The MIT License (MIT)
23543 * @todo Lazy Load Icon
23544 * @todo prevent animationend bubling
23545 * @todo itemsScaleUp
23546 * @todo Test Zepto
23547 * @todo stagePadding calculate wrong active classes
23548 */
23549;(function($, window, document, undefined) {
23550
23551	/**
23552	 * Creates a carousel.
23553	 * @class The Owl Carousel.
23554	 * @public
23555	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
23556	 * @param {Object} [options] - The options
23557	 */
23558	function Owl(element, options) {
23559
23560		/**
23561		 * Current settings for the carousel.
23562		 * @public
23563		 */
23564		this.settings = null;
23565
23566		/**
23567		 * Current options set by the caller including defaults.
23568		 * @public
23569		 */
23570		this.options = $.extend({}, Owl.Defaults, options);
23571
23572		/**
23573		 * Plugin element.
23574		 * @public
23575		 */
23576		this.$element = $(element);
23577
23578		/**
23579		 * Proxied event handlers.
23580		 * @protected
23581		 */
23582		this._handlers = {};
23583
23584		/**
23585		 * References to the running plugins of this carousel.
23586		 * @protected
23587		 */
23588		this._plugins = {};
23589
23590		/**
23591		 * Currently suppressed events to prevent them from beeing retriggered.
23592		 * @protected
23593		 */
23594		this._supress = {};
23595
23596		/**
23597		 * Absolute current position.
23598		 * @protected
23599		 */
23600		this._current = null;
23601
23602		/**
23603		 * Animation speed in milliseconds.
23604		 * @protected
23605		 */
23606		this._speed = null;
23607
23608		/**
23609		 * Coordinates of all items in pixel.
23610		 * @todo The name of this member is missleading.
23611		 * @protected
23612		 */
23613		this._coordinates = [];
23614
23615		/**
23616		 * Current breakpoint.
23617		 * @todo Real media queries would be nice.
23618		 * @protected
23619		 */
23620		this._breakpoint = null;
23621
23622		/**
23623		 * Current width of the plugin element.
23624		 */
23625		this._width = null;
23626
23627		/**
23628		 * All real items.
23629		 * @protected
23630		 */
23631		this._items = [];
23632
23633		/**
23634		 * All cloned items.
23635		 * @protected
23636		 */
23637		this._clones = [];
23638
23639		/**
23640		 * Merge values of all items.
23641		 * @todo Maybe this could be part of a plugin.
23642		 * @protected
23643		 */
23644		this._mergers = [];
23645
23646		/**
23647		 * Widths of all items.
23648		 */
23649		this._widths = [];
23650
23651		/**
23652		 * Invalidated parts within the update process.
23653		 * @protected
23654		 */
23655		this._invalidated = {};
23656
23657		/**
23658		 * Ordered list of workers for the update process.
23659		 * @protected
23660		 */
23661		this._pipe = [];
23662
23663		/**
23664		 * Current state information for the drag operation.
23665		 * @todo #261
23666		 * @protected
23667		 */
23668		this._drag = {
23669			time: null,
23670			target: null,
23671			pointer: null,
23672			stage: {
23673				start: null,
23674				current: null
23675			},
23676			direction: null
23677		};
23678
23679		/**
23680		 * Current state information and their tags.
23681		 * @type {Object}
23682		 * @protected
23683		 */
23684		this._states = {
23685			current: {},
23686			tags: {
23687				'initializing': [ 'busy' ],
23688				'animating': [ 'busy' ],
23689				'dragging': [ 'interacting' ]
23690			}
23691		};
23692
23693		$.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
23694			this._handlers[handler] = $.proxy(this[handler], this);
23695		}, this));
23696
23697		$.each(Owl.Plugins, $.proxy(function(key, plugin) {
23698			this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
23699				= new plugin(this);
23700		}, this));
23701
23702		$.each(Owl.Workers, $.proxy(function(priority, worker) {
23703			this._pipe.push({
23704				'filter': worker.filter,
23705				'run': $.proxy(worker.run, this)
23706			});
23707		}, this));
23708
23709		this.setup();
23710		this.initialize();
23711	}
23712
23713	/**
23714	 * Default options for the carousel.
23715	 * @public
23716	 */
23717	Owl.Defaults = {
23718		items: 3,
23719		loop: false,
23720		center: false,
23721		rewind: false,
23722
23723		mouseDrag: true,
23724		touchDrag: true,
23725		pullDrag: true,
23726		freeDrag: false,
23727
23728		margin: 0,
23729		stagePadding: 0,
23730
23731		merge: false,
23732		mergeFit: true,
23733		autoWidth: false,
23734
23735		startPosition: 0,
23736		rtl: false,
23737
23738		smartSpeed: 250,
23739		fluidSpeed: false,
23740		dragEndSpeed: false,
23741
23742		responsive: {},
23743		responsiveRefreshRate: 200,
23744		responsiveBaseElement: window,
23745
23746		fallbackEasing: 'swing',
23747
23748		info: false,
23749
23750		nestedItemSelector: false,
23751		itemSelector: false,
23752		itemElement: 'div',
23753		stageElement: 'div',
23754
23755		refreshClass: 'owl-refresh',
23756		loadedClass: 'owl-loaded',
23757		loadingClass: 'owl-loading',
23758		rtlClass: 'owl-rtl',
23759		responsiveClass: 'owl-responsive',
23760		dragClass: 'owl-drag',
23761		itemClass: 'owl-item',
23762		stageClass: 'owl-stage',
23763		stageOuterClass: 'owl-stage-outer',
23764		grabClass: 'owl-grab'
23765	};
23766
23767	/**
23768	 * Enumeration for width.
23769	 * @public
23770	 * @readonly
23771	 * @enum {String}
23772	 */
23773	Owl.Width = {
23774		Default: 'default',
23775		Inner: 'inner',
23776		Outer: 'outer'
23777	};
23778
23779	/**
23780	 * Enumeration for types.
23781	 * @public
23782	 * @readonly
23783	 * @enum {String}
23784	 */
23785	Owl.Type = {
23786		Event: 'event',
23787		State: 'state'
23788	};
23789
23790	/**
23791	 * Contains all registered plugins.
23792	 * @public
23793	 */
23794	Owl.Plugins = {};
23795
23796	/**
23797	 * List of workers involved in the update process.
23798	 */
23799	Owl.Workers = [ {
23800		filter: [ 'width', 'settings' ],
23801		run: function() {
23802			this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width();
23803			//this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12);
23804		}
23805	}, {
23806		filter: [ 'width', 'items', 'settings' ],
23807		run: function(cache) {
23808			cache.current = this._items && this._items[this.relative(this._current)];
23809		}
23810	}, {
23811		filter: [ 'items', 'settings' ],
23812		run: function() {
23813			this.$stage.children('.cloned').remove();
23814		}
23815	}, {
23816		filter: [ 'width', 'items', 'settings' ],
23817		run: function(cache) {
23818			var margin = this.settings.margin || '',
23819				grid = !this.settings.autoWidth,
23820				rtl = this.settings.rtl,
23821				css = {
23822					'width': 'auto',
23823					'margin-left': rtl ? margin : '',
23824					'margin-right': rtl ? '' : margin
23825				};
23826
23827			!grid && this.$stage.children().css(css);
23828
23829			cache.css = css;
23830		}
23831	}, {
23832		filter: [ 'width', 'items', 'settings' ],
23833		run: function(cache) {
23834			//UNCODE edit to fix Chrome stage padding issue
23835			var width = Math.round((this.width() / this.settings.items).toFixed(3) - this.settings.margin),
23836				merge = null,
23837				iterator = this._items.length,
23838				grid = !this.settings.autoWidth,
23839				widths = [];
23840
23841			cache.items = {
23842				merge: false,
23843				width: width
23844			};
23845
23846			while (iterator--) {
23847				merge = this._mergers[iterator];
23848				merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
23849
23850				cache.items.merge = merge > 1 || cache.items.merge;
23851
23852				widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
23853			}
23854
23855			this._widths = widths;
23856		}
23857	}, {
23858		filter: [ 'items', 'settings' ],
23859		run: function() {
23860			var clones = [],
23861				items = this._items,
23862				settings = this.settings,
23863				view = Math.max(settings.items * 2, 4),
23864				size = Math.ceil(items.length / 2) * 2,
23865				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
23866				append = '',
23867				prepend = '';
23868
23869			repeat /= 2;
23870
23871			while (repeat--) {
23872				clones.push(this.normalize(clones.length / 2, true));
23873				append = append + items[clones[clones.length - 1]][0].outerHTML;
23874				clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
23875				prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
23876			}
23877
23878			this._clones = clones;
23879
23880			// var appendVideo = $(append).find('.uncode-video-container');
23881			// if (appendVideo.length) {
23882			// 	appendVideo.attr('data-id', Math.round(Math.random() * 100000));
23883			// }
23884			// var prependVideo = $(prepend).find('.uncode-video-container');
23885			// if (prependVideo.length) {
23886			// 	prependVideo.attr('data-id', Math.round(Math.random() * 100000));
23887			// }
23888			$(append).addClass('cloned').appendTo(this.$stage);
23889			$(prepend).addClass('cloned').prependTo(this.$stage);
23890		}
23891	}, {
23892		filter: [ 'width', 'items', 'settings' ],
23893		run: function() {
23894			var rtl = this.settings.rtl ? 1 : -1,
23895				size = this._clones.length + this._items.length,
23896				iterator = -1,
23897				previous = 0,
23898				current = 0,
23899				coordinates = [];
23900
23901			while (++iterator < size) {
23902				previous = coordinates[iterator - 1] || 0;
23903				current = this._widths[this.relative(iterator)] + this.settings.margin;
23904				coordinates.push(previous + current * rtl);
23905			}
23906
23907			this._coordinates = coordinates;
23908		}
23909	}, {
23910		filter: [ 'width', 'items', 'settings' ],
23911		run: function() {
23912			var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200,
23913				padding = stagePadding,
23914				coordinates = this._coordinates,
23915				css = {
23916					'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
23917					'padding-left': padding || '',
23918					'padding-right': padding || ''
23919				};
23920
23921			this.$stage.css(css);
23922		}
23923	}, {
23924		filter: [ 'width', 'items', 'settings' ],
23925		run: function(cache) {
23926			var iterator = this._coordinates.length,
23927				grid = !this.settings.autoWidth,
23928				items = this.$stage.children();
23929
23930			if (grid && cache.items.merge) {
23931				while (iterator--) {
23932					cache.css.width = this._widths[this.relative(iterator)];
23933					items.eq(iterator).css(cache.css);
23934				}
23935			} else if (grid) {
23936				cache.css.width = cache.items.width;
23937				items.css(cache.css);
23938			}
23939		}
23940	}, {
23941		filter: [ 'items' ],
23942		run: function() {
23943			this._coordinates.length < 1 && this.$stage.removeAttr('style');
23944		}
23945	}, {
23946		filter: [ 'width', 'items', 'settings' ],
23947		run: function(cache) {
23948			cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
23949			cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
23950			this.reset(cache.current);
23951		}
23952	}, {
23953		filter: [ 'position' ],
23954		run: function() {
23955			this.animate(this.coordinates(this._current));
23956		}
23957	}, {
23958		filter: [ 'width', 'position', 'items', 'settings' ],
23959		run: function() {
23960			var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200,
23961				rtl = this.settings.rtl ? 1 : -1,
23962				padding = this.settings.stagePadding * 2,
23963				begin = this.coordinates(this.current()) + padding,
23964				end = begin + this.width() * rtl,
23965				inner, outer, matches = [], i, n;
23966
23967			for (i = 0, n = this._coordinates.length; i < n; i++) {
23968				inner = this._coordinates[i - 1] || 0;
23969				outer = Math.abs(this._coordinates[i]) + padding * rtl;
23970
23971				if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
23972					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
23973					matches.push(i);
23974				}
23975			}
23976
23977			this.$stage.children('.active').removeClass('active');
23978			this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
23979
23980			if (this.settings.center) {
23981				this.$stage.children('.center').removeClass('center');
23982				this.$stage.children().eq(this.current()).addClass('center');
23983			}
23984		}
23985	} ];
23986
23987	/**
23988	 * Initializes the carousel.
23989	 * @protected
23990	 */
23991	Owl.prototype.initialize = function() {
23992		this.enter('initializing');
23993		this.trigger('initialize');
23994
23995		this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
23996
23997		if (this.settings.autoWidth && !this.is('pre-loading')) {
23998			var imgs, nestedSelector, width;
23999			imgs = this.$element.find('img');
24000			nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
24001			width = this.$element.children(nestedSelector).width();
24002
24003			if (imgs.length && width <= 0) {
24004				this.preloadAutoWidthImages(imgs);
24005			}
24006		}
24007
24008		this.$element.addClass(this.options.loadingClass);
24009
24010		// create stage
24011		this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')
24012			.wrap('<div class="' + this.settings.stageOuterClass + '"/>');
24013
24014		//UNCODE edit to exclude hidden items
24015		if ( this.settings.itemSelector ) {
24016			// append stage
24017			this.$element.prepend(this.$stage.parent());
24018			// append content
24019			this.replace(this.$element.find(' > ' + this.settings.itemSelector).not(this.$stage.parent()));
24020		} else {
24021			// append stage
24022			this.$element.append(this.$stage.parent());
24023			// append content
24024			this.replace(this.$element.children().not(this.$stage.parent()));
24025		}
24026
24027		// check visibility
24028		if (this.$element.is(':visible')) {
24029			// update view
24030			this.refresh();
24031		} else {
24032			// invalidate width
24033			this.invalidate('width');
24034		}
24035
24036		this.$element
24037			.removeClass(this.options.loadingClass)
24038			.addClass(this.options.loadedClass);
24039
24040		// register event handlers
24041		this.registerEventHandlers();
24042
24043		this.leave('initializing');
24044		this.trigger('initialized');
24045	};
24046
24047	/**
24048	 * Setups the current settings.
24049	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
24050	 * @todo Support for media queries by using `matchMedia` would be nice.
24051	 * @public
24052	 */
24053	Owl.prototype.setup = function() {
24054		var viewport = this.viewport(),
24055			overwrites = this.options.responsive,
24056			match = -1,
24057			settings = null;
24058
24059		if (!overwrites) {
24060			settings = $.extend({}, this.options);
24061		} else {
24062			$.each(overwrites, function(breakpoint) {
24063				if (breakpoint <= viewport && breakpoint > match) {
24064					match = Number(breakpoint);
24065				}
24066			});
24067
24068			settings = $.extend({}, this.options, overwrites[match]);
24069			delete settings.responsive;
24070
24071			// responsive class
24072			if (settings.responsiveClass) {
24073				this.$element.attr('class',
24074					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
24075				);
24076			}
24077		}
24078
24079		if (this.settings === null || this._breakpoint !== match) {
24080			this.trigger('change', { property: { name: 'settings', value: settings } });
24081			this._breakpoint = match;
24082			this.settings = settings;
24083			this.invalidate('settings');
24084			this.trigger('changed', { property: { name: 'settings', value: this.settings } });
24085		}
24086	};
24087
24088	/**
24089	 * Updates option logic if necessery.
24090	 * @protected
24091	 */
24092	Owl.prototype.optionsLogic = function() {
24093		if (this.settings.autoWidth) {
24094			this.settings.stagePadding = false;
24095			this.settings.merge = false;
24096		}
24097	};
24098
24099	/**
24100	 * Prepares an item before add.
24101	 * @todo Rename event parameter `content` to `item`.
24102	 * @protected
24103	 * @returns {jQuery|HTMLElement} - The item container.
24104	 */
24105	Owl.prototype.prepare = function(item, index) {
24106		var event = this.trigger('prepare', { content: item });
24107		if (!event.data) {
24108			event.data = $('<' + this.settings.itemElement + '/>')
24109				.addClass(this.options.itemClass).attr('data-index', index + 1).append(item)
24110		}
24111
24112		this.trigger('prepared', { content: event.data });
24113
24114		return event.data;
24115	};
24116
24117	/**
24118	 * Updates the view.
24119	 * @public
24120	 */
24121	Owl.prototype.update = function() {
24122		var i = 0,
24123			n = this._pipe.length,
24124			filter = $.proxy(function(p) { return this[p] }, this._invalidated),
24125			cache = {};
24126
24127		while (i < n) {
24128			if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
24129				this._pipe[i].run(cache);
24130			}
24131			i++;
24132		}
24133
24134		this._invalidated = {};
24135
24136		!this.is('valid') && this.enter('valid');
24137	};
24138
24139	/**
24140	 * Gets the width of the view.
24141	 * @public
24142	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
24143	 * @returns {Number} - The width of the view in pixel.
24144	 */
24145	Owl.prototype.width = function(dimension) {
24146		dimension = dimension || Owl.Width.Default;
24147		var stagePadding = (this._width < 480 && this.settings.stagePadding > 0) ? 41 : (this._width * this.settings.stagePadding) / 200;
24148		switch (dimension) {
24149			case Owl.Width.Inner:
24150			case Owl.Width.Outer:
24151				return this._width;
24152			default:
24153				return this._width - stagePadding * 2 + this.settings.margin;
24154		}
24155	};
24156
24157	/**
24158	 * Refreshes the carousel primarily for adaptive purposes.
24159	 * @public
24160	 */
24161	Owl.prototype.refresh = function() {
24162		this.enter('refreshing');
24163		this.trigger('refresh');
24164
24165		this.setup();
24166
24167		this.optionsLogic();
24168
24169		this.$element.addClass(this.options.refreshClass);
24170
24171		this.update();
24172
24173		this.$element.removeClass(this.options.refreshClass);
24174
24175		this.leave('refreshing');
24176		this.trigger('refreshed');
24177	};
24178
24179	/**
24180	 * Checks window `resize` event.
24181	 * @protected
24182	 */
24183	Owl.prototype.onThrottledResize = function() {
24184		window.clearTimeout(this.resizeTimer);
24185		this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
24186	};
24187
24188	/**
24189	 * Checks window `resize` event.
24190	 * @protected
24191	 */
24192	Owl.prototype.onResize = function() {
24193		if (!this._items.length) {
24194			return false;
vendor: 46,301 bytes, lines 24195-25899
24195		}
24196
24197		if (this._width === this.$element.width()) {
24198			return false;
24199		}
24200
24201		if (!this.$element.is(':visible')) {
24202			return false;
24203		}
24204
24205		this.enter('resizing');
24206
24207		if (this.trigger('resize').isDefaultPrevented()) {
24208			this.leave('resizing');
24209			return false;
24210		}
24211
24212		this.invalidate('width');
24213
24214		this.refresh();
24215
24216		this.leave('resizing');
24217		this.trigger('resized');
24218	};
24219
24220	/**
24221	 * Registers event handlers.
24222	 * @todo Check `msPointerEnabled`
24223	 * @todo #261
24224	 * @protected
24225	 */
24226	Owl.prototype.registerEventHandlers = function() {
24227		if ($.support.transition) {
24228			this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
24229		}
24230
24231		if (this.settings.responsive !== false) {
24232			this.on(window, 'resize', this._handlers.onThrottledResize);
24233		}
24234
24235		if (this.settings.mouseDrag) {
24236			this.$element.addClass(this.options.dragClass);
24237			this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
24238			this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
24239		}
24240
24241		if (this.settings.touchDrag){
24242			this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
24243			this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
24244		}
24245	};
24246
24247	/**
24248	 * Handles `touchstart` and `mousedown` events.
24249	 * @todo Horizontal swipe threshold as option
24250	 * @todo #261
24251	 * @protected
24252	 * @param {Event} event - The event arguments.
24253	 */
24254	Owl.prototype.onDragStart = function(event) {
24255		var stage = null;
24256
24257		if (event.which === 3) {
24258			return;
24259		}
24260
24261		if ($.support.transform) {
24262			stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
24263			stage = {
24264				x: stage[stage.length === 16 ? 12 : 4],
24265				y: stage[stage.length === 16 ? 13 : 5]
24266			};
24267		} else {
24268			stage = this.$stage.position();
24269			stage = {
24270				x: this.settings.rtl ?
24271					stage.left + this.$stage.width() - this.width() + this.settings.margin :
24272					stage.left,
24273				y: stage.top
24274			};
24275		}
24276
24277		if (this.is('animating')) {
24278			$.support.transform ? this.animate(stage.x) : this.$stage.stop()
24279			this.invalidate('position');
24280		}
24281
24282		this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
24283
24284		this.speed(0);
24285
24286		this._drag.time = new Date().getTime();
24287		this._drag.target = $(event.target);
24288		this._drag.stage.start = stage;
24289		this._drag.stage.current = stage;
24290		this._drag.pointer = this.pointer(event);
24291
24292		$(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
24293
24294		$(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
24295			var delta = this.difference(this._drag.pointer, this.pointer(event));
24296
24297			$(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
24298
24299			if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
24300				return;
24301			}
24302
24303			event.preventDefault();
24304
24305			this.enter('dragging');
24306			this.trigger('drag');
24307		}, this));
24308	};
24309
24310	/**
24311	 * Handles the `touchmove` and `mousemove` events.
24312	 * @todo #261
24313	 * @protected
24314	 * @param {Event} event - The event arguments.
24315	 */
24316	Owl.prototype.onDragMove = function(event) {
24317		var minimum = null,
24318			maximum = null,
24319			pull = null,
24320			delta = this.difference(this._drag.pointer, this.pointer(event)),
24321			stage = this.difference(this._drag.stage.start, delta);
24322
24323		if (!this.is('dragging')) {
24324			return;
24325		}
24326
24327		event.preventDefault();
24328
24329		if (this.settings.loop) {
24330			minimum = this.coordinates(this.minimum());
24331			maximum = this.coordinates(this.maximum() + 1) - minimum;
24332			stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
24333		} else {
24334			minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
24335			maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
24336			pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
24337			stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
24338		}
24339
24340		this._drag.stage.current = stage;
24341
24342		this.animate(stage.x);
24343	};
24344
24345	/**
24346	 * Handles the `touchend` and `mouseup` events.
24347	 * @todo #261
24348	 * @todo Threshold for click event
24349	 * @protected
24350	 * @param {Event} event - The event arguments.
24351	 */
24352	Owl.prototype.onDragEnd = function(event) {
24353		var delta = this.difference(this._drag.pointer, this.pointer(event)),
24354			stage = this._drag.stage.current,
24355			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
24356
24357		$(document).off('.owl.core');
24358
24359		this.$element.removeClass(this.options.grabClass);
24360
24361		if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
24362			this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
24363			this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
24364			this.invalidate('position');
24365			this.update();
24366
24367			this._drag.direction = direction;
24368
24369			if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
24370				this._drag.target.one('click.owl.core', function() { return false; });
24371			}
24372		}
24373
24374		if (!this.is('dragging')) {
24375			return;
24376		}
24377
24378		this.leave('dragging');
24379		this.trigger('dragged');
24380	};
24381
24382	/**
24383	 * Gets absolute position of the closest item for a coordinate.
24384	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
24385	 * @protected
24386	 * @param {Number} coordinate - The coordinate in pixel.
24387	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
24388	 * @return {Number} - The absolute position of the closest item.
24389	 */
24390	Owl.prototype.closest = function(coordinate, direction) {
24391		var position = -1,
24392			pull = 30,
24393			width = this.width(),
24394			coordinates = this.coordinates();
24395
24396		if (!this.settings.freeDrag) {
24397			// check closest item
24398			$.each(coordinates, $.proxy(function(index, value) {
24399				if (coordinate > value - pull && coordinate < value + pull) {
24400					position = index;
24401				} else if (this.op(coordinate, '<', value)
24402					&& this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
24403					position = direction === 'left' ? index + 1 : index;
24404				}
24405				return position === -1;
24406			}, this));
24407		}
24408
24409		if (!this.settings.loop) {
24410			// non loop boundries
24411			if (this.op(coordinate, '>', coordinates[this.minimum()])) {
24412				position = coordinate = this.minimum();
24413			} else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
24414				position = coordinate = this.maximum();
24415			}
24416		}
24417
24418		return position;
24419	};
24420
24421	/**
24422	 * Animates the stage.
24423	 * @todo #270
24424	 * @public
24425	 * @param {Number} coordinate - The coordinate in pixels.
24426	 */
24427	Owl.prototype.animate = function(coordinate) {
24428		var animate = this.speed() > 0;
24429
24430		this.is('animating') && this.onTransitionEnd();
24431
24432		if (animate) {
24433			this.enter('animating');
24434			this.trigger('translate');
24435		}
24436
24437		if ($.support.transform3d && $.support.transition) {
24438			this.$stage.css({
24439				transform: 'translate3d(' + coordinate + 'px,0px,0px)',
24440				transition: (this.speed() / 1000) + 's'
24441			});
24442		} else if (animate) {
24443			this.$stage.animate({
24444				left: coordinate + 'px'
24445			}, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
24446		} else {
24447			this.$stage.css({
24448				left: coordinate + 'px'
24449			});
24450		}
24451	};
24452
24453	/**
24454	 * Checks whether the carousel is in a specific state or not.
24455	 * @param {String} state - The state to check.
24456	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
24457	 */
24458	Owl.prototype.is = function(state) {
24459		return this._states.current[state] && this._states.current[state] > 0;
24460	};
24461
24462	/**
24463	 * Sets the absolute position of the current item.
24464	 * @public
24465	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
24466	 * @returns {Number} - The absolute position of the current item.
24467	 */
24468	Owl.prototype.current = function(position) {
24469		if (position === undefined) {
24470			return this._current;
24471		}
24472
24473		if (this._items.length === 0) {
24474			return undefined;
24475		}
24476
24477		position = this.normalize(position);
24478
24479		if (this._current !== position) {
24480			var event = this.trigger('change', { property: { name: 'position', value: position } });
24481
24482			if (event.data !== undefined) {
24483				position = this.normalize(event.data);
24484			}
24485
24486			this._current = position;
24487
24488			this.invalidate('position');
24489
24490			this.trigger('changed', { property: { name: 'position', value: this._current } });
24491		}
24492
24493		return this._current;
24494	};
24495
24496	/**
24497	 * Invalidates the given part of the update routine.
24498	 * @param {String} [part] - The part to invalidate.
24499	 * @returns {Array.<String>} - The invalidated parts.
24500	 */
24501	Owl.prototype.invalidate = function(part) {
24502		if ($.type(part) === 'string') {
24503			this._invalidated[part] = true;
24504			this.is('valid') && this.leave('valid');
24505		}
24506		return $.map(this._invalidated, function(v, i) { return i });
24507	};
24508
24509	/**
24510	 * Resets the absolute position of the current item.
24511	 * @public
24512	 * @param {Number} position - The absolute position of the new item.
24513	 */
24514	Owl.prototype.reset = function(position) {
24515		position = this.normalize(position);
24516
24517		if (position === undefined) {
24518			return;
24519		}
24520
24521		this._speed = 0;
24522		this._current = position;
24523
24524		this.suppress([ 'translate', 'translated' ]);
24525
24526		this.animate(this.coordinates(position));
24527
24528		this.release([ 'translate', 'translated' ]);
24529	};
24530
24531	/**
24532	 * Normalizes an absolute or a relative position of an item.
24533	 * @public
24534	 * @param {Number} position - The absolute or relative position to normalize.
24535	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
24536	 * @returns {Number} - The normalized position.
24537	 */
24538	Owl.prototype.normalize = function(position, relative) {
24539		var n = this._items.length,
24540			m = relative ? 0 : this._clones.length;
24541
24542		if (!$.isNumeric(position) || n < 1) {
24543			position = undefined;
24544		} else if (position < 0 || position >= n + m) {
24545			position = ((position - m / 2) % n + n) % n + m / 2;
24546		}
24547
24548		return position;
24549	};
24550
24551	/**
24552	 * Converts an absolute position of an item into a relative one.
24553	 * @public
24554	 * @param {Number} position - The absolute position to convert.
24555	 * @returns {Number} - The converted position.
24556	 */
24557	Owl.prototype.relative = function(position) {
24558		position -= this._clones.length / 2;
24559		return this.normalize(position, true);
24560	};
24561
24562	/**
24563	 * Gets the maximum position for the current item.
24564	 * @public
24565	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
24566	 * @returns {Number}
24567	 */
24568	Owl.prototype.maximum = function(relative) {
24569		var settings = this.settings,
24570			maximum = this._coordinates.length,
24571			boundary = Math.abs(this._coordinates[maximum - 1]) - this._width,
24572			i = -1, j;
24573
24574		if (settings.loop) {
24575			maximum = this._clones.length / 2 + this._items.length - 1;
24576		} else if (settings.autoWidth || settings.merge) {
24577			// binary search
24578			while (maximum - i > 1) {
24579				Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary
24580					? i = j : maximum = j;
24581			}
24582		} else if (settings.center) {
24583			maximum = this._items.length - 1;
24584		} else {
24585			maximum = this._items.length - settings.items;
24586		}
24587
24588		if (relative) {
24589			maximum -= this._clones.length / 2;
24590		}
24591
24592		return Math.max(maximum, 0);
24593	};
24594
24595	/**
24596	 * Gets the minimum position for the current item.
24597	 * @public
24598	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
24599	 * @returns {Number}
24600	 */
24601	Owl.prototype.minimum = function(relative) {
24602		return relative ? 0 : this._clones.length / 2;
24603	};
24604
24605	/**
24606	 * Gets an item at the specified relative position.
24607	 * @public
24608	 * @param {Number} [position] - The relative position of the item.
24609	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
24610	 */
24611	Owl.prototype.items = function(position) {
24612		if (position === undefined) {
24613			return this._items.slice();
24614		}
24615
24616		position = this.normalize(position, true);
24617		return this._items[position];
24618	};
24619
24620	/**
24621	 * Gets an item at the specified relative position.
24622	 * @public
24623	 * @param {Number} [position] - The relative position of the item.
24624	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
24625	 */
24626	Owl.prototype.mergers = function(position) {
24627		if (position === undefined) {
24628			return this._mergers.slice();
24629		}
24630
24631		position = this.normalize(position, true);
24632		return this._mergers[position];
24633	};
24634
24635	/**
24636	 * Gets the absolute positions of clones for an item.
24637	 * @public
24638	 * @param {Number} [position] - The relative position of the item.
24639	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
24640	 */
24641	Owl.prototype.clones = function(position) {
24642		var odd = this._clones.length / 2,
24643			even = odd + this._items.length,
24644			map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
24645
24646		if (position === undefined) {
24647			return $.map(this._clones, function(v, i) { return map(i) });
24648		}
24649
24650		return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
24651	};
24652
24653	/**
24654	 * Sets the current animation speed.
24655	 * @public
24656	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
24657	 * @returns {Number} - The current animation speed in milliseconds.
24658	 */
24659	Owl.prototype.speed = function(speed) {
24660		if (speed !== undefined) {
24661			this._speed = speed;
24662		}
24663
24664		return this._speed;
24665	};
24666
24667	/**
24668	 * Gets the coordinate of an item.
24669	 * @todo The name of this method is missleanding.
24670	 * @public
24671	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
24672	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
24673	 */
24674	Owl.prototype.coordinates = function(position) {
24675		var coordinate = null;
24676
24677		if (position === undefined) {
24678			return $.map(this._coordinates, $.proxy(function(coordinate, index) {
24679				return this.coordinates(index);
24680			}, this));
24681		}
24682
24683		if (this.settings.center) {
24684			coordinate = this._coordinates[position];
24685			coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1);
24686		} else {
24687			coordinate = this._coordinates[position - 1] || 0;
24688		}
24689
24690		return coordinate;
24691	};
24692
24693	/**
24694	 * Calculates the speed for a translation.
24695	 * @protected
24696	 * @param {Number} from - The absolute position of the start item.
24697	 * @param {Number} to - The absolute position of the target item.
24698	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
24699	 * @returns {Number} - The time in milliseconds for the translation.
24700	 */
24701	Owl.prototype.duration = function(from, to, factor) {
24702		return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
24703	};
24704
24705	/**
24706	 * Slides to the specified item.
24707	 * @public
24708	 * @param {Number} position - The position of the item.
24709	 * @param {Number} [speed] - The time in milliseconds for the transition.
24710	 */
24711	Owl.prototype.to = function(position, speed) {
24712		var current = this.current(),
24713			revert = null,
24714			distance = position - this.relative(current),
24715			direction = (distance > 0) - (distance < 0),
24716			items = this._items.length,
24717			minimum = this.minimum(),
24718			maximum = this.maximum();
24719
24720		if (this.settings.loop) {
24721			if (!this.settings.rewind && Math.abs(distance) > items / 2) {
24722				distance += direction * -1 * items;
24723			}
24724
24725			position = current + distance;
24726			revert = ((position - minimum) % items + items) % items + minimum;
24727
24728			if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
24729				current = revert - distance;
24730				position = revert;
24731				this.reset(current);
24732			}
24733		} else if (this.settings.rewind) {
24734			maximum += 1;
24735			position = (position % maximum + maximum) % maximum;
24736		} else {
24737			position = Math.max(minimum, Math.min(maximum, position));
24738		}
24739
24740		this.speed(this.duration(current, position, speed));
24741		this.current(position);
24742
24743		if (this.$element.is(':visible')) {
24744			this.update();
24745		}
24746	};
24747
24748	/**
24749	 * Slides to the next item.
24750	 * @public
24751	 * @param {Number} [speed] - The time in milliseconds for the transition.
24752	 */
24753	Owl.prototype.next = function(speed) {
24754		speed = speed || false;
24755		this.to(this.relative(this.current()) + 1, speed);
24756	};
24757
24758	/**
24759	 * Slides to the previous item.
24760	 * @public
24761	 * @param {Number} [speed] - The time in milliseconds for the transition.
24762	 */
24763	Owl.prototype.prev = function(speed) {
24764		speed = speed || false;
24765		this.to(this.relative(this.current()) - 1, speed);
24766	};
24767
24768	/**
24769	 * Handles the end of an animation.
24770	 * @protected
24771	 * @param {Event} event - The event arguments.
24772	 */
24773	Owl.prototype.onTransitionEnd = function(event) {
24774
24775		// if css2 animation then event object is undefined
24776		if (event !== undefined) {
24777			event.stopPropagation();
24778
24779			// Catch only owl-stage transitionEnd event
24780			if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
24781				return false;
24782			}
24783		}
24784
24785		this.leave('animating');
24786		this.trigger('translated');
24787	};
24788
24789	/**
24790	 * Gets viewport width.
24791	 * @protected
24792	 * @return {Number} - The width in pixel.
24793	 */
24794	Owl.prototype.viewport = function() {
24795		var width;
24796		if (this.options.responsiveBaseElement !== window) {
24797			width = $(this.options.responsiveBaseElement).width();
24798		} else if (window.innerWidth) {
24799			width = window.innerWidth;
24800		} else if (document.documentElement && document.documentElement.clientWidth) {
24801			width = document.documentElement.clientWidth;
24802		} else {
24803			throw 'Can not detect viewport width.';
24804		}
24805
24806		return width;
24807	};
24808
24809	/**
24810	 * Replaces the current content.
24811	 * @public
24812	 * @param {HTMLElement|jQuery|String} content - The new content.
24813	 */
24814	Owl.prototype.replace = function(content) {
24815		this.$stage.empty();
24816		this._items = [];
24817
24818		if (content) {
24819			content = (content instanceof jQuery) ? content : $(content);
24820		}
24821
24822		if (this.settings.nestedItemSelector) {
24823			content = content.find('.' + this.settings.nestedItemSelector);
24824		}
24825
24826		content.filter(function() {
24827			return this.nodeType === 1;
24828		}).each($.proxy(function(index, item) {
24829			item = this.prepare(item, index);
24830			this.$stage.append(item);
24831			this._items.push(item);
24832			this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
24833		}, this));
24834
24835		this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
24836
24837		this.invalidate('items');
24838	};
24839
24840	/**
24841	 * Adds an item.
24842	 * @todo Use `item` instead of `content` for the event arguments.
24843	 * @public
24844	 * @param {HTMLElement|jQuery|String} content - The item content to add.
24845	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
24846	 */
24847	Owl.prototype.add = function(content, position) {
24848		var current = this.relative(this._current);
24849
24850		position = position === undefined ? this._items.length : this.normalize(position, true);
24851		content = content instanceof jQuery ? content : $(content);
24852
24853		this.trigger('add', { content: content, position: position });
24854
24855		content = this.prepare(content, this._items[current].index());
24856
24857		if (this._items.length === 0 || position === this._items.length) {
24858			this._items.length === 0 && this.$stage.append(content);
24859			this._items.length !== 0 && this._items[position - 1].after(content);
24860			this._items.push(content);
24861			this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
24862		} else {
24863			this._items[position].before(content);
24864			this._items.splice(position, 0, content);
24865			this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
24866		}
24867
24868		this._items[current] && this.reset(this._items[current].index());
24869
24870		this.invalidate('items');
24871
24872		this.trigger('added', { content: content, position: position });
24873	};
24874
24875	/**
24876	 * Removes an item by its position.
24877	 * @todo Use `item` instead of `content` for the event arguments.
24878	 * @public
24879	 * @param {Number} position - The relative position of the item to remove.
24880	 */
24881	Owl.prototype.remove = function(position) {
24882		position = this.normalize(position, true);
24883
24884		if (position === undefined) {
24885			return;
24886		}
24887
24888		this.trigger('remove', { content: this._items[position], position: position });
24889
24890		this._items[position].remove();
24891		this._items.splice(position, 1);
24892		this._mergers.splice(position, 1);
24893
24894		this.invalidate('items');
24895
24896		this.trigger('removed', { content: null, position: position });
24897	};
24898
24899	/**
24900	 * Preloads images with auto width.
24901	 * @todo Replace by a more generic approach
24902	 * @protected
24903	 */
24904	Owl.prototype.preloadAutoWidthImages = function(images) {
24905		images.each($.proxy(function(i, element) {
24906			this.enter('pre-loading');
24907			element = $(element);
24908			$(new Image()).one('load', $.proxy(function(e) {
24909				element.attr('src', e.target.src);
24910				element.css('opacity', 1);
24911				this.leave('pre-loading');
24912				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
24913			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
24914		}, this));
24915	};
24916
24917	/**
24918	 * Destroys the carousel.
24919	 * @public
24920	 */
24921	Owl.prototype.destroy = function() {
24922
24923		this.$element.off('.owl.core');
24924		this.$stage.off('.owl.core');
24925		$(document).off('.owl.core');
24926
24927		if (this.settings.responsive !== false) {
24928			window.clearTimeout(this.resizeTimer);
24929			this.off(window, 'resize', this._handlers.onThrottledResize);
24930		}
24931
24932		for (var i in this._plugins) {
24933			this._plugins[i].destroy();
24934		}
24935
24936		this.$stage.children('.cloned').remove();
24937
24938		this.$stage.unwrap();
24939		this.$stage.children().contents().unwrap();
24940		this.$stage.children().unwrap();
24941
24942		this.$element
24943			.removeClass(this.options.refreshClass)
24944			.removeClass(this.options.loadingClass)
24945			.removeClass(this.options.loadedClass)
24946			.removeClass(this.options.rtlClass)
24947			.removeClass(this.options.dragClass)
24948			.removeClass(this.options.grabClass)
24949			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
24950			.removeData('owl.carousel');
24951	};
24952
24953	/**
24954	 * Operators to calculate right-to-left and left-to-right.
24955	 * @protected
24956	 * @param {Number} [a] - The left side operand.
24957	 * @param {String} [o] - The operator.
24958	 * @param {Number} [b] - The right side operand.
24959	 */
24960	Owl.prototype.op = function(a, o, b) {
24961		var rtl = this.settings.rtl;
24962		switch (o) {
24963			case '<':
24964				return rtl ? a > b : a < b;
24965			case '>':
24966				return rtl ? a < b : a > b;
24967			case '>=':
24968				return rtl ? a <= b : a >= b;
24969			case '<=':
24970				return rtl ? a >= b : a <= b;
24971			default:
24972				break;
24973		}
24974	};
24975
24976	/**
24977	 * Attaches to an internal event.
24978	 * @protected
24979	 * @param {HTMLElement} element - The event source.
24980	 * @param {String} event - The event name.
24981	 * @param {Function} listener - The event handler to attach.
24982	 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
24983	 */
24984	Owl.prototype.on = function(element, event, listener, capture) {
24985		if (element.addEventListener) {
24986			element.addEventListener(event, listener, capture);
24987		} else if (element.attachEvent) {
24988			element.attachEvent('on' + event, listener);
24989		}
24990	};
24991
24992	/**
24993	 * Detaches from an internal event.
24994	 * @protected
24995	 * @param {HTMLElement} element - The event source.
24996	 * @param {String} event - The event name.
24997	 * @param {Function} listener - The attached event handler to detach.
24998	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
24999	 */
25000	Owl.prototype.off = function(element, event, listener, capture) {
25001		if (element.removeEventListener) {
25002			element.removeEventListener(event, listener, capture);
25003		} else if (element.detachEvent) {
25004			element.detachEvent('on' + event, listener);
25005		}
25006	};
25007
25008	/**
25009	 * Triggers a public event.
25010	 * @todo Remove `status`, `relatedTarget` should be used instead.
25011	 * @protected
25012	 * @param {String} name - The event name.
25013	 * @param {*} [data=null] - The event data.
25014	 * @param {String} [namespace=carousel] - The event namespace.
25015	 * @param {String} [state] - The state which is associated with the event.
25016	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
25017	 * @returns {Event} - The event arguments.
25018	 */
25019	Owl.prototype.trigger = function(name, data, namespace, state, enter) {
25020		var status = {
25021			item: { count: this._items.length, index: this.current() }
25022		}, handler = $.camelCase(
25023			$.grep([ 'on', name, namespace ], function(v) { return v })
25024				.join('-').toLowerCase()
25025		), event = $.Event(
25026			[ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
25027			$.extend({ relatedTarget: this }, status, data)
25028		);
25029
25030		if (!this._supress[name]) {
25031			$.each(this._plugins, function(name, plugin) {
25032				if (plugin.onTrigger) {
25033					plugin.onTrigger(event);
25034				}
25035			});
25036
25037			this.register({ type: Owl.Type.Event, name: name });
25038			this.$element.trigger(event);
25039
25040			if (this.settings && typeof this.settings[handler] === 'function') {
25041				this.settings[handler].call(this, event);
25042			}
25043		}
25044
25045		return event;
25046	};
25047
25048	/**
25049	 * Enters a state.
25050	 * @param name - The state name.
25051	 */
25052	Owl.prototype.enter = function(name) {
25053		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
25054			if (this._states.current[name] === undefined) {
25055				this._states.current[name] = 0;
25056			}
25057
25058			this._states.current[name]++;
25059		}, this));
25060	};
25061
25062	/**
25063	 * Leaves a state.
25064	 * @param name - The state name.
25065	 */
25066	Owl.prototype.leave = function(name) {
25067		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
25068			this._states.current[name]--;
25069		}, this));
25070	};
25071
25072	/**
25073	 * Registers an event or state.
25074	 * @public
25075	 * @param {Object} object - The event or state to register.
25076	 */
25077	Owl.prototype.register = function(object) {
25078		if (object.type === Owl.Type.Event) {
25079			if (!$.event.special[object.name]) {
25080				$.event.special[object.name] = {};
25081			}
25082
25083			if (!$.event.special[object.name].owl) {
25084				var _default = $.event.special[object.name]._default;
25085				$.event.special[object.name]._default = function(e) {
25086					if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
25087						return _default.apply(this, arguments);
25088					}
25089					return e.namespace && e.namespace.indexOf('owl') > -1;
25090				};
25091				$.event.special[object.name].owl = true;
25092			}
25093		} else if (object.type === Owl.Type.State) {
25094			if (!this._states.tags[object.name]) {
25095				this._states.tags[object.name] = object.tags;
25096			} else {
25097				this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
25098			}
25099
25100			this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
25101				return $.inArray(tag, this._states.tags[object.name]) === i;
25102			}, this));
25103		}
25104	};
25105
25106	/**
25107	 * Suppresses events.
25108	 * @protected
25109	 * @param {Array.<String>} events - The events to suppress.
25110	 */
25111	Owl.prototype.suppress = function(events) {
25112		$.each(events, $.proxy(function(index, event) {
25113			this._supress[event] = true;
25114		}, this));
25115	};
25116
25117	/**
25118	 * Releases suppressed events.
25119	 * @protected
25120	 * @param {Array.<String>} events - The events to release.
25121	 */
25122	Owl.prototype.release = function(events) {
25123		$.each(events, $.proxy(function(index, event) {
25124			delete this._supress[event];
25125		}, this));
25126	};
25127
25128	/**
25129	 * Gets unified pointer coordinates from event.
25130	 * @todo #261
25131	 * @protected
25132	 * @param {Event} - The `mousedown` or `touchstart` event.
25133	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
25134	 */
25135	Owl.prototype.pointer = function(event) {
25136		var result = { x: null, y: null };
25137
25138		event = event.originalEvent || event || window.event;
25139
25140		event = event.touches && event.touches.length ?
25141			event.touches[0] : event.changedTouches && event.changedTouches.length ?
25142				event.changedTouches[0] : event;
25143
25144		if (event.pageX) {
25145			result.x = event.pageX;
25146			result.y = event.pageY;
25147		} else {
25148			result.x = event.clientX;
25149			result.y = event.clientY;
25150		}
25151
25152		return result;
25153	};
25154
25155	/**
25156	 * Gets the difference of two vectors.
25157	 * @todo #261
25158	 * @protected
25159	 * @param {Object} - The first vector.
25160	 * @param {Object} - The second vector.
25161	 * @returns {Object} - The difference.
25162	 */
25163	Owl.prototype.difference = function(first, second) {
25164		return {
25165			x: first.x - second.x,
25166			y: first.y - second.y
25167		};
25168	};
25169
25170	/**
25171	 * The jQuery Plugin for the Owl Carousel
25172	 * @todo Navigation plugin `next` and `prev`
25173	 * @public
25174	 */
25175	$.fn.owlCarousel = function(option) {
25176		var args = Array.prototype.slice.call(arguments, 1);
25177
25178		return this.each(function() {
25179			var $this = $(this),
25180				data = $this.data('owl.carousel');
25181
25182			if (!data) {
25183				data = new Owl(this, typeof option == 'object' && option);
25184				$this.data('owl.carousel', data);
25185
25186				$.each([
25187					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
25188				], function(i, event) {
25189					data.register({ type: Owl.Type.Event, name: event });
25190					data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
25191						if (e.namespace && e.relatedTarget !== this) {
25192							this.suppress([ event ]);
25193							data[event].apply(this, [].slice.call(arguments, 1));
25194							this.release([ event ]);
25195						}
25196					}, data));
25197				});
25198			}
25199
25200			if (typeof option == 'string' && option.charAt(0) !== '_') {
25201				data[option].apply(data, args);
25202			}
25203		});
25204	};
25205
25206	/**
25207	 * The constructor for the jQuery Plugin
25208	 * @public
25209	 */
25210	$.fn.owlCarousel.Constructor = Owl;
25211
25212})(window.Zepto || window.jQuery, window, document);
25213
25214/**
25215 * AutoRefresh Plugin
25216 * @version 2.0.0-beta.3
25217 * @author Artus Kolanowski
25218 * @license The MIT License (MIT)
25219 */
25220;(function($, window, document, undefined) {
25221
25222	/**
25223	 * Creates the auto refresh plugin.
25224	 * @class The Auto Refresh Plugin
25225	 * @param {Owl} carousel - The Owl Carousel
25226	 */
25227	var AutoRefresh = function(carousel) {
25228		/**
25229		 * Reference to the core.
25230		 * @protected
25231		 * @type {Owl}
25232		 */
25233		this._core = carousel;
25234
25235		/**
25236		 * Refresh interval.
25237		 * @protected
25238		 * @type {number}
25239		 */
25240		this._interval = null;
25241
25242		/**
25243		 * Whether the element is currently visible or not.
25244		 * @protected
25245		 * @type {Boolean}
25246		 */
25247		this._visible = null;
25248
25249		/**
25250		 * All event handlers.
25251		 * @protected
25252		 * @type {Object}
25253		 */
25254		this._handlers = {
25255			'initialized.owl.carousel': $.proxy(function(e) {
25256				if (e.namespace && this._core.settings.autoRefresh) {
25257					this.watch();
25258				}
25259			}, this)
25260		};
25261
25262		// set default options
25263		this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
25264
25265		// register event handlers
25266		this._core.$element.on(this._handlers);
25267	};
25268
25269	/**
25270	 * Default options.
25271	 * @public
25272	 */
25273	AutoRefresh.Defaults = {
25274		autoRefresh: true,
25275		autoRefreshInterval: 500
25276	};
25277
25278	/**
25279	 * Watches the element.
25280	 */
25281	AutoRefresh.prototype.watch = function() {
25282		if (this._interval) {
25283			return;
25284		}
25285
25286		this._visible = this._core.$element.is(':visible');
25287		this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
25288	};
25289
25290	/**
25291	 * Refreshes the element.
25292	 */
25293	AutoRefresh.prototype.refresh = function() {
25294		if (this._core.$element.is(':visible') === this._visible || this._core.$element.closest('.drop-menu').length) {
25295			return;
25296		}
25297
25298		this._visible = !this._visible;
25299
25300		this._core.$element.toggleClass('owl-hidden', !this._visible);
25301
25302		this._visible && (this._core.invalidate('width') && this._core.refresh());
25303	};
25304
25305	/**
25306	 * Destroys the plugin.
25307	 */
25308	AutoRefresh.prototype.destroy = function() {
25309		var handler, property;
25310
25311		window.clearInterval(this._interval);
25312
25313		for (handler in this._handlers) {
25314			this._core.$element.off(handler, this._handlers[handler]);
25315		}
25316		for (property in Object.getOwnPropertyNames(this)) {
25317			typeof this[property] != 'function' && (this[property] = null);
25318		}
25319	};
25320
25321	$.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
25322
25323})(window.Zepto || window.jQuery, window, document);
25324
25325/**
25326 * Lazy Plugin
25327 * @version 2.0.0-beta.3
25328 * @author Bartosz Wojciechowski
25329 * @license The MIT License (MIT)
25330 */
25331;(function($, window, document, undefined) {
25332
25333	/**
25334	 * Creates the lazy plugin.
25335	 * @class The Lazy Plugin
25336	 * @param {Owl} carousel - The Owl Carousel
25337	 */
25338	var Lazy = function(carousel) {
25339
25340		/**
25341		 * Reference to the core.
25342		 * @protected
25343		 * @type {Owl}
25344		 */
25345		this._core = carousel;
25346
25347		/**
25348		 * Already loaded items.
25349		 * @protected
25350		 * @type {Array.<jQuery>}
25351		 */
25352		this._loaded = [];
25353
25354		/**
25355		 * Event handlers.
25356		 * @protected
25357		 * @type {Object}
25358		 */
25359		this._handlers = {
25360			'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) {
25361				if (!e.namespace) {
25362					return;
25363				}
25364
25365				if (!this._core.settings || !this._core.settings.lazyLoad) {
25366					return;
25367				}
25368
25369				if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
25370					var settings = this._core.settings,
25371						n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
25372						i = ((settings.center && n * -1) || 0),
25373						position = ((e.property && e.property.value) || this._core.current()) + i,
25374						clones = this._core.clones().length,
25375						load = $.proxy(function(i, v) { this.load(v) }, this);
25376
25377					while (i++ < n) {
25378						this.load(clones / 2 + this._core.relative(position));
25379						clones && $.each(this._core.clones(this._core.relative(position)), load);
25380						position++;
25381					}
25382				}
25383			}, this)
25384		};
25385
25386		// set the default options
25387		this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
25388
25389		// register event handler
25390		this._core.$element.on(this._handlers);
25391	}
25392
25393	/**
25394	 * Default options.
25395	 * @public
25396	 */
25397	Lazy.Defaults = {
25398		lazyLoad: false
25399	}
25400
25401	/**
25402	 * Loads all resources of an item at the specified position.
25403	 * @param {Number} position - The absolute position of the item.
25404	 * @protected
25405	 */
25406	Lazy.prototype.load = function(position) {
25407		var $item = this._core.$stage.children().eq(position),
25408			$elements = $item && $item.find('.owl-lazy');
25409
25410		if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
25411			return;
25412		}
25413
25414		$elements.each($.proxy(function(index, element) {
25415			var $element = $(element), image,
25416				url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');
25417
25418			this._core.trigger('load', { element: $element, url: url }, 'lazy');
25419
25420			if ($element.is('img')) {
25421				$element.one('load.owl.lazy', $.proxy(function() {
25422					$element.css('opacity', 1);
25423					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
25424				}, this)).attr('src', url);
25425			} else {
25426				image = new Image();
25427				image.onload = $.proxy(function() {
25428					$element.css({
25429						'background-image': 'url(' + url + ')',
25430						'opacity': '1'
25431					});
25432					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
25433				}, this);
25434				image.src = url;
25435			}
25436		}, this));
25437
25438		this._loaded.push($item.get(0));
25439	}
25440
25441	/**
25442	 * Destroys the plugin.
25443	 * @public
25444	 */
25445	Lazy.prototype.destroy = function() {
25446		var handler, property;
25447
25448		for (handler in this.handlers) {
25449			this._core.$element.off(handler, this.handlers[handler]);
25450		}
25451		for (property in Object.getOwnPropertyNames(this)) {
25452			typeof this[property] != 'function' && (this[property] = null);
25453		}
25454	};
25455
25456	$.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
25457
25458})(window.Zepto || window.jQuery, window, document);
25459
25460/**
25461 * AutoHeight Plugin
25462 * @version 2.0.0-beta.3
25463 * @author Bartosz Wojciechowski
25464 * @license The MIT License (MIT)
25465 */
25466;(function($, window, document, undefined) {
25467
25468	/**
25469	 * Creates the auto height plugin.
25470	 * @class The Auto Height Plugin
25471	 * @param {Owl} carousel - The Owl Carousel
25472	 */
25473	var AutoHeight = function(carousel) {
25474		/**
25475		 * Reference to the core.
25476		 * @protected
25477		 * @type {Owl}
25478		 */
25479		this._core = carousel;
25480
25481		/**
25482		 * All event handlers.
25483		 * @protected
25484		 * @type {Object}
25485		 */
25486		this._handlers = {
25487			'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {
25488				if (e.namespace && this._core.settings.autoHeight) {
25489					this.update();
25490				}
25491			}, this),
25492			'changed.owl.carousel': $.proxy(function(e) {
25493				if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){
25494					this.update();
25495				}
25496			}, this),
25497			'loaded.owl.lazy': $.proxy(function(e) {
25498				if (e.namespace && this._core.settings.autoHeight
25499					&& e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
25500					this.update();
25501				}
25502			}, this)
25503		};
25504
25505		// set default options
25506		this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
25507
25508		// register event handlers
25509		this._core.$element.on(this._handlers);
25510	};
25511
25512	/**
25513	 * Default options.
25514	 * @public
25515	 */
25516	AutoHeight.Defaults = {
25517		autoHeight: false,
25518		autoHeightClass: 'owl-height'
25519	};
25520
25521	/**
25522	 * Updates the view.
25523	 */
25524	AutoHeight.prototype.update = function() {
25525		var start = this._core._current,
25526			end = start + this._core.settings.items,
25527			visible = this._core.$stage.children().toArray().slice(start, end);
25528			heights = [],
25529			maxheight = 0;
25530
25531		$.each(visible, function(index, item) {
25532			heights.push($(item).height());
25533		});
25534
25535		maxheight = Math.max.apply(null, heights);
25536
25537		this._core.$stage.parent()
25538			.height(maxheight)
25539			.addClass(this._core.settings.autoHeightClass);
25540	};
25541
25542	AutoHeight.prototype.destroy = function() {
25543		var handler, property;
25544
25545		for (handler in this._handlers) {
25546			this._core.$element.off(handler, this._handlers[handler]);
25547		}
25548		for (property in Object.getOwnPropertyNames(this)) {
25549			typeof this[property] != 'function' && (this[property] = null);
25550		}
25551	};
25552
25553	$.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
25554
25555})(window.Zepto || window.jQuery, window, document);
25556
25557/**
25558 * Video Plugin
25559 * @version 2.0.0-beta.3
25560 * @author Bartosz Wojciechowski
25561 * @license The MIT License (MIT)
25562 */
25563;(function($, window, document, undefined) {
25564
25565	/**
25566	 * Creates the video plugin.
25567	 * @class The Video Plugin
25568	 * @param {Owl} carousel - The Owl Carousel
25569	 */
25570	var Video = function(carousel) {
25571		/**
25572		 * Reference to the core.
25573		 * @protected
25574		 * @type {Owl}
25575		 */
25576		this._core = carousel;
25577
25578		/**
25579		 * Cache all video URLs.
25580		 * @protected
25581		 * @type {Object}
25582		 */
25583		this._videos = {};
25584
25585		/**
25586		 * Current playing item.
25587		 * @protected
25588		 * @type {jQuery}
25589		 */
25590		this._playing = null;
25591
25592		/**
25593		 * All event handlers.
25594		 * @todo The cloned content removale is too late
25595		 * @protected
25596		 * @type {Object}
25597		 */
25598		this._handlers = {
25599			'initialized.owl.carousel': $.proxy(function(e) {
25600				if (e.namespace) {
25601					this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });
25602				}
25603			}, this),
25604			'resize.owl.carousel': $.proxy(function(e) {
25605				if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
25606					e.preventDefault();
25607				}
25608			}, this),
25609			'refreshed.owl.carousel': $.proxy(function(e) {
25610				if (e.namespace && this._core.is('resizing')) {
25611					this._core.$stage.find('.cloned .owl-video-frame').remove();
25612				}
25613			}, this),
25614			'changed.owl.carousel': $.proxy(function(e) {
25615				if (e.namespace && e.property.name === 'position' && this._playing) {
25616					this.stop();
25617				}
25618			}, this),
25619			'prepared.owl.carousel': $.proxy(function(e) {
25620				if (!e.namespace) {
25621					return;
25622				}
25623
25624				var $element = $(e.content).find('.owl-video');
25625
25626				if ($element.length) {
25627					$element.css('display', 'none');
25628					this.fetch($element, $(e.content));
25629				}
25630			}, this)
25631		};
25632
25633		// set default options
25634		this._core.options = $.extend({}, Video.Defaults, this._core.options);
25635
25636		// register event handlers
25637		this._core.$element.on(this._handlers);
25638
25639		this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
25640			this.play(e);
25641		}, this));
25642	};
25643
25644	/**
25645	 * Default options.
25646	 * @public
25647	 */
25648	Video.Defaults = {
25649		video: false,
25650		videoHeight: false,
25651		videoWidth: false
25652	};
25653
25654	/**
25655	 * Gets the video ID and the type (YouTube/Vimeo only).
25656	 * @protected
25657	 * @param {jQuery} target - The target containing the video data.
25658	 * @param {jQuery} item - The item containing the video.
25659	 */
25660	Video.prototype.fetch = function(target, item) {
25661		var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube',
25662			id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'),
25663			width = target.attr('data-width') || this._core.settings.videoWidth,
25664			height = target.attr('data-height') || this._core.settings.videoHeight,
25665			url = target.attr('href');
25666
25667		if (url) {
25668			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+)?/);
25669
25670			if (id[3].indexOf('youtu') > -1) {
25671				type = 'youtube';
25672			} else if (id[3].indexOf('vimeo') > -1) {
25673				type = 'vimeo';
25674			} else {
25675				throw new Error('Video URL not supported.');
25676			}
25677			id = id[6];
25678		} else {
25679			throw new Error('Missing video URL.');
25680		}
25681
25682		this._videos[url] = {
25683			type: type,
25684			id: id,
25685			width: width,
25686			height: height
25687		};
25688
25689		item.attr('data-video', url);
25690
25691		this.thumbnail(target, this._videos[url]);
25692	};
25693
25694	/**
25695	 * Creates video thumbnail.
25696	 * @protected
25697	 * @param {jQuery} target - The target containing the video data.
25698	 * @param {Object} info - The video info object.
25699	 * @see `fetch`
25700	 */
25701	Video.prototype.thumbnail = function(target, video) {
25702		var tnLink,
25703			icon,
25704			path,
25705			dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
25706			customTn = target.find('img'),
25707			srcType = 'src',
25708			lazyClass = '',
25709			settings = this._core.settings,
25710			create = function(path) {
25711				icon = '<div class="owl-video-play-icon"></div>';
25712
25713				if (settings.lazyLoad) {
25714					tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';
25715				} else {
25716					tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';
25717				}
25718				target.after(tnLink);
25719				target.after(icon);
25720			};
25721
25722		// wrap video content into owl-video-wrapper div
25723		target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');
25724
25725		if (this._core.settings.lazyLoad) {
25726			srcType = 'data-src';
25727			lazyClass = 'owl-lazy';
25728		}
25729
25730		// custom thumbnail
25731		if (customTn.length) {
25732			create(customTn.attr(srcType));
25733			customTn.remove();
25734			return false;
25735		}
25736
25737		if (video.type === 'youtube') {
25738			path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
25739			create(path);
25740		} else if (video.type === 'vimeo') {
25741			$.ajax({
25742				type: 'GET',
25743				url: '//vimeo.com/api/v2/video/' + video.id + '.json',
25744				jsonp: 'callback',
25745				dataType: 'jsonp',
25746				success: function(data) {
25747					path = data[0].thumbnail_large;
25748					create(path);
25749				}
25750			});
25751		}
25752	};
25753
25754	/**
25755	 * Stops the current video.
25756	 * @public
25757	 */
25758	Video.prototype.stop = function() {
25759		this._core.trigger('stop', null, 'video');
25760		this._playing.find('.owl-video-frame').remove();
25761		this._playing.removeClass('owl-video-playing');
25762		this._playing = null;
25763		this._core.leave('playing');
25764		this._core.trigger('stopped', null, 'video');
25765	};
25766
25767	/**
25768	 * Starts the current video.
25769	 * @public
25770	 * @param {Event} event - The event arguments.
25771	 */
25772	Video.prototype.play = function(event) {
25773		var target = $(event.target),
25774			item = target.closest('.' + this._core.settings.itemClass),
25775			video = this._videos[item.attr('data-video')],
25776			width = video.width || '100%',
25777			height = video.height || this._core.$stage.height(),
25778			html;
25779
25780		if (this._playing) {
25781			return;
25782		}
25783
25784		this._core.enter('playing');
25785		this._core.trigger('play', null, 'video');
25786
25787		item = this._core.items(this._core.relative(item.index()));
25788
25789		this._core.reset(item.index());
25790
25791		if (video.type === 'youtube') {
25792			html = '<iframe width="' + width + '" height="' + height + '" src="//www.youtube.com/embed/' +
25793				video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';
25794		} else if (video.type === 'vimeo') {
25795			html = '<iframe src="//player.vimeo.com/video/' + video.id +
25796				'?autoplay=1" width="' + width + '" height="' + height +
25797				'" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
25798		}
25799
25800		$('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video'));
25801
25802		this._playing = item.addClass('owl-video-playing');
25803	};
25804
25805	/**
25806	 * Checks whether an video is currently in full screen mode or not.
25807	 * @todo Bad style because looks like a readonly method but changes members.
25808	 * @protected
25809	 * @returns {Boolean}
25810	 */
25811	Video.prototype.isInFullScreen = function() {
25812		var element = document.fullscreenElement || document.mozFullScreenElement ||
25813				document.webkitFullscreenElement;
25814
25815		return element && $(element).parent().hasClass('owl-video-frame');
25816	};
25817
25818	/**
25819	 * Destroys the plugin.
25820	 */
25821	Video.prototype.destroy = function() {
25822		var handler, property;
25823
25824		this._core.$element.off('click.owl.video');
25825
25826		for (handler in this._handlers) {
25827			this._core.$element.off(handler, this._handlers[handler]);
25828		}
25829		for (property in Object.getOwnPropertyNames(this)) {
25830			typeof this[property] != 'function' && (this[property] = null);
25831		}
25832	};
25833
25834	$.fn.owlCarousel.Constructor.Plugins.Video = Video;
25835
25836})(window.Zepto || window.jQuery, window, document);
25837
25838/**
25839 * Animate Plugin
25840 * @version 2.0.0-beta.3
25841 * @author Bartosz Wojciechowski
25842 * @license The MIT License (MIT)
25843 */
25844;(function($, window, document, undefined) {
25845
25846	/**
25847	 * Creates the animate plugin.
25848	 * @class The Navigation Plugin
25849	 * @param {Owl} scope - The Owl Carousel
25850	 */
25851	var Animate = function(scope) {
25852		this.core = scope;
25853		this.core.options = $.extend({}, Animate.Defaults, this.core.options);
25854		this.swapping = true;
25855		this.previous = undefined;
25856		this.next = undefined;
25857
25858		this.handlers = {
25859			'change.owl.carousel': $.proxy(function(e) {
25860				if (e.namespace && e.property.name == 'position') {
25861					this.previous = this.core.current();
25862					this.next = e.property.value;
25863				}
25864			}, this),
25865			'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
25866				if (e.namespace) {
25867					this.swapping = e.type == 'translated';
25868				}
25869			}, this),
25870			'translate.owl.carousel': $.proxy(function(e) {
25871				if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
25872					this.swap();
25873				}
25874			}, this)
25875		};
25876
25877		this.core.$element.on(this.handlers);
25878	};
25879
25880	/**
25881	 * Default options.
25882	 * @public
25883	 */
25884	Animate.Defaults = {
25885		animateOut: false,
25886		animateIn: false
25887	};
25888
25889	/**
25890	 * Toggles the animation classes whenever an translations starts.
25891	 * @protected
25892	 * @returns {Boolean|undefined}
25893	 */
25894	Animate.prototype.swap = function() {
25895
25896		if (this.core.settings.items !== 1) {
25897			return;
25898		}
25899
25900		if (!$.support.animation || !$.support.transition) {
25901			return;
25902		}
25903
25904		this.core.speed(0);
25905
25906		var left,
25907			clear = $.proxy(this.clear, this),
25908			previous = this.core.$stage.children().eq(this.previous),
25909			next = this.core.$stage.children().eq(this.next),
25910			incoming = this.core.settings.animateIn,
25911			outgoing = this.core.settings.animateOut;
25912
25913		if (this.core.current() === this.previous) {
25914			return;
25915		}
25916
25917		if (outgoing) {
25918			left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
25919			previous.css( { 'left': left + 'px' } )
25920				.addClass('animated owl-animated-out')
25921				.addClass(outgoing)
25922				.on($.support.animation.end, clear);
25923		}
25924
25925		if (incoming) {
25926			next.addClass('animated owl-animated-in')
25927				.addClass(incoming)
25928				.on($.support.animation.end, clear);
25929		}
25930	};
25931
25932	Animate.prototype.clear = function(e) {
25933		if ($(e.target).hasClass('animated')) {
25934			$(e.target).css( { 'left': '' } )
25935				.removeClass('animated owl-animated-out owl-animated-in')
25936				.removeClass(this.core.settings.animateIn)
25937				.removeClass(this.core.settings.animateOut);
25938			this.core.onTransitionEnd();
25939		}
25940	};
25941
25942	/**
25943	 * Destroys the plugin.
25944	 * @public
25945	 */
25946	Animate.prototype.destroy = function() {
25947		var handler, property;
25948
25949		for (handler in this.handlers) {
25950			this.core.$element.off(handler, this.handlers[handler]);
25951		}
25952		for (property in Object.getOwnPropertyNames(this)) {
25953			typeof this[property] != 'function' && (this[property] = null);
25954		}
25955	};
25956
25957	$.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
25958
25959})(window.Zepto || window.jQuery, window, document);
25960
25961/**
25962 * Autoplay Plugin
25963 * @version 2.0.0-beta.3
25964 * @author Bartosz Wojciechowski
25965 * @author Artus Kolanowski
25966 * @license The MIT License (MIT)
25967 */
25968;(function($, window, document, undefined) {
25969
25970	/**
25971	 * Creates the autoplay plugin.
25972	 * @class The Autoplay Plugin
25973	 * @param {Owl} scope - The Owl Carousel
25974	 */
25975	var Autoplay = function(carousel) {
25976		/**
25977		 * Reference to the core.
25978		 * @protected
25979		 * @type {Owl}
25980		 */
25981		this._core = carousel;
25982
25983		/**
25984		 * The autoplay interval.
25985		 * @type {Number}
25986		 */
25987		this._interval = null;
25988
25989		/**
25990		 * Indicates whenever the autoplay is paused.
25991		 * @type {Boolean}
25992		 */
25993		this._paused = false;
25994
25995		/**
25996		 * All event handlers.
25997		 * @protected
25998		 * @type {Object}
25999		 */
26000		this._handlers = {
26001			'changed.owl.carousel': $.proxy(function(e) {
26002				if (e.namespace && e.property.name === 'settings') {
26003					if (this._core.settings.autoplay) {
26004						this.play();
26005					} else {
26006						this.stop();
26007					}
26008				}
26009			}, this),
26010			'initialized.owl.carousel': $.proxy(function(e) {
26011				if (e.namespace && this._core.settings.autoplay) {
26012					this.play();
26013				}
26014			}, this),
26015			'play.owl.autoplay': $.proxy(function(e, t, s) {
26016				if (e.namespace) {
26017					this.play(t, s);
26018				}
26019			}, this),
26020			'stop.owl.autoplay': $.proxy(function(e) {
26021				if (e.namespace) {
26022					this.stop();
26023				}
26024			}, this),
26025			'mouseover.owl.autoplay': $.proxy(function() {
26026				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
26027					this.pause();
26028				}
26029			}, this),
26030			'mouseleave.owl.autoplay': $.proxy(function() {
26031				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
26032					this.play();
26033				}
26034			}, this)
26035		};
26036
26037		// register event handlers
26038		this._core.$element.on(this._handlers);
26039
26040		// set default options
26041		this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
26042	};
26043
26044	/**
26045	 * Default options.
26046	 * @public
26047	 */
26048	Autoplay.Defaults = {
26049		autoplay: false,
26050		autoplayTimeout: 5000,
26051		autoplayHoverPause: false,
26052		autoplaySpeed: false
26053	};
26054
26055	/**
26056	 * Starts the autoplay.
26057	 * @public
26058	 * @param {Number} [timeout] - The interval before the next animation starts.
26059	 * @param {Number} [speed] - The animation speed for the animations.
26060	 */
26061	Autoplay.prototype.play = function(timeout, speed) {
26062		this._paused = false;
26063
26064		if (this._core.is('rotating')) {
26065			return;
26066		}
26067
26068		this._core.enter('rotating');
26069
26070		this._interval = window.setInterval($.proxy(function() {
26071			if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) {
26072				return;
26073			}
26074			this._core.next(speed || this._core.settings.autoplaySpeed);
26075		}, this), timeout || this._core.settings.autoplayTimeout);
26076	};
26077
26078	/**
26079	 * Stops the autoplay.
26080	 * @public
26081	 */
26082	Autoplay.prototype.stop = function() {
26083		if (!this._core.is('rotating')) {
26084			return;
26085		}
26086
26087		window.clearInterval(this._interval);
26088		this._core.leave('rotating');
26089	};
26090
26091	/**
26092	 * Stops the autoplay.
26093	 * @public
26094	 */
26095	Autoplay.prototype.pause = function() {
26096		if (!this._core.is('rotating')) {
26097			return;
26098		}
26099
26100		this._paused = true;
26101	};
26102
26103	/**
26104	 * Destroys the plugin.
26105	 */
26106	Autoplay.prototype.destroy = function() {
26107		var handler, property;
26108
26109		this.stop();
26110
26111		for (handler in this._handlers) {
26112			this._core.$element.off(handler, this._handlers[handler]);
26113		}
26114		for (property in Object.getOwnPropertyNames(this)) {
26115			typeof this[property] != 'function' && (this[property] = null);
26116		}
26117	};
26118
26119	$.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
26120
26121})(window.Zepto || window.jQuery, window, document);
26122
26123/**
26124 * Navigation Plugin
26125 * @version 2.0.0-beta.3
26126 * @author Artus Kolanowski
26127 * @license The MIT License (MIT)
26128 */
26129;(function($, window, document, undefined) {
26130	'use strict';
26131
26132	/**
26133	 * Creates the navigation plugin.
26134	 * @class The Navigation Plugin
26135	 * @param {Owl} carousel - The Owl Carousel.
26136	 */
26137	var Navigation = function(carousel) {
26138		/**
26139		 * Reference to the core.
26140		 * @protected
26141		 * @type {Owl}
26142		 */
26143		this._core = carousel;
26144
26145		/**
26146		 * Indicates whether the plugin is initialized or not.
26147		 * @protected
26148		 * @type {Boolean}
26149		 */
26150		this._initialized = false;
vendor: 14,134 bytes, lines 26151-26679
26151
26152		/**
26153		 * The current paging indexes.
26154		 * @protected
26155		 * @type {Array}
26156		 */
26157		this._pages = [];
26158
26159		/**
26160		 * All DOM elements of the user interface.
26161		 * @protected
26162		 * @type {Object}
26163		 */
26164		this._controls = {};
26165
26166		/**
26167		 * Markup for an indicator.
26168		 * @protected
26169		 * @type {Array.<String>}
26170		 */
26171		this._templates = [];
26172
26173		/**
26174		 * The carousel element.
26175		 * @type {jQuery}
26176		 */
26177		this.$element = this._core.$element;
26178
26179		/**
26180		 * Overridden methods of the carousel.
26181		 * @protected
26182		 * @type {Object}
26183		 */
26184		this._overrides = {
26185			next: this._core.next,
26186			prev: this._core.prev,
26187			to: this._core.to
26188		};
26189
26190		/**
26191		 * All event handlers.
26192		 * @protected
26193		 * @type {Object}
26194		 */
26195		this._handlers = {
26196			'prepared.owl.carousel': $.proxy(function(e) {
26197				if (e.namespace && this._core.settings.dotsData) {
26198					this._templates.push('<div class="' + this._core.settings.dotClass + '">' +
26199						$(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>');
26200				}
26201			}, this),
26202			'added.owl.carousel': $.proxy(function(e) {
26203				if (e.namespace && this._core.settings.dotsData) {
26204					this._templates.splice(e.position, 0, this._templates.pop());
26205				}
26206			}, this),
26207			'remove.owl.carousel': $.proxy(function(e) {
26208				if (e.namespace && this._core.settings.dotsData) {
26209					this._templates.splice(e.position, 1);
26210				}
26211			}, this),
26212			'changed.owl.carousel': $.proxy(function(e) {
26213				if (e.namespace && e.property.name == 'position') {
26214					this.draw();
26215				}
26216			}, this),
26217			'initialized.owl.carousel': $.proxy(function(e) {
26218				if (e.namespace && !this._initialized) {
26219					this._core.trigger('initialize', null, 'navigation');
26220					this.initialize();
26221					this.update();
26222					this.draw();
26223					this._initialized = true;
26224					this._core.trigger('initialized', null, 'navigation');
26225				}
26226			}, this),
26227			'refreshed.owl.carousel': $.proxy(function(e) {
26228				if (e.namespace && this._initialized) {
26229					this._core.trigger('refresh', null, 'navigation');
26230					this.update();
26231					this.draw();
26232					this._core.trigger('refreshed', null, 'navigation');
26233				}
26234			}, this)
26235		};
26236
26237		// set default options
26238		this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
26239
26240		// register event handlers
26241		this.$element.on(this._handlers);
26242	};
26243
26244	/**
26245	 * Default options.
26246	 * @public
26247	 * @todo Rename `slideBy` to `navBy`
26248	 */
26249	Navigation.Defaults = {
26250		nav: false,
26251		navText: [ 'prev', 'next' ],
26252		navSpeed: false,
26253		navElement: 'button type="button"',
26254		navContainer: false,
26255		navContainerClass: 'owl-nav',
26256		navClass: [ 'owl-prev', 'owl-next' ],
26257		slideBy: 1,
26258		dotClass: 'owl-dot',
26259		dotsClass: 'owl-dots',
26260		dots: true,
26261		dotsEach: false,
26262		dotsData: false,
26263		dotsSpeed: false,
26264		dotsContainer: false
26265	};
26266
26267	/**
26268	 * Initializes the layout of the plugin and extends the carousel.
26269	 * @protected
26270	 */
26271	Navigation.prototype.initialize = function() {
26272		var override,
26273			settings = this._core.settings;
26274
26275		// create DOM structure for relative navigation
26276		this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
26277			: $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');
26278
26279		this._controls.$previous = $('<' + settings.navElement[0] + '>')
26280			.addClass(settings.navClass[0])
26281			.html(settings.navText[0])
26282			.prependTo(this._controls.$relative)
26283			.on('click', $.proxy(function(e) {
26284				this.prev(settings.navSpeed);
26285			}, this));
26286		this._controls.$next = $('<' + settings.navElement[1] + '>')
26287			.addClass(settings.navClass[1])
26288			.html(settings.navText[1])
26289			.appendTo(this._controls.$relative)
26290			.on('click', $.proxy(function(e) {
26291				this.next(settings.navSpeed);
26292			}, this));
26293
26294		// create DOM structure for absolute navigation
26295		if (!settings.dotsData) {
26296			this._templates = [ $('<button>')
26297				.addClass(settings.dotClass)
26298				.append($('<span>'))
26299				.prop('outerHTML') ];
26300		}
26301
26302		this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
26303			: $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');
26304
26305		this._controls.$absolute.on('click', 'div, button', $.proxy(function(e) {
26306			var index = $(e.target).parent().is(this._controls.$absolute)
26307				? $(e.target).index() : $(e.target).parent().index();
26308
26309			e.preventDefault();
26310
26311			this.to(index, settings.dotsSpeed);
26312		}, this));
26313
26314		// override public methods of the carousel
26315		for (override in this._overrides) {
26316			this._core[override] = $.proxy(this[override], this);
26317		}
26318	};
26319
26320	/**
26321	 * Destroys the plugin.
26322	 * @protected
26323	 */
26324	Navigation.prototype.destroy = function() {
26325		var handler, control, property, override;
26326
26327		for (handler in this._handlers) {
26328			this.$element.off(handler, this._handlers[handler]);
26329		}
26330		for (control in this._controls) {
26331			this._controls[control].remove();
26332		}
26333		for (override in this.overides) {
26334			this._core[override] = this._overrides[override];
26335		}
26336		for (property in Object.getOwnPropertyNames(this)) {
26337			typeof this[property] != 'function' && (this[property] = null);
26338		}
26339	};
26340
26341	/**
26342	 * Updates the internal state.
26343	 * @protected
26344	 */
26345	Navigation.prototype.update = function() {
26346		var i, j, k,
26347			lower = this._core.clones().length / 2,
26348			upper = lower + this._core.items().length,
26349			maximum = this._core.maximum(true),
26350			settings = this._core.settings,
26351			size = settings.center || settings.autoWidth || settings.dotsData
26352				? 1 : settings.dotsEach || settings.items;
26353
26354		if (settings.slideBy !== 'page') {
26355			settings.slideBy = Math.min(settings.slideBy, settings.items);
26356		}
26357
26358		if (settings.dots || settings.slideBy == 'page') {
26359			this._pages = [];
26360
26361			for (i = lower, j = 0, k = 0; i < upper; i++) {
26362				if (j >= size || j === 0) {
26363					this._pages.push({
26364						start: Math.min(maximum, i - lower),
26365						end: i - lower + size - 1
26366					});
26367					if (Math.min(maximum, i - lower) === maximum) {
26368						break;
26369					}
26370					j = 0, ++k;
26371				}
26372				j += this._core.mergers(this._core.relative(i));
26373			}
26374		}
26375	};
26376
26377	/**
26378	 * Draws the user interface.
26379	 * @todo The option `dotsData` wont work.
26380	 * @protected
26381	 */
26382	Navigation.prototype.draw = function() {
26383		var difference,
26384			settings = this._core.settings,
26385			disabled = this._core.items().length <= settings.items,
26386			index = this._core.relative(this._core.current()),
26387			loop = settings.loop || settings.rewind;
26388
26389		this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);
26390
26391		if (settings.nav) {
26392			this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
26393			this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
26394		}
26395
26396		this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);
26397
26398		if (settings.dots) {
26399			difference = this._pages.length - this._controls.$absolute.children().length;
26400
26401			if (settings.dotsData && difference !== 0) {
26402				this._controls.$absolute.html(this._templates.join(''));
26403			} else if (difference > 0) {
26404				this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
26405			} else if (difference < 0) {
26406				this._controls.$absolute.children().slice(difference).remove();
26407			}
26408
26409			this._controls.$absolute.find('.active').removeClass('active');
26410			this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
26411		}
26412	};
26413
26414	/**
26415	 * Extends event data.
26416	 * @protected
26417	 * @param {Event} event - The event object which gets thrown.
26418	 */
26419	Navigation.prototype.onTrigger = function(event) {
26420		var settings = this._core.settings;
26421
26422		event.page = {
26423			index: $.inArray(this.current(), this._pages),
26424			count: this._pages.length,
26425			size: settings && (settings.center || settings.autoWidth || settings.dotsData
26426				? 1 : settings.dotsEach || settings.items)
26427		};
26428	};
26429
26430	/**
26431	 * Gets the current page position of the carousel.
26432	 * @protected
26433	 * @returns {Number}
26434	 */
26435	Navigation.prototype.current = function() {
26436		var current = this._core.relative(this._core.current());
26437		return $.grep(this._pages, $.proxy(function(page, index) {
26438			return page.start <= current && page.end >= current;
26439		}, this)).pop();
26440	};
26441
26442	/**
26443	 * Gets the current succesor/predecessor position.
26444	 * @protected
26445	 * @returns {Number}
26446	 */
26447	Navigation.prototype.getPosition = function(successor) {
26448		var position, length,
26449			settings = this._core.settings;
26450
26451		if (settings.slideBy == 'page') {
26452			position = $.inArray(this.current(), this._pages);
26453			length = this._pages.length;
26454			successor ? ++position : --position;
26455			position = this._pages[((position % length) + length) % length].start;
26456		} else {
26457			position = this._core.relative(this._core.current());
26458			length = this._core.items().length;
26459			successor ? position += settings.slideBy : position -= settings.slideBy;
26460		}
26461
26462		return position;
26463	};
26464
26465	/**
26466	 * Slides to the next item or page.
26467	 * @public
26468	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
26469	 */
26470	Navigation.prototype.next = function(speed) {
26471		$.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
26472	};
26473
26474	/**
26475	 * Slides to the previous item or page.
26476	 * @public
26477	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
26478	 */
26479	Navigation.prototype.prev = function(speed) {
26480		$.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
26481	};
26482
26483	/**
26484	 * Slides to the specified item or page.
26485	 * @public
26486	 * @param {Number} position - The position of the item or page.
26487	 * @param {Number} [speed] - The time in milliseconds for the transition.
26488	 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
26489	 */
26490	Navigation.prototype.to = function(position, speed, standard) {
26491		var length;
26492
26493		if (!standard) {
26494			length = this._pages.length;
26495			$.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
26496		} else {
26497			$.proxy(this._overrides.to, this._core)(position, speed);
26498		}
26499	};
26500
26501	$.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
26502
26503})(window.Zepto || window.jQuery, window, document);
26504
26505/**
26506 * Hash Plugin
26507 * @version 2.0.0-beta.3
26508 * @author Artus Kolanowski
26509 * @license The MIT License (MIT)
26510 */
26511;(function($, window, document, undefined) {
26512	'use strict';
26513
26514	/**
26515	 * Creates the hash plugin.
26516	 * @class The Hash Plugin
26517	 * @param {Owl} carousel - The Owl Carousel
26518	 */
26519	var Hash = function(carousel) {
26520		/**
26521		 * Reference to the core.
26522		 * @protected
26523		 * @type {Owl}
26524		 */
26525		this._core = carousel;
26526
26527		/**
26528		 * Hash index for the items.
26529		 * @protected
26530		 * @type {Object}
26531		 */
26532		this._hashes = {};
26533
26534		/**
26535		 * The carousel element.
26536		 * @type {jQuery}
26537		 */
26538		this.$element = this._core.$element;
26539
26540		/**
26541		 * All event handlers.
26542		 * @protected
26543		 * @type {Object}
26544		 */
26545		this._handlers = {
26546			'initialized.owl.carousel': $.proxy(function(e) {
26547				if (e.namespace && this._core.settings.startPosition === 'URLHash') {
26548					$(window).trigger('hashchange.owl.navigation');
26549				}
26550			}, this),
26551			'prepared.owl.carousel': $.proxy(function(e) {
26552				if (e.namespace) {
26553					var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');
26554
26555					if (!hash) {
26556						return;
26557					}
26558
26559					this._hashes[hash] = e.content;
26560				}
26561			}, this),
26562			'changed.owl.carousel': $.proxy(function(e) {
26563				if (e.namespace && e.property.name === 'position') {
26564					var current = this._core.items(this._core.relative(this._core.current())),
26565						hash = $.map(this._hashes, function(item, hash) {
26566							return item === current ? hash : null;
26567						}).join();
26568
26569					if (!hash || window.location.hash.slice(1) === hash) {
26570						return;
26571					}
26572
26573					window.location.hash = hash;
26574				}
26575			}, this)
26576		};
26577
26578		// set default options
26579		this._core.options = $.extend({}, Hash.Defaults, this._core.options);
26580
26581		// register the event handlers
26582		this.$element.on(this._handlers);
26583
26584		// register event listener for hash navigation
26585		/*$(window).on('hashchange.owl.navigation', $.proxy(function(e) {
26586			var hash = window.location.hash.substring(1),
26587				items = this._core.$stage.children(),
26588				position = this._hashes[hash] && items.index(this._hashes[hash]);
26589
26590			if (position === undefined || position === this._core.current()) {
26591				return;
26592			}
26593
26594			this._core.to(this._core.relative(position), false, true);
26595		}, this));*/
26596	};
26597
26598	/**
26599	 * Default options.
26600	 * @public
26601	 */
26602	Hash.Defaults = {
26603		URLhashListener: false
26604	};
26605
26606	/**
26607	 * Destroys the plugin.
26608	 * @public
26609	 */
26610	Hash.prototype.destroy = function() {
26611		var handler, property;
26612
26613		$(window).off('hashchange.owl.navigation');
26614
26615		for (handler in this._handlers) {
26616			this._core.$element.off(handler, this._handlers[handler]);
26617		}
26618		for (property in Object.getOwnPropertyNames(this)) {
26619			typeof this[property] != 'function' && (this[property] = null);
26620		}
26621	};
26622
26623	$.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
26624
26625})(window.Zepto || window.jQuery, window, document);
26626
26627/**
26628 * Support Plugin
26629 *
26630 * @version 2.0.0-beta.3
26631 * @author Vivid Planet Software GmbH
26632 * @author Artus Kolanowski
26633 * @license The MIT License (MIT)
26634 */
26635;(function($, window, document, undefined) {
26636
26637	var style = $('<support>').get(0).style,
26638		prefixes = 'Webkit Moz O ms'.split(' '),
26639		events = {
26640			transition: {
26641				end: {
26642					WebkitTransition: 'webkitTransitionEnd',
26643					MozTransition: 'transitionend',
26644					OTransition: 'oTransitionEnd',
26645					transition: 'transitionend'
26646				}
26647			},
26648			animation: {
26649				end: {
26650					WebkitAnimation: 'webkitAnimationEnd',
26651					MozAnimation: 'animationend',
26652					OAnimation: 'oAnimationEnd',
26653					animation: 'animationend'
26654				}
26655			}
26656		},
26657		tests = {
26658			csstransforms: function() {
26659				return !!test('transform');
26660			},
26661			csstransforms3d: function() {
26662				return !!test('perspective');
26663			},
26664			csstransitions: function() {
26665				return !!test('transition');
26666			},
26667			cssanimations: function() {
26668				return !!test('animation');
26669			}
26670		};
26671
26672	function test(property, prefixed) {
26673		var result = false,
26674			upper = property.charAt(0).toUpperCase() + property.slice(1);
26675
26676		$.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {
26677			if (style[property] !== undefined) {
26678				result = prefixed ? property : true;
26679				return false;
26680			}
26681		});
26682
26683		return result;
26684	}
26685
26686	function prefixed(property) {
26687		return test(property, true);
26688	}
26689
26690	if (tests.csstransitions()) {
26691		/* jshint -W053 */
26692		$.support.transition = new String(prefixed('transition'))
26693		$.support.transition.end = events.transition.end[ $.support.transition ];
26694	}
26695
26696	if (tests.cssanimations()) {
26697		/* jshint -W053 */
26698		$.support.animation = new String(prefixed('animation'))
26699		$.support.animation.end = events.animation.end[ $.support.animation ];
26700	}
26701
26702	if (tests.csstransforms()) {
26703		/* jshint -W053 */
26704		$.support.transform = new String(prefixed('transform'));
26705		$.support.transform3d = tests.csstransforms3d();
26706	}
26707
26708})(window.Zepto || window.jQuery, window, document);
26709
26710(function(window, document, undefined) {
26711
26712	/**
26713	 * Find the absolute position of an element
26714	 */
26715	var absPos = function(element) {
26716		var offsetLeft, offsetTop;
26717		offsetLeft = offsetTop = 0;
26718		if (element.offsetParent) {
26719			do {
26720				offsetLeft += element.offsetLeft;
26721				offsetTop += element.offsetTop;
26722			} while (element = element.offsetParent);
26723		}
26724		return [offsetLeft, offsetTop];
26725	};
26726
26727	/**
26728	 * @constructor Progress Circle class
26729	 * @param params.canvas Canvas on which the circles will be drawn.
26730	 * @param params.minRadius Inner radius of the innermost circle, in px.
26731	 * @param params.arcWidth Width of each circle(to be more accurate, ring).
26732	 * @param params.gapWidth Space between each circle.
26733	 * @param params.centerX X coordinate of the center of circles.
26734	 * @param params.centerY Y coordinate of the center of circles.
26735	 * @param params.infoLineBaseAngle Base angle of the info line.
26736	 * @param params.infoLineAngleInterval Angles between the info lines.
26737	 */
26738	var ProgressCircle = function(params) {
26739		this.canvas = params.canvas;
26740		this.minRadius = params.minRadius || 15;
26741		this.arcWidth = params.arcWidth || 5;
26742		this.gapWidth = params.gapWidth || 3;
26743		this.centerX = params.centerX || this.canvas.width / 2;
26744		this.centerY = params.centerY || this.canvas.height / 2;
26745		this.infoLineLength = params.infoLineLength || 60;
26746		this.horizLineLength = params.horizLineLength || 10;
26747		this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8;
26748		this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6;
26749
26750		this.context = this.canvas.getContext('2d');
26751
26752		this.width = this.canvas.width;
26753		this.height = this.canvas.height;
26754
26755		this.circles = [];
26756		this.runningCount = 0;
26757	};
26758
26759	ProgressCircle.prototype = {
26760		constructor: ProgressCircle,
26761
26762		/**
26763		 * @method Adds an progress monitor entry.
26764		 * @param params.fillColor Color to fill in the circle.
26765		 * @param params.outlineColor Color to outline the circle.
26766		 * @param params.progressListener Callback function to fetch the progress.
26767		 * @param params.infoListener Callback function to fetch the info.
26768		 * @returns this
26769		 */
26770		addEntry: function(params) {
26771			this.circles.push(new Circle({
26772				canvas: this.canvas,
26773				context: this.context,
26774				centerX: this.centerX,
26775				centerY: this.centerY,
26776				innerRadius: this.minRadius + this.circles.length *
26777					(this.gapWidth + this.arcWidth),
26778				arcWidth: this.arcWidth,
26779				infoLineLength: this.infoLineLength,
26780				horizLineLength: this.horizLineLength,
26781
26782				id: this.circles.length,
26783				fillColor: params.fillColor,
26784				outlineColor: params.outlineColor,
26785				progressListener: params.progressListener,
26786				infoListener: params.infoListener,
26787				infoLineAngle: this.infoLineBaseAngle +
26788					this.circles.length * this.infoLineAngleInterval,
26789			}));
26790
26791			return this;
26792		},
26793
26794		/**
26795		 * @method Starts the monitor and updates with the given interval.
26796		 * @param interval Interval between updates, in millisecond.
26797		 * @returns this
26798		 */
26799		start: function(interval) {
26800			var self = this;
26801			this.timer = setInterval(function() {
26802				self._update();
26803			}, interval || 33);
26804
26805			return this;
26806		},
26807
26808		/**
26809		 * @method Stop the animation.
26810		 */
26811		stop: function() {
26812			clearTimeout(this.timer);
26813		},
26814
26815		/**
26816		 * @private
26817		 * @method Call update on each circle and redraw them.
26818		 * @returns this
26819		 */
26820		_update: function() {
26821			this._clear();
26822			this.circles.forEach(function(circle, idx, array) {
26823				circle.update();
26824			});
26825
26826			return this;
26827		},
26828
26829		/**
26830		 * @private
26831		 * @method Clear the canvas.
26832		 * @returns this
26833		 */
26834		_clear: function() {
26835			this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
26836
26837			return this;
26838		},
26839
26840	};
26841
26842	/**
26843	 * @private
26844	 * @class Individual progress circle.
26845	 * @param params.canvas Canvas on which the circle will be drawn.
26846	 * @param params.context Context of the canvas.
26847	 * @param params.innerRadius Inner radius of the circle, in px.
26848	 * @param params.arcWidth Width of each arc(circle).
26849	 * @param params.gapWidth Distance between each arc.
26850	 * @param params.centerX X coordinate of the center of circles.
26851	 * @param params.centerY Y coordinate of the center of circles.
26852	 * @param params.fillColor Color to fill in the circle.
26853	 * @param params.outlineColor Color to outline the circle.
26854	 * @param params.progressListener Callback function to fetch the progress.
26855	 * @param params.infoListener Callback function to fetch the info.
26856	 * @param params.infoLineAngle Angle of info line.
26857	 */
26858	var Circle = function(params) {
26859		this.id = params.id;
26860		this.canvas = params.canvas;
26861		this.context = params.context;
26862		this.centerX = params.centerX;
26863		this.centerY = params.centerY;
26864		this.arcWidth = params.arcWidth;
26865		this.innerRadius = params.innerRadius || 0;
26866		this.fillColor = params.fillColor || '#fff';
26867		this.outlineColor = params.outlineColor || this.fillColor;
26868		this.progressListener = params.progressListener;
26869		this.infoLineLength = params.infoLineLength || 250;
26870		this.horizLineLength = params.horizLineLength || 50;
26871		this.infoListener = params.infoListener;
26872		this.infoLineAngle = params.infoLineAngle;
26873
26874		this.outerRadius = this.innerRadius + this.arcWidth;
26875
26876		// If the info listener is not registered, then don't calculate
26877		// the related coordinates
26878		if (!this.infoListener) return;
26879
26880		// calculate the info-line turning points
26881		var angle = this.infoLineAngle,
26882			arcDistance = (this.innerRadius + this.outerRadius) / 2,
26883
26884			sinA = Math.sin(angle),
26885			cosA = Math.cos(angle);
26886
26887		this.infoLineStartX = this.centerX + sinA * arcDistance;
26888		this.infoLineStartY = this.centerY - cosA * arcDistance;
26889
26890		this.infoLineMidX = this.centerX + sinA * this.infoLineLength;
26891		this.infoLineMidY = this.centerY - cosA * this.infoLineLength;
26892
26893		this.infoLineEndX = this.infoLineMidX +
26894			 (sinA < 0 ? -this.horizLineLength : this.horizLineLength);
26895		this.infoLineEndY = this.infoLineMidY;
26896
26897		var infoText = document.createElement('div'),
26898			style = infoText.style;
26899
26900		style.color = this.fillColor;
26901		style.position = 'absolute';
26902		style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px';
26903		// style.top will be calculated in the `drawInfo` method. Since
26904		// user may want to change the size of the font, so the top offset
26905		// must be updated in each loop.
26906		infoText.className = 'ProgressCircleInfo'; // For css styling
26907		infoText.id = 'progress_circle_info_' + this.id;
26908		document.body.appendChild(infoText);
26909		this.infoText = infoText;
26910	};
26911
26912	Circle.prototype = {
26913		constructor: Circle,
26914
26915		update: function() {
26916			this.progress = this.progressListener();
26917			this._draw();
26918
26919			if (this.infoListener) {
26920				this.info = this.infoListener();
26921				this._drawInfo();
26922			}
26923		},
26924
26925		/**
26926		 * @private
26927		 * @method Draw the circle on the canvas.
26928		 * @returns this
26929		 */
26930		_draw: function() {
26931			var ctx = this.context,
26932
26933				ANGLE_OFFSET = -Math.PI / 2,
26934
26935				startAngle = 0 + ANGLE_OFFSET,
26936				endAngle= startAngle + this.progress * Math.PI * 2,
26937
26938				x = this.centerX,
26939				y = this.centerY,
26940
26941				innerRadius = this.innerRadius - this.arcWidth - 1,
26942				outerRadius = this.outerRadius - this.arcWidth - 1;
26943
26944			if ( innerRadius < 0 )
26945				return;
26946
26947			ctx.fillStyle = this.fillColor;
26948			ctx.strokeStyle = this.outlineColor;
26949
26950			ctx.beginPath();
26951			ctx.arc(x, y, innerRadius, startAngle, endAngle, false);
26952			ctx.arc(x, y, outerRadius, endAngle, startAngle, true);
26953			ctx.closePath();
26954			ctx.stroke();
26955			ctx.fill();
26956
26957			return this;
26958		},
26959
26960		/**
26961		 * @private
26962		 * @method Draw the info lines and info text.
26963		 * @returns this
26964		 */
26965		_drawInfo: function() {
26966
26967			var pointList, lineHeight;
26968
26969			pointList = [
26970				[this.infoLineStartX, this.infoLineStartY],
26971				[this.infoLineMidX, this.infoLineMidY],
26972				[this.infoLineEndX, this.infoLineEndY],
26973			];
26974			this._drawSegments(pointList, false);
26975
26976			this.infoText.innerHTML = this.info;
26977
26978			lineHeight = this.infoText.offsetHeight;
26979			this.infoText.style.top = this.infoLineEndY +
26980				absPos(this.canvas)[1] - lineHeight / 2 + 'px';
26981
26982			return this;
26983		},
26984
26985		/**
26986		 * @private
26987		 * @method Helper function to draw the segments
26988		 * @param pointList An array of points in the form of [x, y].
26989		 * @param close Whether to connect the first and last point.
26990		 */
26991		_drawSegments: function(pointList, close) {
26992			var ctx = this.context;
26993
26994			ctx.beginPath();
26995			ctx.moveTo(pointList[0][0], pointList[0][1]);
26996			for (var i = 1; i < pointList.length; ++i) {
26997				ctx.lineTo(pointList[i][0], pointList[i][1]);
26998			}
26999
27000			if (close) {
27001				ctx.closePath();
27002			}
27003			ctx.stroke();
27004		},
27005	};
27006
27007	window.ProgressCircle = ProgressCircle;
27008
27009})(window, document);
27010
27011
27012
27013
27014/* =========================================================
27015 * jquery.vc_chart.js v1.0
27016 * =========================================================
27017 * Copyright 2013 Wpbakery
27018 *
27019 * Jquery chart plugin for the Visual Composer.
27020 * ========================================================= */
27021(function($){
27022	/**
27023	 * Pie chart animated.
27024	 * @param element - DOM element
27025	 * @param options - settings object.
27026	 * @constructor
27027	 */
27028	var VcChart = function(element, options) {
27029		this.el = element;
27030		this.$el = $(this.el);
27031		var $this = this;
27032		$this.options = $.extend({
27033			color: 'wpb_button',
27034			units: '',
27035			width: '',
27036			label_selector: '.vc_pie_chart_value',
27037			back_selector: '.vc_pie_chart_back',
27038			responsive: true
27039		}, options);
27040		$this.init();
27041	};
27042	VcChart.prototype = {
27043		constructor: VcChart,
27044		_progress_v: 0,
27045		animated: false,
27046		colors: {
27047			'wpb_button': 'rgba(247, 247, 247, 1)',
27048			'btn-primary': 'rgba(0, 136, 204, 1)',
27049			'btn-info': 'rgba(88, 185, 218, 1)',
27050			'btn-success': 'rgba(106, 177, 101, 1)',
27051			'btn-warning': 'rgba(255, 153, 0, 1)',
27052			'btn-danger': 'rgba(255, 103, 91, 1)',
27053			'btn-inverse': 'rgba(85, 85, 85, 1)'
27054		},
27055		init: function() {
27056			this.setupColor();
27057			this.value = this.$el.data('pie-value')/100;
27058			this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value');
27059			this.$wrapper = $('.vc_pie_wrapper', this.$el);
27060			this.$label = $(this.options.label_selector, this.$el);
27061			this.$back = $(this.options.back_selector, this.$el);
27062			this.$canvas = this.$el.find('canvas');
27063			this.arcWidth = this.$el.data('pie-width') * 2;
27064			this.draw();
27065			this.setWayPoint();
27066			if(this.options.responsive === true) this.setResponsive();
27067			if (UNCODE.isMobile) this._progress_v = this.value;
27068		},
27069		setupColor: function() {
27070			// if(typeof this.colors[this.options.color] !== 'undefined') {
27071			//     this.color = this.colors[this.options.color];
27072			// } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) {
27073			//     this.color = this.options.color;
27074			// } else {
27075			//     this.color = 'rgba(247, 247, 247, 0.2)';
27076			// }
27077			if(typeof this.options.color !== 'undefined') {
27078				this.color = this.options.color;
27079			} else this.color = 'rgba(247, 247, 247, 0.2)';
27080
27081		},
27082		setResponsive: function() {
27083			var that = this;
27084			if (!UNCODE.isMobile) {
27085				$(window).resize(function(){
27086					if(that.animated === true) that.circle.stop();
27087					that.draw(true);
27088				});
27089			}
27090		},
27091		draw: function(redraw) {
27092			var w = this.$el.addClass('vc_ready').width() * 2,
27093				border_w = this.arcWidth,
27094				radius;
27095			if(!w) w = this.$el.parents(':visible').first().width()-2;
27096			//w = Math.round(w/100*80);
27097			//if (w < 250) w = 250;
27098			radius = w/2;
27099			this.$wrapper.css({"width" : (w / 2) + "px"});
27100			this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"});
27101			this.$back.css({"width" : (w / 2), "height" : (w / 2)});
27102			this.$canvas.attr({"width" : w + "px", "height" : w + "px"});
27103			this.$el.addClass('vc_ready');
27104			this.circle = new ProgressCircle({
27105				canvas: this.$canvas.get(0),
27106				minRadius: radius,
27107				arcWidth: border_w
27108			});
27109			if(redraw === true && this.animated === true) {
27110				this._progress_v = this.value;
27111				this.circle.addEntry({
27112					fillColor: this.color,
27113					progressListener: $.proxy(this.setProgress, this)
27114				}).start();
27115			}
27116		},
27117		setProgress: function() {
27118			if (this._progress_v >= this.value) {
27119				this.circle.stop();
27120				this.animated = true;
27121				this.$label.html(this.label_value + this.options.units);
27122				return this._progress_v;
27123			}
27124			this._progress_v += 0.01;
27125			if (!isNaN(this.label_value)) {
27126				var label_value = this._progress_v/this.value*this.label_value;
27127				var val = Math.round(label_value) + this.options.units;
27128				this.$label.html(val);
27129			} else this.$label.html(this.label_value + this.options.units);
27130			return this._progress_v;
27131		},
27132		animate: function() {
27133			if(this.animated !== true) {
27134				this.circle.addEntry({
27135					fillColor: this.color,
27136					progressListener: $.proxy(this.setProgress, this)
27137				}).start(10);
27138			}
27139		},
27140		setWayPoint: function() {
27141			if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) {
27142				this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' });
27143			} else {
27144				this.animate();
27145			}
27146		}
27147	};
27148	/**
27149	 * jQuery plugin
27150	 * @param option - object with settings
27151	 * @return {*}
27152	 */
27153	$.fn.vcChat = function(option, value) {
27154		return this.each(function () {
27155			var $this = $(this),
27156				data = $this.data('vc_chart'),
27157				options = typeof option === 'object' ? option : {
27158					color: $this.data('pie-color'),
27159					units: $this.data('pie-units')
27160				};
27161			if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options)));
27162			if (typeof option == 'string') data[option](value);
27163		});
27164	};
27165	/**
27166	 * Allows users to rewrite function inside theme.
27167	 */
27168	if ( typeof window['vc_pieChart'] !== 'function' ) {
27169		window.vc_pieChart = function() {
27170			$('.vc_pie_chart:visible:not(.vc_ready)').vcChat();
27171		}
27172	}
27173	$(document).ready(function(){
27174		!window.vc_iframe && vc_pieChart();
27175
27176		/**
27177		* Tab and collapse integration.
27178		*/
27179		$('.nav-tabs a').on('shown.bs.tab', function(e){
27180			var $cont = $(e.target).closest('.tab-container'),
27181				$active = $('.tab-pane.active', $cont);
27182			$('.vc_pie_chart:not(.vc_ready)', $active).vcChat();
27183		});
27184
27185		$('.panel-collapse').on('shown.bs.collapse', function (e) {
27186			$('.vc_pie_chart:not(.vc_ready)', e.target).vcChat();
27187		})
27188	});
27189
27190})(window.jQuery);
27191
27192/* Progress bar
27193 ---------------------------------------------------------- */
27194function uncode_progress_bar() {
27195	jQuery.each(jQuery('.vc_progress_bar'), function(index, val) {
27196		if (UNCODE.isUnmodalOpen && !val.closest('#unmodal-content')) {
27197			return;
27198		}
27199		if (!UNCODE.isMobile) {
27200			new Waypoint({
27201				context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window,
27202				element: val,
27203				handler: function() {
27204					var element = jQuery(this.element);
27205					element.find('.vc_single_bar').each(function(index) {
27206						var $this = jQuery(this),
27207							bar = $this.find('.vc_bar'),
27208							val = bar.data('percentage-value');
27209						setTimeout(function() {
27210							bar.css({
27211								"width": val + '%'
27212							});
27213						}, index * 200);
27214					});
27215				},
27216				offset: '80%'
27217			});
27218		} else {
27219			var element = jQuery(val);
27220			element.find('.vc_single_bar').each(function(index) {
27221				var $this = jQuery(this),
27222					bar = $this.find('.vc_bar'),
27223					val = bar.data('percentage-value');
27224				setTimeout(function() {
27225					bar.css({
27226						"width": val + '%'
27227					});
27228				}, index * 200);
27229			});
27230		}
27231	});
27232};
27233uncode_progress_bar();
27234
27235/*!
27236 * jquery.counterup.js 1.0
27237 *
27238 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal
27239 * Released under the GPL v2 License
27240 *
27241 * Date: Nov 26, 2013
27242 */
27243(function($) {
27244	"use strict";
27245	$.fn.counterUp = function(options) {
27246		// Defaults
27247		var settings = $.extend({
27248			'time': 400,
27249			'delay': 10
27250		}, options);
27251		return this.each(function() {
27252			// Store the object
27253			var $this = $(this);
27254			var $settings = settings;
27255			var counterUpper = function() {
27256				var nums = [];
27257				var divisions = $settings.time / $settings.delay;
27258				var numReal = $this.attr('data-val'),
27259				num = numReal;
27260				var isComma = /[0-9]+,[0-9]+/.test(num);
27261				num = num.replace(/,/g, '');
27262				var isInt = /^[0-9]+$/.test(num);
27263				var isFloat = /^[0-9]+\.[0-9]+$/.test(num);
27264				var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;
27265				// Generate list of incremental numbers to display
27266				for (var i = divisions; i >= 1; i--) {
27267					// Preserve as int if input was int
27268					var newNum = parseInt(num / divisions * i);
27269					// Preserve float if input was float
27270					if (isFloat) {
27271						newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces);
27272					}
27273					// Preserve commas if input had commas
27274					if (isComma) {
27275						while (/(\d+)(\d{3})/.test(newNum.toString())) {
27276							newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
27277						}
27278					}
27279					nums.unshift(newNum);
27280				}
27281				nums.push(numReal);
27282				$this.data('counterup-nums', nums);
27283				$this.text('0');
27284				// Updates the number until we're done
27285				var f = function() {
27286					if ($this.data('counterup-nums') != null) {
27287						$this.text($this.data('counterup-nums').shift());
27288						if ($this.data('counterup-nums').length) {
27289							setTimeout($this.data('counterup-func'), $settings.delay);
27290						} else {
27291							delete $this.data('counterup-nums');
27292							$this.data('counterup-nums', null);
27293							$this.data('counterup-func', null);
27294						}
27295					}
27296				};
27297				$this.data('counterup-func', f);
27298				// Start the count up
27299				setTimeout($this.data('counterup-func'), $settings.delay);
27300			};
27301			// Perform counts when the element gets into view
27302			new Waypoint({
27303				context: UNCODE.isUnmodalOpen ? document.getElementById('unmodal-content') : window,
27304				element: this,
27305				handler: function() {
27306					counterUpper();
27307					if (!UNCODE.isUnmodalOpen) {
27308						this.destroy();
27309					}
27310				},
27311				offset: '100%'
27312			});
27313		});
27314	};
27315})(jQuery);
27316
27317/*!
27318 * The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/)
27319 * Copyright (c) 2016 Edson Hilios
27320 *
27321 * Permission is hereby granted, free of charge, to any person obtaining a copy of
27322 * this software and associated documentation files (the "Software"), to deal in
27323 * the Software without restriction, including without limitation the rights to
27324 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
27325 * the Software, and to permit persons to whom the Software is furnished to do so,
27326 * subject to the following conditions:
27327 *
27328 * The above copyright notice and this permission notice shall be included in all
27329 * copies or substantial portions of the Software.
27330 *
27331 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27332 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
27333 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
27334 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
27335 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27336 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27337 */
27338(function(factory) {
27339	"use strict";
27340	if (typeof define === "function" && define.amd) {
27341		define([ "jquery" ], factory);
27342	} else {
27343		factory(jQuery);
27344	}
27345})(function($) {
27346	"use strict";
27347	var instances = [], matchers = [], defaultOptions = {
27348		precision: 100,
27349		elapse: false,
27350		defer: false
27351	};
27352	matchers.push(/^[0-9]*$/.source);
27353	matchers.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
27354	matchers.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source);
27355	matchers = new RegExp(matchers.join("|"));
27356	function parseDateString(dateString) {
27357		if (dateString instanceof Date) {
27358			return dateString;
27359		}
27360		if (String(dateString).match(matchers)) {
27361			if (String(dateString).match(/^[0-9]*$/)) {
27362				dateString = Number(dateString);
27363			}
27364			if (String(dateString).match(/\-/)) {
27365				dateString = String(dateString).replace(/\-/g, "/");
27366			}
27367			return new Date(dateString);
27368		} else {
27369			throw new Error("Couldn't cast `" + dateString + "` to a date object.");
27370		}
27371	}
27372	var DIRECTIVE_KEY_MAP = {
27373		Y: "years",
27374		m: "months",
27375		n: "daysToMonth",
27376		d: "daysToWeek",
27377		w: "weeks",
27378		W: "weeksToMonth",
27379		H: "hours",
27380		M: "minutes",
27381		S: "seconds",
27382		D: "totalDays",
27383		I: "totalHours",
27384		N: "totalMinutes",
27385		T: "totalSeconds"
27386	};
27387	function escapedRegExp(str) {
27388		var sanitize = str.toString().replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
27389		return new RegExp(sanitize);
27390	}
27391	function strftime(offsetObject) {
27392		return function(format) {
27393			var directives = format.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);
27394			if (directives) {
27395				for (var i = 0, len = directives.length; i < len; ++i) {
27396					var directive = directives[i].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/), regexp = escapedRegExp(directive[0]), modifier = directive[1] || "", plural = directive[3] || "", value = null;
27397					directive = directive[2];
27398					if (DIRECTIVE_KEY_MAP.hasOwnProperty(directive)) {
27399						value = DIRECTIVE_KEY_MAP[directive];
27400						value = Number(offsetObject[value]);
27401					}
27402					if (value !== null) {
27403						if (modifier === "!") {
27404							value = pluralize(plural, value);
27405						}
27406						if (modifier === "") {
27407							if (value < 10) {
27408								value = "0" + value.toString();
27409							}
27410						}
27411						format = format.replace(regexp, value.toString());
27412					}
27413				}
27414			}
27415			format = format.replace(/%%/, "%");
27416			return format;
27417		};
27418	}
27419	function pluralize(format, count) {
27420		var plural = "s", singular = "";
27421		if (format) {
27422			format = format.rep
vendor: 8,618 bytes, lines 27422-27566
27422lace(/(:|;|\s)/gi, "").split(/\,/);
27423			if (format.length === 1) {
27424				plural = format[0];
27425			} else {
27426				singular = format[0];
27427				plural = format[1];
27428			}
27429		}
27430		if (Math.abs(count) > 1) {
27431			return plural;
27432		} else {
27433			return singular;
27434		}
27435	}
27436	var Countdown = function(el, finalDate, options) {
27437		this.el = el;
27438		this.$el = $(el);
27439		this.interval = null;
27440		this.offset = {};
27441		this.options = $.extend({}, defaultOptions);
27442		this.instanceNumber = instances.length;
27443		instances.push(this);
27444		this.$el.data("countdown-instance", this.instanceNumber);
27445		if (options) {
27446			if (typeof options === "function") {
27447				this.$el.on("update.countdown", options);
27448				this.$el.on("stoped.countdown", options);
27449				this.$el.on("finish.countdown", options);
27450			} else {
27451				this.options = $.extend({}, defaultOptions, options);
27452			}
27453		}
27454		this.setFinalDate(finalDate);
27455		if (this.options.defer === false) {
27456			this.start();
27457		}
27458	};
27459	$.extend(Countdown.prototype, {
27460		start: function() {
27461			if (this.interval !== null) {
27462				clearInterval(this.interval);
27463			}
27464			var self = this;
27465			this.update();
27466			this.interval = setInterval(function() {
27467				self.update.call(self);
27468			}, this.options.precision);
27469		},
27470		stop: function() {
27471			clearInterval(this.interval);
27472			this.interval = null;
27473			this.dispatchEvent("stoped");
27474		},
27475		toggle: function() {
27476			if (this.interval) {
27477				this.stop();
27478			} else {
27479				this.start();
27480			}
27481		},
27482		pause: function() {
27483			this.stop();
27484		},
27485		resume: function() {
27486			this.start();
27487		},
27488		remove: function() {
27489			this.stop.call(this);
27490			instances[this.instanceNumber] = null;
27491			delete this.$el.data().countdownInstance;
27492		},
27493		setFinalDate: function(value) {
27494			this.finalDate = parseDateString(value);
27495		},
27496		update: function() {
27497			if (this.$el.closest("html").length === 0) {
27498				this.remove();
27499				return;
27500			}
27501			var hasEventsAttached = $._data(this.el, "events") !== undefined, now = new Date(), newTotalSecsLeft;
27502			newTotalSecsLeft = this.finalDate.getTime() - now.getTime();
27503			newTotalSecsLeft = Math.ceil(newTotalSecsLeft / 1e3);
27504			newTotalSecsLeft = !this.options.elapse && newTotalSecsLeft < 0 ? 0 : Math.abs(newTotalSecsLeft);
27505			if (this.totalSecsLeft === newTotalSecsLeft || !hasEventsAttached) {
27506				return;
27507			} else {
27508				this.totalSecsLeft = newTotalSecsLeft;
27509			}
27510			this.elapsed = now >= this.finalDate;
27511			this.offset = {
27512				seconds: this.totalSecsLeft % 60,
27513				minutes: Math.floor(this.totalSecsLeft / 60) % 60,
27514				hours: Math.floor(this.totalSecsLeft / 60 / 60) % 24,
27515				days: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7,
27516				daysToWeek: Math.floor(this.totalSecsLeft / 60 / 60 / 24) % 7,
27517				daysToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 % 30.4368),
27518				weeks: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7),
27519				weeksToMonth: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 7) % 4,
27520				months: Math.floor(this.totalSecsLeft / 60 / 60 / 24 / 30.4368),
27521				years: Math.abs(this.finalDate.getFullYear() - now.getFullYear()),
27522				totalDays: Math.floor(this.totalSecsLeft / 60 / 60 / 24),
27523				totalHours: Math.floor(this.totalSecsLeft / 60 / 60),
27524				totalMinutes: Math.floor(this.totalSecsLeft / 60),
27525				totalSeconds: this.totalSecsLeft
27526			};
27527			if (!this.options.elapse && this.totalSecsLeft === 0) {
27528				this.stop();
27529				this.dispatchEvent("finish");
27530			} else {
27531				this.dispatchEvent("update");
27532			}
27533		},
27534		dispatchEvent: function(eventName) {
27535			var event = $.Event(eventName + ".countdown");
27536			event.finalDate = this.finalDate;
27537			event.elapsed = this.elapsed;
27538			event.offset = $.extend({}, this.offset);
27539			event.strftime = strftime(this.offset);
27540			this.$el.trigger(event);
27541		}
27542	});
27543	$.fn.countdown = function() {
27544		var argumentsArray = Array.prototype.slice.call(arguments, 0);
27545		return this.each(function() {
27546			var instanceNumber = $(this).data("countdown-instance");
27547			if (instanceNumber !== undefined) {
27548				var instance = instances[instanceNumber], method = argumentsArray[0];
27549				if (Countdown.prototype.hasOwnProperty(method)) {
27550					instance[method].apply(instance, argumentsArray.slice(1));
27551				} else if (String(method).match(/^[$A-Z_][0-9A-Z_$]*$/i) === null) {
27552					instance.setFinalDate.call(instance, method);
27553					instance.start();
27554				} else {
27555					$.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi, method));
27556				}
27557			} else {
27558				new Countdown(this, argumentsArray[0], argumentsArray[1]);
27559			}
27560		});
27561	};
27562});
27563
27564!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;
27565function getStyles(config){
27566  // 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;
27566left: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+"}"
27567};
27568  var ShareUtils;
27569
27570if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") {
27571  Object.defineProperty(HTMLElement.prototype, "classList", {
27572    get: function() {
27573      var ret, self, update;
27574      update = function(fn) {
27575        return function(value) {
27576          var classes, index;
27577          classes = self.className.split(/\s+/);
27578          index = classes.indexOf(value);
27579          fn(classes, index, value);
27580          self.className = classes.join(" ");
27581        };
27582      };
27583      self = this;
27584      ret = {
27585        add: update(function(classes, index, value) {
27586          ~index || classes.push(value);
27587        }),
27588        remove: update(function(classes, index) {
27589          ~index && classes.splice(index, 1);
27590        }),
27591        toggle: update(function(classes, index, value) {
27592          if (~index) {
27593            classes.splice(index, 1);
27594          } else {
27595            classes.push(value);
27596          }
27597        }),
27598        contains: function(value) {
27599          return !!~self.className.split(/\s+/).indexOf(value);
27600        },
27601        item: function(i) {
27602          return self.className.split(/\s+/)[i] || null;
27603        }
27604      };
27605      Object.defineProperty(ret, "length", {
27606        get: function() {
27607          return self.className.split(/\s+/).length;
27608        }
27609      });
27610      return ret;
27611    }
27612  });
27613}
27614
27615String.prototype.to_rfc3986 = function() {
27616  var tmp;
27617  tmp = encodeURIComponent(this);
27618  return tmp.replace(/[!'()*]/g, function(c) {
27619    return "%" + c.charCodeAt(0).toString(16);
27620  });
27621};
27622
27623ShareUtils = (function() {
27624  function ShareUtils() {}
27625
27626  ShareUtils.prototype.extend = function(to, from, overwrite) {
27627    var hasProp, prop;
27628    for (prop in from) {
27629      hasProp = to[prop] !== undefined;
27630      if (hasProp && typeof from[prop] === "object") {
27631        this.extend(to[prop], from[prop], overwrite);
27632      } else {
27633        if (overwrite || !hasProp) {
27634          to[prop] = from[prop];
27635        }
27636      }
27637    }
27638  };
27639
27640  ShareUtils.prototype.hide = function(el) {
27641    return el.style.display = "none";
27642  };
27643
27644  ShareUtils.prototype.show = function(el) {
27645    return el.style.display = "block";
27646  };
27647
27648  ShareUtils.prototype.has_class = function(el, class_name) {
27649    return el.classList.contains(class_name);
27650  };
27651
27652  ShareUtils.prototype.add_class = function(el, class_name) {
27653    return el.classList.add(class_name);
27654  };
27655
27656  ShareUtils.prototype.remove_class = function(el, class_name) {
27657    return el.classList.remove(class_name);
27658  };
27659
27660  ShareUtils.prototype.is_encoded = function(str) {
27661    str = str.to_rfc3986();
27662    return decodeURIComponent(str) !== str;
27663  };
27664
27665  ShareUtils.prototype.encode = function(str) {
27666    if (typeof str === "undefined" || this.is_encoded(str)) {
27667      return str;
27668    } else {
27669      return str.to_rfc3986();
27670    }
27671  };
27672
27673  ShareUtils.prototype.popup = function(url, params) {
27674    var k, popup, qs, v;
27675    if (params == null) {
27676      params = {};
27677    }
27678    popup = {
27679      width: 500,
27680      height: 350
27681    };
27682    popup.top = (screen.height / 2) - (popup.height / 2);
27683    popup.left = (screen.width / 2) - (popup.width / 2);
27684    qs = ((function() {
27685      var _results;
27686      _results = [];
27687      for (k in params) {
27688        v = params[k];
27689        _results.push("" + k + "=" + (this.encode(v)));
27690      }
27691      return _results;
27692    }).call(this)).join('&');
27693    if (qs) {
27694      qs = "?" + qs;
27695    }
27696    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=" 
27696+ popup.width + ",height=" + popup.height);
27697  };
27698
27699  return ShareUtils;
27700
27701})();
27702var Share,
27703  __hasProp = {}.hasOwnProperty,
27704  __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; };
27705
27706Share = (function(_super) {
27707  __extends(Share, _super);
27708
27709  function Share(element, options) {
27710    this.element = element;
27711    this.el = {
27712      head: document.getElementsByTagName('head')[0],
27713      body: document.getElementsByTagName('body')[0]
27714    };
27715    this.config = {
27716      enabled_networks: 0,
27717      protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//',
27718      url: window.location.href.replace("&", "%26"),
27719      caption: null,
27720      title: this.default_title(),
27721      image: this.default_image(),
27722      description: this.default_description(),
27723      ui: {
27724        flyout: 'top center',
27725        button_text: 'Share',
27726        button_font: true,
27727        icon_font: true
27728      },
27729      networks: {
27730        twitter: {
27731          enabled: true,
27732          url: null,
27733          title: null,
27734          description: null
27735        },
27736        facebook: {
27737          enabled: true,
27738          load_sdk: true,
27739          url: null,
27740          app_id: null,
27741          title: null,
27742          caption: null,
27743          description: null,
27744          image: null
27745        },
27746        threads: {
27747          enabled: true,
27748          url: null,
27749          title: null,
27750          description: null
27751        },
27752        bluesky: {
27753          enabled: true,
27754          url: null,
27755          title: null,
27756          description: null
27757        },
27758        pinterest: {
27759          enabled: true,
27760          url: null,
27761          image: null,
27762          description: null
27763        },
27764        reddit: {
27765          enabled: true,
27766          url: null,
27767          title: null
27768        },
27769        linkedin: {
27770          enabled: true,
27771          url: null,
27772          title: null,
27773          description: null
27774        },
27775        xing: {
27776          enabled: true,
27777          url: null,
27778          title: null,
27779          image: null,
27780          description: null
27781        },
27782        whatsapp: {
27783          enabled: true,
27784          title: null,
27785          url: null
27786        },
27787        email: {
27788          enabled: true,
27789          title: null,
27790          description: null,
27791          url: null
27792        }
27793      }
27794    };
27795    this.setup(element, options);
27796    return this;
27797  }
27798
27799  Share.prototype.setup = function(element, opts) {
27800    var index, instance, instances, _i, _len;
27801    instances = document.querySelectorAll(element);
27802    this.extend(this.config, opts, true);
27803    this.set_global_configuration();
27804    this.normalize_network_configuration();
27805    if (this.config.ui.icon_font) {
27806      this.inject_icons();
27807    }
27808    if (this.config.ui.button_font) {
27809      this.inject_fonts();
27810    }
27811    if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) {
27812      this.inject_facebook_sdk();
27813    }
27814    for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) {
27815      instance = instances[index];
27816      this.setup_instance(element, index);
27817    }
27818  };
27819
27820  Share.prototype.setup_instance = function(element, index) {
27821    var button, instance, label, network, networks, _i, _len, _results,
27822      _this = this;
27823    instance = document.querySelectorAll(element)[index];
27824    this.hide(instance);
27825    this.add_class(instance, "sharer-" + index);
27826    instance = document.querySelectorAll(element)[index];
27827    this.inject_css(instance);
27828    this.inject_html(instance);
27829    this.show(instance);
27830    label = instance.getElementsByTagName("label")[0];
27831    button = instance.getElementsByClassName("social")[0];
27832    networks = instance.getElementsByTagName('li');
27833    this.add_class(button, "networks-" + this.config.enabled_networks);
27834    label.addEventListener("click", function() {
27835      return _this.event_toggle(button);
27836    });
27837    _this = this;
27838    _results = [];
27839    for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) {
27840      network = networks[index];
27841      _results.push(network.addEventListener("click", function() {
27842        _this.event_network(instance, this);
27843        return _this.event_close(button);
27844      }));
27845    }
27846    return _results;
27847  };
27848
27849  Share.prototype.event_toggle = function(button) {
27850    if (this.has_class(button, "active")) {
27851      return this.event_close(button);
27852    } else {
27853      return this.event_open(button);
27854    }
27855  };
27856
27857  Share.prototype.event_open = function(button) {
27858    if (this.has_class(button, "load")) {
27859      this.remove_class(button, "load");
27860    }
27861    return this.add_class(button, "active");
27862  };
27863
27864  Share.prototype.event_close = function(button) {
27865    return this.remove_class(button, "active");
27866  };
27867
27868  Share.prototype.event_network = function(instance, network) {
27869    var name;
27870    name = network.getAttribute("data-network");
27871    this.hook("before", name, instance);
27872    this["network_" + name]();
27873    return this.hook("after", name, instance);
27874  };
27875
27876  Share.prototype.open = function() {
27877    return this["public"]("open");
27878  };
27879
27880  Share.prototype.close = function() {
27881    return this["public"]("close");
27882  };
27883
27884  Share.prototype.toggle = function() {
27885    return this["public"]("toggle");
27886  };
27887
27888  Share.prototype["public"] = function(action) {
27889    var button, index, instance, _i, _len, _ref, _results;
27890    _ref = document.querySelectorAll(this.element);
27891    _results = [];
27892    for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
27893      instance = _ref[index];
27894      button = instance.getElementsByClassName("social")[0];
27895      _results.push(this["event_" + action](button));
27896    }
27897    return _results;
27898  };
27899
27900  Share.prototype.network_facebook = function() {
27901    if (this.config.networks.facebook.load_sdk) {
27902      if (!window.FB) {
27903        return console.error("The Facebook JS SDK hasn't loaded yet.");
27904      }
27905      return FB.ui({
27906        method: 'feed',
27907        name: this.config.networks.facebook.title,
27908        link: this.config.networks.facebook.url,
27909        picture: this.config.networks.facebook.image,
27910        caption: this.config.networks.facebook.caption,
27911        description: this.config.networks.facebook.description
27912      });
27913    } else {
27914      return this.popup('https://www.facebook.com/sharer/sharer.php', {
27915        u: this.config.networks.facebook.url
27916      });
27917    }
27918  };
27919
27920  Share.prototype.network_threads = function() {
27921    return this.popup('https://threads.net/intent/post', {
27922      text: this.config.networks.threads.title,
27923      url: this.config.networks.threads.url
27924    });
27925  };
27926
27927  Share.prototype.network_bluesky = function() {
27928    return this.popup('https://bsky.app/intent/compose', {
27929      text: this.config.networks.bluesky.title + ' ' + this.config.networks.bluesky.url
27930    });
27931  };
27932
27933  Share.prototype.network_twitter = function() {
27934    return this.popup('https://twitter.com/intent/tweet', {
27935      text: this.config.networks.twitter.title,
27936      url: this.config.networks.twitter.url
27937    });
27938  };
27939
27940  Share.prototype.network_pinterest = function() {
27941    return this.popup('https://www.pinterest.com/pin/create/button', {
27942      url: this.config.networks.pinterest.url,
27943      media: this.config.networks.pinterest.image,
27944      description: this.config.networks.pinterest.description
27945    });
27946  };
27947
27948  Share.prototype.network_linkedin = function() {
27949    return this.popup('https://www.linkedin.com/shareArticle', {
27950      url: this.config.networks.linkedin.url,
27951      title: this.config.networks.linkedin.title,
27952      summary: this.config.networks.linkedin.description
27953    });
27954  }
27955
27956  Share.prototype.network_xing = function() {
27957    return this.popup('https://www.xing.com/spi/shares/new', {
27958      url: this.config.networks.xing.url,
27959      image: this.config.networks.xing.image,
27960      title: this.config.networks.xing.title,
27961      summary: this.config.networks.xing.description
27962    });
27963  }
27964
27965  Share.prototype.network_whatsapp = function() {
27966    return this.popup('https://api.whatsapp.com/send', {
27967      text: this.config.networks.whatsapp.title + '%20' + this.config.networks.whatsapp.url,
27968    });
27969  }
27970
27971  Share.prototype.network_email = function() {
27972    return this.popup('mailto:', {
27973      subject: this.config.networks.email.title,
27974      body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description,
27975    });
27976  };
27977
27978  Share.prototype.inject_icons = function() {
27979  //  return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css");
27980  };
27981
27982  Share.prototype.inject_fonts = function() {
27983   // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text);
27984  };
27985
27986  Share.prototype.inject_stylesheet = function(url) {
27987    var link;
27988    if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) {
27989      link = document.createElement("link");
27990      link.setAttribute("rel", "stylesheet");
27991      link.setAttribute("href", url);
27992      return this.el.head.appendChild(link);
27993    }
27994  };
27995
27996  Share.prototype.inject_css = function(instance) {
27997    var css, meta, selector, style;
27998    selector = "." + (instance.getAttribute('class').split(" ").join("."));
27999    if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) {
28000      this.config.selector = selector;
28001      css = getStyles(this.config);
28002      style = document.createElement("style");
28003      style.type = "text/css";
28004      if (style.styleSheet) {
28005        style.styleSheet.cssText = css;
28006      } else {
28007        style.appendChild(document.createTextNode(css));
28008      }
28009      this.el.head.appendChild(style);
28010      delete this.config.selector;
28011      meta = document.createElement("meta");
28012      meta.setAttribute("name", "sharer" + selector);
28013      return this.el.head.appendChild(meta);
28014    }
28015  };
28016
28017  Share.prototype.inject_html = function(instance) {
28018    // 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>";
28019    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>";
28020  };
28021
28022  Share.prototype.inject_facebook_sdk = function() {
28023    var fb_root, script;
28024    if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) {
28025      script = document.createElement("script");
28026      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')";
28027      fb_root = document.createElement("div");
28028      fb_root.id = "fb-root";
28029      this.el.body.appendChild(fb_root);
28030      return this.el.body.appendChild(script);
28031    }
28032  };
28033
28034  Share.prototype.hook = function(type, network, instance) {
28035    var fn, opts;
28036    fn = this.config.networks[network][type];
28037    if (typeof fn === "function") {
28038      opts = fn.call(this.config.networks[network], instance);
28039      if (opts !== void 0) {
28040        opts = this.normalize_filter_config_updates(opts);
28041        this.extend(this.config.networks[network], opts, true);
28042        this.normalize_network_configuration();
28043      }
28044    }
28045  };
28046
28047  Share.prototype.default_title = function() {
28048    var content;
28049    if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) {
28050      return encodeURIComponent(content.getAttribute('content'));
28051    } else if (content = document.querySelector('title')) {
28052      return encodeURIComponent(content.innerText);
28053    }
28054  };
28055
28056  Share.prototype.default_image = function() {
28057    var content;
28058    if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) {
28059      return content.getAttribute('content');
28060    }
28061  };
28062
28063  Share.prototype.default_description = function() {
28064    var content;
28065    if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) {
28066      return encodeURIComponent(content.getAttribute('content'));
28067    } else {
28068      return '';
28069    }
28070  };
28071
28072  Share.prototype.set_global_configuration = function() {
28073    var display, network, option, options, _ref, _results;
28074    _ref = this.config.networks;
28075    _results = [];
28076    for (network in _ref) {
28077      options = _ref[network];
28078      for (option in options) {
28079        if (this.config.networks[network][option] == null) {
28080          this.config.networks[network][option] = this.config[option];
28081        }
28082      }
28083      if (this.config.networks[network].enabled) {
28084        display = 'block';
28085        this.config.enabled_networks += 1;
28086      } else {
28087        display = 'none';
28088      }
28089      _results.push(this.config.networks[network].display = display);
28090    }
28091    return _results;
28092  };
28093
28094  Share.prototype.normalize_network_configuration = function() {
28095    if (!this.config.networks.facebook.app_id) {
28096      this.config.networks.facebook.load_sdk = false;
28097    }
28098    if (!this.is_encoded(this.config.networks.twitter.description)) {
28099      this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description);
28100    }
28101    if (typeof this.config.networks.facebook.app_id === 'number') {
28102      return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString();
28103    }
28104  };
28105
28106  Share.prototype.normalize_filter_config_updates = function(opts) {
28107    if (this.config.networks.facebook.app_id !== opts.app_id) {
28108      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.");
28109      delete opts.app_id;
28110    }
28111    if (this.config.networks.facebook.load_sdk !== opts.load_sdk) {
28112      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.");
28113      delete opts.app_id;
28114    }
28115    return opts;
28116  };
28117
28118  return Share;
28119
28120})(ShareUtils);
28121 return Share;
28122});
28123
28124// Generated by CoffeeScript 1.9.2
28125
28126// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net
28127
28128(function() {
28129  var $, win;
28130
28131  $ = this.jQuery || window.jQuery;
28132
28133  win = $(window);
28134
28135  $.fn.stick_in_parent = function(opts) {
28136    var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class;
28137    if (opts == null) {
28138      opts = {};
28139    }
28140    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;
28141    if (offset_top == null) {
28142      offset_top = 0;
28143    }
28144    if (parent_selector == null) {
28145      parent_selector = void 0;
28146    }
28147    if (inner_scrolling == null) {
28148      inner_scrolling = true;
28149    }
28150    if (sticky_class == null) {
28151      sticky_class = "is_stuck";
28152    }
28153    doc = $(document);
28154    if (enable_bottoming == null) {
28155      enable_bottoming = true;
28156    }
28157    outer_width = function(el) {
28158      var _el, computed, w;
28159      if (window.getComputedStyle) {
28160        _el = el[0];
28161        computed = window.getComputedStyle(el[0]);
28162        w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right"));
28163        if (computed.getPropertyValue("box-sizing") !== "border-box") {
28164          w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right"));
28165        }
28166        return w;
28167      } else {
28168        return el.outerWidth(true);
28169      }
28170    };
28171    fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) {
28172      var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick;
28173      if (elm.data("sticky_kit")) {
28174        return;
28175      }
28176      elm.data("sticky_kit", true);
28177      last_scroll_height = doc.height();
28178      parent = elm.parent();
28179      if (parent_selector != null) {
28180        parent = parent.closest(parent_selector);
28181      }
28182      if (!parent.length) {
28183        throw "failed to find stick parent";
28184      }
28185      fixed = false;
28186      bottomed = false;
28187      spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />");
28188      if (spacer) {
28189        spacer.css('position', elm.css('position'));
28190      }
28191      recalc = function() {
28192        var border_top, padding_top, restore;
28193        if (detached) {
28194          return;
28195        }
28196        last_scroll_height = doc.height();
28197        border_top = parseInt(parent.css("border-top-width"), 10);
28198        padding_top = parseInt(parent.css("padding-top"), 10);
28199        padding_bottom = parseInt(parent.css("padding-bottom"), 10);
28200        parent_top = parent.offset().top + border_top + padding_top;
28201        parent_height = parent.height();
28202        if (fixed) {
28203          fixed = false;
vendor: 6,068 bytes, lines 28204-28398
28204          bottomed = false;
28205          if (manual_spacer == null) {
28206            elm.insertAfter(spacer);
28207            spacer.detach();
28208          }
28209          elm.css({
28210            position: "",
28211            top: "",
28212            width: "",
28213            bottom: ""
28214          }).removeClass(sticky_class);
28215          restore = true;
28216        }
28217        top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top;
28218        height = elm.outerHeight(true);
28219        el_float = elm.css("float");
28220        if (spacer) {
28221          spacer.css({
28222            width: outer_width(elm),
28223            height: height,
28224            display: elm.css("display"),
28225            "vertical-align": elm.css("vertical-align"),
28226            "float": el_float
28227          });
28228        }
28229        if (restore) {
28230          return tick();
28231        }
28232      };
28233      recalc();
28234      if (height === parent_height) {
28235        return;
28236      }
28237      last_pos = void 0;
28238      offset = offset_top;
28239      recalc_counter = recalc_every;
28240      tick = function() {
28241        var css, delta, recalced, scroll, will_bottom, win_height;
28242        if (detached) {
28243          return;
28244        }
28245        recalced = false;
28246        if (recalc_counter != null) {
28247          recalc_counter -= 1;
28248          if (recalc_counter <= 0) {
28249            recalc_counter = recalc_every;
28250            recalc();
28251            recalced = true;
28252          }
28253        }
28254        if (!recalced && doc.height() !== last_scroll_height) {
28255          recalc();
28256          recalced = true;
28257        }
28258        scroll = win.scrollTop();
28259        if (last_pos != null) {
28260          delta = scroll - last_pos;
28261        }
28262        last_pos = scroll;
28263        if (fixed) {
28264          if (enable_bottoming) {
28265            will_bottom = scroll + height + offset > parent_height + parent_top;
28266            if (bottomed && !will_bottom) {
28267              bottomed = false;
28268              elm.css({
28269                position: "fixed",
28270                bottom: "",
28271                top: offset
28272              }).trigger("sticky_kit:unbottom");
28273            }
28274          }
28275          if (scroll < top) {
28276            fixed = false;
28277            offset = offset_top;
28278            if (manual_spacer == null) {
28279              if (el_float === "left" || el_float === "right") {
28280                elm.insertAfter(spacer);
28281              }
28282              spacer.detach();
28283            }
28284            css = {
28285              position: "",
28286              width: "",
28287              top: ""
28288            };
28289            elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick");
28290          }
28291          if (inner_scrolling) {
28292            win_height = win.height();
28293            if (height + offset_top > win_height) {
28294              if (!bottomed) {
28295                offset -= delta;
28296                offset = Math.max(win_height - height, offset);
28297                offset = Math.min(offset_top, offset);
28298                if (fixed) {
28299                  elm.css({
28300                    top: offset + "px"
28301                  });
28302                }
28303              }
28304            }
28305          }
28306        } else {
28307          if (scroll > top) {
28308            fixed = true;
28309            css = {
28310              position: "fixed",
28311              top: offset
28312            };
28313            css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px";
28314            elm.css(css).addClass(sticky_class);
28315            if (manual_spacer == null) {
28316              elm.after(spacer);
28317              if (el_float === "left" || el_float === "right") {
28318                spacer.append(elm);
28319              }
28320            }
28321            elm.trigger("sticky_kit:stick");
28322          }
28323        }
28324        if (fixed && enable_bottoming) {
28325          if (will_bottom == null) {
28326            will_bottom = scroll + height + offset > parent_height + parent_top;
28327          }
28328          if (!bottomed && will_bottom) {
28329            bottomed = true;
28330            if (parent.css("position") === "static") {
28331              parent.css({
28332                position: "relative"
28333              });
28334            }
28335            return elm.css({
28336              position: "absolute",
28337              bottom: padding_bottom,
28338              top: "auto"
28339            }).trigger("sticky_kit:bottom");
28340          }
28341        }
28342      };
28343      recalc_and_tick = function() {
28344        recalc();
28345        return tick();
28346      };
28347      detach = function() {
28348        detached = true;
28349        win.off("touchmove", tick);
28350        win.off("scroll", tick);
28351        win.off("resize", recalc_and_tick);
28352        $(document.body).off("sticky_kit:recalc", recalc_and_tick);
28353        elm.off("sticky_kit:detach", detach);
28354        elm.removeData("sticky_kit");
28355        elm.css({
28356          position: "",
28357          bottom: "",
28358          top: "",
28359          width: ""
28360        });
28361        parent.position("position", "");
28362        if (fixed) {
28363          if (manual_spacer == null) {
28364            if (el_float === "left" || el_float === "right") {
28365              elm.insertAfter(spacer);
28366            }
28367            spacer.remove();
28368          }
28369          return elm.removeClass(sticky_class);
28370        }
28371      };
28372      win.on("touchmove", tick);
28373      win.on("scroll", tick);
28374      win.on("resize", recalc_and_tick);
28375      $(document.body).on("sticky_kit:recalc", recalc_and_tick);
28376      elm.on("sticky_kit:detach", detach);
28377      return setTimeout(tick, 0);
28378    };
28379    for (i = 0, len = this.length; i < len; i++) {
28380      elm = this[i];
28381      fn($(elm));
28382    }
28383    return this;
28384  };
28385
28386}).call(this);
28387/* ==========================================================================
28388 * bootstrap-tab-history.js
28389 * Author: Michael Narayan <[email protected]>
28390 * Repository: https://github.com/mnarayan01/bootstrap-tab-history/
28391 * ==========================================================================
28392 * Licensed under the Apache License, Version 2.0 (the "License"); you may
28393 * not use this file except in compliance with the License. You may obtain a
28394 * copy of the License at
28395 *
28396 * http://www.apache.org/licenses/LICENSE-2.0
28397 *
28398 * Unless required by applicable law or agreed to in writing, softw
28398are
28399 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
28400 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
28401 * License for the specific language governing permissions and limitations
28402 * under the License.
28403 * ========================================================================== */
28404
28405/* ========================================================================== */
28406/* JSHint directives                                                          */
28407/*                                                                            */
28408/* global BootstrapTabHistory: true                                           */
28409/*                                                                            */
28410/* global document                                                            */
28411/* global jQuery                                                              */
28412/* global history                                                             */
28413/* global window                                                              */
28414/* ========================================================================== */
28415
28416/**
28417 * Integrate [HTML5 history state tracking](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history)
28418 * with [`bootstrap/tab.js`](http://getbootstrap.com/javascript/#tabs). To enable tracking on a tab element, simply set
28419 * the `data-tab-history` attribute to true (or a string denoting a tab grouping).
28420 *
28421 * See the README for additional information.
28422 *
28423 * Functionality based upon bootstrap/tab.js v3.1.0; reference it when making any changes.
28424 */
28425
28426BootstrapTabHistory = {
28427  options: {
28428    /**
28429     * When the anchor portion of the URI is used to activate a tab, scroll down to the given offset, rather than the
28430     * element with the given `id` attribute. Set to null to disable. Only relevant if showTabsBasedOnAnchor is true.
28431     *
28432     * May be overriden on a per-element basis by the attribute `data-tab-history-anchor-y-offset`.
28433     *
28434     * @public
28435     * @type {?number}
28436     */
28437    defaultAnchorYOffset: 0,
28438    /**
28439     * Either 'push' or 'replace', for whether to use `history.pushState` or `history.replaceState`, resp.
28440     *
28441     * May be overriden on a per-element basis by the attribute `data-tab-history-changer`.
28442     *
28443     * @public
28444     * @type {string}
28445     */
28446    defaultChanger: 'replace',
28447    /**
28448     * If true, update the URL in onShownTab in the calls to `history.pushState` and `history.replaceState`. Otherwise,
28449     * `null` is passed as the third parameter to these calls.
28450     *
28451     * May be overriden on a per-element basis by the attribute `data-tab-history-update-url`.
28452     *
28453     * @public
28454     * @type {boolean}
28455     */
28456    defaultUpdateURL: false,
28457    /**
28458     * Should the anchor portion of the loaded URI be used to activate a single tab if no history was present on page
28459     * load.
28460     *
28461     * @public
28462     * @type {boolean}
28463     */
28464    showTabsBasedOnAnchor: true
28465  }
28466};
28467
28468(function () {
28469  'use strict';
28470
28471  jQuery(function () {
28472    if(history && history.pushState && history.replaceState) {
28473      var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory;
28474
28475      if(bootstrapTabHistory) {
28476        showTabsBasedOnState(bootstrapTabHistory);
28477      } else {
28478        showTabsBasedOnAnchor();
28479      }
28480
28481      backfillHistoryState();
28482
28483      jQuery(document).on('shown.bs.tab show.bs.collapse', onShownTab);
28484      jQuery(window).on('popstate', onPopState);
28485    } else {
28486      showTabsBasedOnAnchor();
28487    }
28488  });
28489
28490  /**
28491   * Used to prevent onShownTab from registering shown events that we triggered via showTabsBasedOnState.
28492   *
28493   * @type {boolean}
28494   */
28495  var showingTabsBasedOnState = false;
28496
28497  /**
28498   * Used to update `history.state` to reflect the default active tabs on initial page load. This supports proper
28499   * `history.back` handling when `data-tab-history-update-url` is true.
28500   */
28501  function backfillHistoryState() {
28502    var newState = null;
28503
28504    jQuery('li.active > [data-tab-history], .panel-title.active [data-tab-history]').each(function () {//edited by Uncode
28505      var $activeTabElement = jQuery(this);
28506      var selector = getTabSelector($activeTabElement);
28507
28508      if(selector) {
28509        var tabGroup = getTabGroup($activeTabElement);
28510
28511        if(tabGroup) {
28512          newState = createNewHistoryState(newState || history.state, tabGroup, selector);
28513        }
28514      }
28515    });
28516
28517    if(newState) {
28518      history.replaceState(newState, '', null);
28519    }
28520  }
28521
28522  /**
28523   * Clone the existing state, ensure its bootstrapTabHistory attribute is an Object, and add the provided tabGroup to
28524   * said bootstrapTabHistory attribute.
28525   *
28526   * @param {?object} existingState
28527   * @param {!string} tabGroup
28528   * @param {!string} selector
28529   * @returns {!object}
28530   */
28531  function createNewHistoryState(existingState, tabGroup, selector) {
28532    // Clone history.state and ensure it has a bootstrapTabHistory entry.
28533    var newState = jQuery.extend(true, {}, existingState, {
28534      bootstrapTabHistory: {}
28535    });
28536
28537    newState.bootstrapTabHistory[tabGroup] = selector;
28538
28539    return newState;
28540  }
28541
28542  /**
28543   * @param {jQuery} $tab
28544   * @returns {?string}
28545   */
28546  function getTabGroup($tab) {
28547    return parseTruthyAttributeValue($tab.data('tab-history'));
28548  }
28549
28550  /**
28551   * @param {jQuery} $tab
28552   * @returns {?string}
28553   */
28554  function getTabSelector($tab) {
28555    return $tab.data('target') || $tab.attr('href');
28556  }
28557
28558  /**
28559   * Receives the `shown.bs.tab` event. Updates `history.state` as appropriate.
28560   *
28561   * @param {jQuery.Event} shownEvt
28562   */
28563  function onShownTab(shownEvt) {
28564    if(!showingTabsBasedOnState) {
28565      var $activatedTab = jQuery(shownEvt.target);
28566      if ( $activatedTab.hasClass('panel-collapse') )
28567        $activatedTab = $activatedTab.closest('.panel').find('a');
28568      var selector = getTabSelector($activatedTab);
28569
28570      if(selector) {
28571        var tabGroup = getTabGroup($activatedTab);
28572
28573        if(tabGroup) {
28574          var historyChanger = $activatedTab.data('tab-history-changer') || BootstrapTabHistory.options.defaultChanger;
28575          var newState = createNewHistoryState(history.state, tabGroup, selector);
28576          var updateURL = (function ($activatedTab) {
28577            if(selector[0] === '#') {
28578              var elementUpdateURLOption = parseTruthyAttributeValue($activatedTab.data('tab-history-update-url'));
28579
28580              if(elementUpdateURLOption === undefined) {
28581                return BootstrapTabHistory.options.defaultUpdateURL;
28582              } else {
28583                return elementUpdateURLOption;
28584              }
28585            } else {
28586              return false;
28587            }
28588          })($activatedTab);
28589
28590          switch(historyChanger) {
28591            case 'push':
28592              history.pushState(newState, '', updateURL ? selector : null);
28593              break;
28594            case 'replace':
28595              history.replaceState(newState, '', updateURL ? selector : null);
28596              break;
28597            default:
28598              throw new Error('Unknown tab-history-changer: ' + historyChanger);
28599          }
28600        }
28601      }
28602    }
28603  }
28604
28605  /**
28606   * Receives the `popstate` event. Shows tabs based on the value of `history.state` as appropriate.
28607   */
28608  function onPopState() {
28609    var bootstrapTabHistory = history.state && history.state.bootstrapTabHistory;
28610
28611    if(bootstrapTabHistory) {
28612      showTabsBasedOnState(bootstrapTabHistory);
28613    }
28614  }
28615
28616  /**
28617   * Returns the given value, _unless_ that value is an empty string, in which case `true` is returned.
28618   *
28619   * Rationale: HAML data attributes which are set to `true` are rendered as a blank string.
28620   *
28621   * @param {*} value
28622   * @returns {*}
28623   */
28624  function parseTruthyAttributeValue(value) {
28625    if(value) {
28626      return value;
28627    } else if(value === '') {
28628      return true;
28629    } else {
28630      return value;
28631    }
28632  }
28633
28634  /**
28635   * Show tabs based upon the anchor component of `window.location`.
28636   */
28637  function showTabsBasedOnAnchor() {
28638    if(BootstrapTabHistory.options.showTabsBasedOnAnchor) {
28639      var anchor = window.location && window.location.hash;
28640
28641      if(anchor) {
28642        var $tabElement = showTabForSelector(anchor);
28643
28644        if($tabElement && window.addEventListener && window.removeEventListener) {
28645          var anchorYOffset = (function ($tabElement) {
28646            var elementSetting = $tabElement.data('tab-history-anchor-y-offset');
28647
28648            if(elementSetting === undefined) {
28649              return BootstrapTabHistory.options.defaultAnchorYOffset;
28650            } else {
28651              return elementSetting;
28652            }
28653          })($tabElement);
28654
28655          // HACK: This prevents scrolling to the tab on page load. This relies on the fact that we should never get
28656          //   here on `history.forward`, `history.back`, or `location.reload`, since in all those situations the
28657          //   `history.state` object should have been used (unless the browser did not support the modern History API).
28658          if(anchorYOffset || anchorYOffset === 0) {
28659            var scrollListener = function resetAnchorScroll () {
28660              window.removeEventListener('scroll', scrollListener);
28661              window.scrollTo(0, anchorYOffset);
28662            };
28663
28664            window.addEventListener('scroll', scrollListener);
28665          }
28666        }
28667      }
28668    }
28669  }
28670
28671  /**
28672   * Show a tab which corresponds to the provided selector.
28673   *
28674   * @param {string} selector - A CSS selector.
28675   * @returns {?jQuery} - The tab which was found to show (even if said tab was already active).
28676   */
28677  function showTabForSelector(selector) {
28678    var $tabElement = (function (selector) {
28679      var $ret = null;
28680
28681      jQuery('[data-toggle="tab"], [data-toggle="pill"], [data-toggle="collapse"]').each(function () {
28682        var $potentialTab = jQuery(this);
28683
28684        if(($potentialTab.attr('href') === selector || $potentialTab.data('target') === selector ) && getTabGroup($potentialTab)) {
28685          $ret = $potentialTab;
28686          return false;
vendor: 43,483 bytes, lines 28687-29903
28687        } else {
28688         return null;
28689        }
28690      });
28691
28692      return $ret;
28693    })(selector);
28694
28695    if($tabElement) {
28696      if ( !$tabElement.parent().hasClass('active') ) {
28697        $tabElement.trigger('click');
28698      }
28699      //$tabElement.tab('show');
28700    }
28701
28702    return $tabElement;
28703  }
28704
28705  /**
28706   * Iterate through the provided set of tab tab groups, showing the tabs based on the stored selectors.
28707   *
28708   * @param {object} bootstrapTabHistory - Each of the values is passed to showTabForSelector; the keys are actually irrelevant.
28709   */
28710  function showTabsBasedOnState(bootstrapTabHistory) {
28711    showingTabsBasedOnState = true;
28712
28713    try {
28714      for(var k in bootstrapTabHistory) {
28715        if(bootstrapTabHistory.hasOwnProperty(k)) {
28716          showTabForSelector(bootstrapTabHistory[k]);
28717        }
28718      }
28719    } finally {
28720      showingTabsBasedOnState = false;
28721    }
28722  }
28723})();
28724
28725/*!
28726 * justifiedGallery - v3.8.1
28727 * http://miromannino.github.io/Justified-Gallery/
28728 * Copyright (c) 2020 Miro Mannino
28729 * Licensed under the MIT license.
28730 */
28731(function (factory) {
28732  if (typeof define === 'function' && define.amd) {
28733    // AMD. Register as an anonymous module.
28734    define(['jquery'], factory);
28735  } else if (typeof module === 'object' && module.exports) {
28736    // Node/CommonJS
28737    module.exports = function (root, jQuery) {
28738      if (jQuery === undefined) {
28739        // require('jQuery') returns a factory that requires window to
28740        // build a jQuery instance, we normalize how we use modules
28741        // that require this pattern but the window provided is a noop
28742        // if it's defined (how jquery works)
28743        if (typeof window !== 'undefined') {
28744          jQuery = require('jquery');
28745        }
28746        else {
28747          jQuery = require('jquery')(root);
28748        }
28749      }
28750      factory(jQuery);
28751      return jQuery;
28752    };
28753  } else {
28754    // Browser globals
28755    factory(jQuery);
28756  }
28757}(function ($) {
28758
28759  /**
28760   * Justified Gallery controller constructor
28761   *
28762   * @param $gallery the gallery to build
28763   * @param settings the settings (the defaults are in JustifiedGallery.defaults)
28764   * @constructor
28765   */
28766  var JustifiedGallery = function ($gallery, settings) {
28767
28768    this.settings = settings;
28769    this.checkSettings();
28770
28771    this.imgAnalyzerTimeout = null;
28772    this.entries = null;
28773    this.buildingRow = {
28774      entriesBuff: [],
28775      width: 0,
28776      height: 0,
28777      aspectRatio: 0
28778    };
28779    this.lastFetchedEntry = null;
28780    this.lastAnalyzedIndex = -1;
28781    this.yield = {
28782      every: 2, // do a flush every n flushes (must be greater than 1)
28783      flushed: 0 // flushed rows without a yield
28784    };
28785    this.border = settings.border >= 0 ? settings.border : settings.margins;
28786    this.maxRowHeight = this.retrieveMaxRowHeight();
28787    this.suffixRanges = this.retrieveSuffixRanges();
28788    this.offY = this.border;
28789    this.rows = 0;
28790    this.spinner = {
28791      phase: 0,
28792      timeSlot: 150,
28793      $el: $('<div class="jg-spinner"><span></span><span></span><span></span></div>'),
28794      intervalId: null
28795    };
28796    this.scrollBarOn = false;
28797    this.checkWidthIntervalId = null;
28798    this.galleryWidth = $gallery.width();
28799    this.$gallery = $gallery;
28800
28801  };
28802
28803  /** @returns {String} the best suffix given the width and the height */
28804  JustifiedGallery.prototype.getSuffix = function (width, height) {
28805    var longestSide, i;
28806    longestSide = (width > height) ? width : height;
28807    for (i = 0; i < this.suffixRanges.length; i++) {
28808      if (longestSide <= this.suffixRanges[i]) {
28809        return this.settings.sizeRangeSuffixes[this.suffixRanges[i]];
28810      }
28811    }
28812    return this.settings.sizeRangeSuffixes[this.suffixRanges[i - 1]];
28813  };
28814
28815  /**
28816   * Remove the suffix from the string
28817   *
28818   * @returns {string} a new string without the suffix
28819   */
28820  JustifiedGallery.prototype.removeSuffix = function (str, suffix) {
28821    return str.substring(0, str.length - suffix.length);
28822  };
28823
28824  /**
28825   * @returns {boolean} a boolean to say if the suffix is contained in the str or not
28826   */
28827  JustifiedGallery.prototype.endsWith = function (str, suffix) {
28828    return str.indexOf(suffix, str.length - suffix.length) !== -1;
28829  };
28830
28831  /**
28832   * Get the used suffix of a particular url
28833   *
28834   * @param str
28835   * @returns {String} return the used suffix
28836   */
28837  JustifiedGallery.prototype.getUsedSuffix = function (str) {
28838    for (var si in this.settings.sizeRangeSuffixes) {
28839      if (this.settings.sizeRangeSuffixes.hasOwnProperty(si)) {
28840        if (this.settings.sizeRangeSuffixes[si].length === 0) continue;
28841        if (this.endsWith(str, this.settings.sizeRangeSuffixes[si])) return this.settings.sizeRangeSuffixes[si];
28842      }
28843    }
28844    return '';
28845  };
28846
28847  /**
28848   * Given an image src, with the width and the height, returns the new image src with the
28849   * best suffix to show the best quality thumbnail.
28850   *
28851   * @returns {String} the suffix to use
28852   */
28853  JustifiedGallery.prototype.newSrc = function (imageSrc, imgWidth, imgHeight, image) {
28854    var newImageSrc;
28855
28856    if (this.settings.thumbnailPath) {
28857      newImageSrc = this.settings.thumbnailPath(imageSrc, imgWidth, imgHeight, image);
28858    } else {
28859      var matchRes = imageSrc.match(this.settings.extension);
28860      var ext = (matchRes !== null) ? matchRes[0] : '';
28861      newImageSrc = imageSrc.replace(this.settings.extension, '');
28862      newImageSrc = this.removeSuffix(newImageSrc, this.getUsedSuffix(newImageSrc));
28863      newImageSrc += this.getSuffix(imgWidth, imgHeight) + ext;
28864    }
28865
28866    return newImageSrc;
28867  };
28868
28869  /**
28870   * Shows the images that is in the given entry
28871   *
28872   * @param $entry the entry
28873   * @param callback the callback that is called when the show animation is finished
28874   */
28875  JustifiedGallery.prototype.showImg = function ($entry, callback) {
28876    if (this.settings.cssAnimation) {
28877      $entry.addClass('jg-entry-visible');
28878      if (callback) callback();
28879    } else {
28880      $entry.stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
28881      $entry.find(this.settings.imgSelector).stop().fadeTo(this.settings.imagesAnimationDuration, 1.0, callback);
28882    }
28883  };
28884
28885  /**
28886   * Extract the image src form the image, looking from the 'safe-src', and if it can't be found, from the
28887   * 'src' attribute. It saves in the image data the 'jg.originalSrc' field, with the extracted src.
28888   *
28889   * @param $image the image to analyze
28890   * @returns {String} the extracted src
28891   */
28892  JustifiedGallery.prototype.extractImgSrcFromImage = function ($image) {
28893    var imageSrc = $image.data('safe-src');
28894    var imageSrcLoc = 'data-safe-src';
28895    // Begin Uncode edit
28896    if (typeof imageSrc === 'undefined') {
28897    	var imageCurrentSrc = $image[0].currentSrc;
28898    	if (imageCurrentSrc) {
28899    		imageSrc = imageCurrentSrc;
28900    	} else {
28901    		imageSrc = $image.attr('src');
28902    	}
28903		imageSrcLoc = 'src';
28904    }
28905    // End Uncode edit
28906    $image.data('jg.originalSrc', imageSrc); // this is saved for the destroy method
28907    $image.data('jg.src', imageSrc); // this will change overtime
28908    $image.data('jg.originalSrcLoc', imageSrcLoc); // this is saved for the destroy method
28909    return imageSrc;
28910  };
28911
28912  /** @returns {jQuery} the image in the given entry */
28913  JustifiedGallery.prototype.imgFromEntry = function ($entry) {
28914    var $img = $entry.find(this.settings.imgSelector);
28915    if ($img.length === 0) $img = $entry.find('.t-entry-visual-cont img');//hacked by Uncode
28916    return $img.length === 0 ? null : $img;
28917  };
28918
28919  /** @returns {jQuery} the caption in the given entry */
28920  JustifiedGallery.prototype.captionFromEntry = function ($entry) {
28921    var $caption = $entry.find('> .jg-caption');
28922    return $caption.length === 0 ? null : $caption;
28923  };
28924
28925  /**
28926   * Display the entry
28927   *
28928   * @param {jQuery} $entry the entry to display
28929   * @param {int} x the x position where the entry must be positioned
28930   * @param y the y position where the entry must be positioned
28931   * @param imgWidth the image width
28932   * @param imgHeight the image height
28933   * @param rowHeight the row height of the row that owns the entry
28934   */
28935  JustifiedGallery.prototype.displayEntry = function ($entry, x, y, imgWidth, imgHeight, rowHeight) {
28936    $entry.width(imgWidth);
28937    $entry.height(Math.floor(rowHeight));//hacked by Uncode
28938    $entry.css('top', Math.floor(y));//hacked by Uncode
28939    $entry.css('left', x);
28940
28941    var $image = this.imgFromEntry($entry);
28942    if ($image !== null) {
28943      $image.css('width', imgWidth);
28944      $image.css('height', imgHeight);
28945      $image.css('margin-left', - imgWidth / 2);
28946      $image.css('margin-top', - imgHeight / 2);
28947
28948      // Image reloading for an high quality of thumbnails
28949      var imageSrc = $image.data('jg.src');
28950      if (imageSrc) {
28951        imageSrc = this.newSrc(imageSrc, imgWidth, imgHeight, $image[0]);
28952
28953        $image.one('error', function () {
28954           this.resetImgSrc($image); //revert to the original thumbnail
28955        });
28956
28957        var loadNewImage = function () {
28958          // if (imageSrc !== newImageSrc) {
28959            $image.attr('src', imageSrc);
28960          // }
28961        };
28962
28963        if ($entry.data('jg.loaded') === 'skipped' && imageSrc) {
28964          this.onImageEvent(imageSrc, (function() {
28965            this.showImg($entry, loadNewImage); //load the new image after the fadeIn
28966            $entry.data('jg.loaded', true);
28967          }).bind(this));
28968        } else {
28969          this.showImg($entry, loadNewImage); //load the new image after the fadeIn
28970        }
28971
28972      }
28973
28974    } else {
28975      this.showImg($entry);
28976    }
28977
28978    this.displayEntryCaption($entry);
28979  };
28980
28981  /**
28982   * Display the entry caption. If the caption element doesn't exists, it creates the caption using the 'alt'
28983   * or the 'title' attributes.
28984   *
28985   * @param {jQuery} $entry the entry to process
28986   */
28987  JustifiedGallery.prototype.displayEntryCaption = function ($entry) {
28988    var $image = this.imgFromEntry($entry);
28989    if ($image !== null && this.settings.captions) {
28990      var $imgCaption = this.captionFromEntry($entry);
28991
28992      // Create it if it doesn't exists
28993      if ($imgCaption === null) {
28994        var caption = $image.attr('alt');
28995        if (!this.isValidCaption(caption)) caption = $entry.attr('title');
28996        if (this.isValidCaption(caption)) { // Create only we found something
28997          $imgCaption = $('<div class="jg-caption">' + caption + '</div>');
28998          $entry.append($imgCaption);
28999          $entry.data('jg.createdCaption', true);
29000        }
29001      }
29002
29003      // Create events (we check again the $imgCaption because it can be still inexistent)
29004      if ($imgCaption !== null) {
29005        if (!this.settings.cssAnimation) $imgCaption.stop().fadeTo(0, this.settings.captionSettings.nonVisibleOpacity);
29006        this.addCaptionEventsHandlers($entry);
29007      }
29008    } else {
29009      this.removeCaptionEventsHandlers($entry);
29010    }
29011  };
29012
29013  /**
29014   * Validates the caption
29015   *
29016   * @param caption The caption that should be validated
29017   * @return {boolean} Validation result
29018   */
29019  JustifiedGallery.prototype.isValidCaption = function (caption) {
29020    return (typeof caption !== 'undefined' && caption.length > 0);
29021  };
29022
29023  /**
29024   * The callback for the event 'mouseenter'. It assumes that the event currentTarget is an entry.
29025   * It shows the caption using jQuery (or using CSS if it is configured so)
29026   *
29027   * @param {Event} eventObject the event object
29028   */
29029  JustifiedGallery.prototype.onEntryMouseEnterForCaption = function (eventObject) {
29030    var $caption = this.captionFromEntry($(eventObject.currentTarget));
29031    if (this.settings.cssAnimation) {
29032      $caption.addClass('jg-caption-visible').removeClass('jg-caption-hidden');
29033    } else {
29034      $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
29035        this.settings.captionSettings.visibleOpacity);
29036    }
29037  };
29038
29039  /**
29040   * The callback for the event 'mouseleave'. It assumes that the event currentTarget is an entry.
29041   * It hides the caption using jQuery (or using CSS if it is configured so)
29042   *
29043   * @param {Event} eventObject the event object
29044   */
29045  JustifiedGallery.prototype.onEntryMouseLeaveForCaption = function (eventObject) {
29046    var $caption = this.captionFromEntry($(eventObject.currentTarget));
29047    if (this.settings.cssAnimation) {
29048      $caption.removeClass('jg-caption-visible').removeClass('jg-caption-hidden');
29049    } else {
29050      $caption.stop().fadeTo(this.settings.captionSettings.animationDuration,
29051        this.settings.captionSettings.nonVisibleOpacity);
29052    }
29053  };
29054
29055  /**
29056   * Add the handlers of the entry for the caption
29057   *
29058   * @param $entry the entry to modify
29059   */
29060  JustifiedGallery.prototype.addCaptionEventsHandlers = function ($entry) {
29061    var captionMouseEvents = $entry.data('jg.captionMouseEvents');
29062    if (typeof captionMouseEvents === 'undefined') {
29063      captionMouseEvents = {
29064        mouseenter: $.proxy(this.onEntryMouseEnterForCaption, this),
29065        mouseleave: $.proxy(this.onEntryMouseLeaveForCaption, this)
29066      };
29067      $entry.on('mouseenter', undefined, undefined, captionMouseEvents.mouseenter);
29068      $entry.on('mouseleave', undefined, undefined, captionMouseEvents.mouseleave);
29069      $entry.data('jg.captionMouseEvents', captionMouseEvents);
29070    }
29071  };
29072
29073  /**
29074   * Remove the handlers of the entry for the caption
29075   *
29076   * @param $entry the entry to modify
29077   */
29078  JustifiedGallery.prototype.removeCaptionEventsHandlers = function ($entry) {
29079    var captionMouseEvents = $entry.data('jg.captionMouseEvents');
29080    if (typeof captionMouseEvents !== 'undefined') {
29081      $entry.off('mouseenter', undefined, captionMouseEvents.mouseenter);
29082      $entry.off('mouseleave', undefined, captionMouseEvents.mouseleave);
29083      $entry.removeData('jg.captionMouseEvents');
29084    }
29085  };
29086
29087  /**
29088   * Clear the building row data to be used for a new row
29089   */
29090  JustifiedGallery.prototype.clearBuildingRow = function () {
29091    this.buildingRow.entriesBuff = [];
29092    this.buildingRow.aspectRatio = 0;
29093    this.buildingRow.width = 0;
29094  };
29095
29096  /**
29097   * Justify the building row, preparing it to
29098   *
29099   * @param isLastRow
29100   * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row.
29101   * @returns a boolean to know if the row has been justified or not
29102   */
29103  JustifiedGallery.prototype.prepareBuildingRow = function (isLastRow, hiddenRow) {
29104    var i, $entry, imgAspectRatio, newImgW, newImgH, justify = true;
29105    var minHeight = 0;
29106    var availableWidth = this.galleryWidth - 2 * this.border - (
29107      (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
29108    var rowHeight = Math.floor( availableWidth / this.buildingRow.aspectRatio );//hacked by Uncode
29109    var defaultRowHeight = this.settings.rowHeight;
29110    var justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold;
29111
29112    //Skip the last row if we can't justify it and the lastRow == 'hide'
29113    if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) {
29114      for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29115        $entry = this.buildingRow.entriesBuff[i];
29116        if (this.settings.cssAnimation)
29117          $entry.removeClass('jg-entry-visible');
29118        else {
29119          $entry.stop().fadeTo(0, 0.1);
29120          $entry.find('> img, > a > img').fadeTo(0, 0);
29121        }
29122      }
29123      return -1;
29124    }
29125
29126    // With lastRow = nojustify, justify if is justificable (the images will not become too big)
29127    if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') {
29128      justify = false;
29129
29130      if (this.rows > 0) {
29131        defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows;
29132        justify = defaultRowHeight * this.buildingRow.aspectRatio / availableWidth > this.settings.justifyThreshold;
29133      }
29134    }
29135
29136    for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29137      $entry = this.buildingRow.entriesBuff[i];
29138      imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
29139
29140      if (justify) {
29141        newImgW = (i === this.buildingRow.entriesBuff.length - 1) ? availableWidth : rowHeight * imgAspectRatio;
29142        newImgH = rowHeight;
29143      } else {
29144        newImgW = defaultRowHeight * imgAspectRatio;
29145        newImgH = defaultRowHeight;
29146      }
29147
29148      availableWidth -= Math.round(newImgW);
29149      $entry.data('jg.jwidth', Math.round(newImgW));
29150      $entry.data('jg.jheight', Math.ceil(newImgH));
29151      if (i === 0 || minHeight > newImgH) minHeight = newImgH;
29152    }
29153
29154    this.buildingRow.height = minHeight;
29155    return justify;
29156  };
29157
29158  /**
29159   * Flush a row: justify it, modify the gallery height accordingly to the row height
29160   *
29161   * @param isLastRow
29162   * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row.
29163   */
29164  JustifiedGallery.prototype.flushRow = function (isLastRow, hiddenRow) {
29165    var settings = this.settings;
29166    var $entry, buildingRowRes, offX = this.border, i;
29167
29168    buildingRowRes = this.prepareBuildingRow(isLastRow, hiddenRow);
29169    if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowRes === -1)) {
29170      this.clearBuildingRow();
29171      return;
29172    }
29173
29174    if (this.maxRowHeight) {
29175      if (this.maxRowHeight < this.buildingRow.height) this.buildingRow.height = this.maxRowHeight;
29176    }
29177
29178    //Align last (unjustified) row
29179    if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) {
29180      var availableWidth = this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins;
29181
29182      for (i = 0; i < this.buildingRow.entriesBuff.length; i++) {
29183        $entry = this.buildingRow.entriesBuff[i];
29184        availableWidth -= $entry.data('jg.jwidth');
29185      }
29186
29187      if (settings.lastRow === 'center')
29188        offX += Math.round(availableWidth / 2);
29189      else if (settings.lastRow === 'right')
29190        offX += availableWidth;
29191    }
29192
29193    var lastEntryIdx = this.buildingRow.entriesBuff.length - 1;
29194    for (i = 0; i <= lastEntryIdx; i++) {
29195      $entry = this.buildingRow.entriesBuff[this.settings.rtl ? lastEntryIdx - i : i];
29196      this.displayEntry($entry, offX, this.offY, $entry.data('jg.jwidth'), $entry.data('jg.jheight'), this.buildingRow.height);
29197      offX += $entry.data('jg.jwidth') + settings.margins;
29198    }
29199
29200    //Gallery Height
29201    this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border;
29202    this.setGalleryTempHeight(this.galleryHeightToSet + this.getSpinnerHeight());
29203
29204    if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowRes)) {
29205      //Ready for a new row
29206      this.offY += this.buildingRow.height + settings.margins;
29207      this.rows += 1;
29208      this.clearBuildingRow();
29209      this.settings.triggerEvent.call(this, 'jg.rowflush');
29210    }
29211  };
29212
29213
29214  // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221
29215  var galleryPrevStaticHeight = 0;
29216
29217  JustifiedGallery.prototype.rememberGalleryHeight = function () {
29218    galleryPrevStaticHeight = this.$gallery.height();
29219    this.$gallery.height(galleryPrevStaticHeight);
29220  };
29221
29222  // grow only
29223  JustifiedGallery.prototype.setGalleryTempHeight = function (height) {
29224    galleryPrevStaticHeight = Math.max(height, galleryPrevStaticHeight);
29225    this.$gallery.height(galleryPrevStaticHeight);
29226  };
29227
29228  JustifiedGallery.prototype.setGalleryFinalHeight = function (height) {
29229    galleryPrevStaticHeight = height;
29230    this.$gallery.height(height);
29231  };
29232
29233  /**
29234   * Checks the width of the gallery container, to know if a new justification is needed
29235   */
29236  JustifiedGallery.prototype.checkWidth = function () {
29237    this.checkWidthIntervalId = setInterval($.proxy(function () {
29238
29239      // if the gallery is not currently visible, abort.
29240      if (!this.$gallery.is(":visible")) return;
29241
29242      var galleryWidth = parseFloat(this.$gallery.width());
29243      if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) {
29244        this.galleryWidth = galleryWidth;
29245        this.rewind();
29246
29247        this.rememberGalleryHeight();
29248
29249        // Restart to analyze
29250        this.startImgAnalyzer(true);
29251      }
29252    }, this), this.settings.refreshTime);
29253  };
29254
29255  /**
29256   * @returns {boolean} a boolean saying if the spinner is active or not
29257   */
29258  JustifiedGallery.prototype.isSpinnerActive = function () {
29259    return this.spinner.intervalId !== null;
29260  };
29261
29262  /**
29263   * @returns {int} the spinner height
29264   */
29265  JustifiedGallery.prototype.getSpinnerHeight = function () {
29266    return this.spinner.$el.innerHeight();
29267  };
29268
29269  /**
29270   * Stops the spinner animation and modify the gallery height to exclude the spinner
29271   */
29272  JustifiedGallery.prototype.stopLoadingSpinnerAnimation = function () {
29273    clearInterval(this.spinner.intervalId);
29274    this.spinner.intervalId = null;
29275    this.setGalleryTempHeight(this.$gallery.height() - this.getSpinnerHeight());
29276    this.spinner.$el.detach();
29277  };
29278
29279  /**
29280   * Starts the spinner animation
29281   */
29282  JustifiedGallery.prototype.startLoadingSpinnerAnimation = function () {
29283    var spinnerContext = this.spinner;
29284    var $spinnerPoints = spinnerContext.$el.find('span');
29285    clearInterval(spinnerContext.intervalId);
29286    this.$gallery.append(spinnerContext.$el);
29287    this.setGalleryTempHeight(this.offY + this.buildingRow.height + this.getSpinnerHeight());
29288    spinnerContext.intervalId = setInterval(function () {
29289      if (spinnerContext.phase < $spinnerPoints.length) {
29290        $spinnerPoints.eq(spinnerContext.phase).fadeTo(spinnerContext.timeSlot, 1);
29291      } else {
29292        $spinnerPoints.eq(spinnerContext.phase - $spinnerPoints.length).fadeTo(spinnerContext.timeSlot, 0);
29293      }
29294      spinnerContext.phase = (spinnerContext.phase + 1) % ($spinnerPoints.length * 2);
29295    }, spinnerContext.timeSlot);
29296  };
29297
29298  /**
29299   * Rewind the image analysis to start from the first entry.
29300   */
29301  JustifiedGallery.prototype.rewind = function () {
29302    this.lastFetchedEntry = null;
29303    this.lastAnalyzedIndex = -1;
29304    this.offY = this.border;
29305    this.rows = 0;
29306    this.clearBuildingRow();
29307  };
29308
29309  /**
29310   * @returns {String} `settings.selector` rejecting spinner element
29311   */
29312  JustifiedGallery.prototype.getSelectorWithoutSpinner = function () {
29313    return this.settings.selector + ', div:not(.jg-spinner)';
29314  };
29315
29316  /**
29317   * @returns {Array} all entries matched by `settings.selector`
29318   */
29319  JustifiedGallery.prototype.getAllEntries = function () {
29320    var selector = this.getSelectorWithoutSpinner();
29321    return this.$gallery.children(selector).toArray();
29322  };
29323
29324  /**
29325   * Update the entries searching it from the justified gallery HTML element
29326   *
29327   * @param norewind if norewind only the new entries will be changed (i.e. randomized, sorted or filtered)
29328   * @returns {boolean} true if some entries has been founded
29329   */
29330  JustifiedGallery.prototype.updateEntries = function (norewind) {
29331    var newEntries;
29332
29333    if (norewind && this.lastFetchedEntry != null) {
29334      var selector = this.getSelectorWithoutSpinner();
29335      newEntries = $(this.lastFetchedEntry).nextAll(selector).toArray();
29336    } else {
29337      this.entries = [];
29338      newEntries = this.getAllEntries();
29339    }
29340
29341    if (newEntries.length > 0) {
29342
29343      // Sort or randomize
29344      if ($.isFunction(this.settings.sort)) {
29345        newEntries = this.sortArray(newEntries);
29346      } else if (this.settings.randomize) {
29347        newEntries = this.shuffleArray(newEntries);
29348      }
29349      this.lastFetchedEntry = newEntries[newEntries.length - 1];
29350
29351      // Filter
29352      if (this.settings.filter) {
29353        newEntries = this.filterArray(newEntries);
29354      } else {
29355        this.resetFilters(newEntries);
29356      }
29357
29358    }
29359
29360    this.entries = this.entries.concat(newEntries);
29361    return true;
29362  };
29363
29364  /**
29365   * Apply the entries order to the DOM, iterating the entries and appending the images
29366   *
29367   * @param entries the entries that has been modified and that must be re-ordered in the DOM
29368   */
29369  JustifiedGallery.prototype.insertToGallery = function (entries) {
29370    var that = this;
29371    $.each(entries, function () {
29372      $(this).appendTo(that.$gallery);
29373    });
29374  };
29375
29376  /**
29377   * Shuffle the array using the Fisher-Yates shuffle algorithm
29378   *
29379   * @param a the array to shuffle
29380   * @return the shuffled array
29381   */
29382  JustifiedGallery.prototype.shuffleArray = function (a) {
29383    var i, j, temp;
29384    for (i = a.length - 1; i > 0; i--) {
29385      j = Math.floor(Math.random() * (i + 1));
29386      temp = a[i];
29387      a[i] = a[j];
29388      a[j] = temp;
29389    }
29390    this.insertToGallery(a);
29391    return a;
29392  };
29393
29394  /**
29395   * Sort the array using settings.comparator as comparator
29396   *
29397   * @param a the array to sort (it is sorted)
29398   * @return the sorted array
29399   */
29400  JustifiedGallery.prototype.sortArray = function (a) {
29401    a.sort(this.settings.sort);
29402    this.insertToGallery(a);
29403    return a;
29404  };
29405
29406  /**
29407   * Reset the filters removing the 'jg-filtered' class from all the entries
29408   *
29409   * @param a the array to reset
29410   */
29411  JustifiedGallery.prototype.resetFilters = function (a) {
29412    for (var i = 0; i < a.length; i++) $(a[i]).removeClass('jg-filtered');
29413  };
29414
29415  /**
29416   * Filter the entries considering theirs classes (if a string has been passed) or using a function for filtering.
29417   *
29418   * @param a the array to filter
29419   * @return the filtered array
29420   */
29421  JustifiedGallery.prototype.filterArray = function (a) {
29422    var settings = this.settings;
29423    if ($.type(settings.filter) === 'string') {
29424      // Filter only keeping the entries passed in the string
29425      return a.filter(function (el) {
29426        var $el = $(el);
29427        if ($el.is(settings.filter)) {
29428          $el.removeClass('jg-filtered');
29429          return true;
29430        } else {
29431          $el.addClass('jg-filtered').removeClass('jg-visible');
29432          return false;
29433        }
29434      });
29435    } else if ($.isFunction(settings.filter)) {
29436      // Filter using the passed function
29437      var filteredArr = a.filter(settings.filter);
29438      for (var i = 0; i < a.length; i++) {
29439        if (filteredArr.indexOf(a[i]) === -1) {
29440          $(a[i]).addClass('jg-filtered').removeClass('jg-visible');
29441        } else {
29442          $(a[i]).removeClass('jg-filtered');
29443        }
29444      }
29445      return filteredArr;
29446    }
29447  };
29448
29449  /**
29450   * Revert the image src to the default value.
29451   */
29452  JustifiedGallery.prototype.resetImgSrc = function ($img) {
29453    if ($img.data('jg.originalSrcLoc') === 'src') {
29454      $img.attr('src', $img.data('jg.originalSrc'));
29455    } else {
29456      $img.attr('src', '');
29457    }
29458  };
29459
29460  /**
29461   * Destroy the Justified Gallery instance.
29462   *
29463   * It clears all the css properties added in the style attributes. We doesn't backup the original
29464   * values for those css attributes, because it costs (performance) and because in general one
29465   * shouldn't use the style attribute for an uniform set of images (where we suppose the use of
29466   * classes). Creating a backup is also difficult because JG could be called multiple times and
29467   * with different style attributes.
29468   */
29469  JustifiedGallery.prototype.destroy = function () {
29470    clearInterval(this.checkWidthIntervalId);
29471    this.stopImgAnalyzerStarter();
29472
29473    // Get fresh entries list since filtered entries are absent in `this.entries`
29474    $.each(this.getAllEntries(), $.proxy(function (_, entry) {
29475      var $entry = $(entry);
29476
29477      // Reset entry style
29478      $entry.css('width', '');
29479      $entry.css('height', '');
29480      $entry.css('top', '');
29481      $entry.css('left', '');
29482      $entry.data('jg.loaded', undefined);
29483      $entry.removeClass('jg-entry jg-filtered jg-entry-visible');
29484
29485      // Reset image style
29486      var $img = this.imgFromEntry($entry);
29487      if ($img) {
29488        $img.css('width', '');
29489        $img.css('height', '');
29490        $img.css('margin-left', '');
29491        $img.css('margin-top', '');
29492        this.resetImgSrc($img);
29493        $img.data('jg.originalSrc', undefined);
29494        $img.data('jg.originalSrcLoc', undefined);
29495        $img.data('jg.src', undefined);
29496      }
29497
29498      // Remove caption
29499      this.removeCaptionEventsHandlers($entry);
29500      var $caption = this.captionFromEntry($entry);
29501      if ($entry.data('jg.createdCaption')) {
29502        // remove also the caption element (if created by jg)
29503        $entry.data('jg.createdCaption', undefined);
29504        if ($caption !== null) $caption.remove();
29505      } else {
29506        if ($caption !== null) $caption.fadeTo(0, 1);
29507      }
29508
29509    }, this));
29510
29511    this.$gallery.css('height', '');
29512    this.$gallery.removeClass('justified-gallery');
29513    this.$gallery.data('jg.controller', undefined);
29514    this.settings.triggerEvent.call(this, 'jg.destroy');
29515  };
29516
29517  /**
29518   * Analyze the images and builds the rows. It returns if it found an image that is not loaded.
29519   *
29520   * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end
29521   */
29522  JustifiedGallery.prototype.analyzeImages = function (isForResize) {
29523    for (var i = this.lastAnalyzedIndex + 1; i < this.entries.length; i++) {
29524      var $entry = $(this.entries[i]);
29525      if ($entry.data('jg.loaded') === true || $entry.data('jg.loaded') === 'skipped') {
29526        var availableWidth = this.galleryWidth - 2 * this.border - (
29527          (this.buildingRow.entriesBuff.length - 1) * this.settings.margins);
29528        var imgAspectRatio = $entry.data('jg.width') / $entry.data('jg.height');
29529
29530        this.buildingRow.entriesBuff.push($entry);
29531        this.buildingRow.aspectRatio += imgAspectRatio;
29532        this.buildingRow.width += imgAspectRatio * this.settings.rowHeight;
29533        this.lastAnalyzedIndex = i;
29534
29535        if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) {
29536          this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount);
29537
29538          if (++this.yield.flushed >= this.yield.every) {
29539            this.startImgAnalyzer(isForResize);
29540            return;
29541          }
29542        }
29543      } else if ($entry.data('jg.loaded') !== 'error') {
29544        return;
29545      }
29546    }
29547
29548    // Last row flush (the row is not full)
29549    if (this.buildingRow.entriesBuff.length > 0) {
29550      this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount);
29551    }
29552
29553    if (this.isSpinnerActive()) {
29554      this.stopLoadingSpinnerAnimation();
29555    }
29556
29557    /* Stop, if there is, the timeout to start the analyzeImages.
29558     This is because an image can be set loaded, and the timeout can be set,
29559     but this image can be analyzed yet.
29560     */
29561    this.stopImgAnalyzerStarter();
29562
29563    this.setGalleryFinalHeight(this.galleryHeightToSet);
29564
29565    //On complete callback
29566    this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete');
29567  };
29568
29569  /**
29570   * Stops any ImgAnalyzer starter (that has an assigned timeout)
29571   */
29572  JustifiedGallery.prototype.stopImgAnalyzerStarter = function () {
29573    this.yield.flushed = 0;
29574    if (this.imgAnalyzerTimeout !== null) {
29575      clearTimeout(this.imgAnalyzerTimeout);
29576      this.imgAnalyzerTimeout = null;
29577    }
29578  };
29579
29580  /**
29581   * Starts the image analyzer. It is not immediately called to let the browser to update the view
29582   *
29583   * @param isForResize specifies if the image analyzer must be called for resizing or not
29584   */
29585  JustifiedGallery.prototype.startImgAnalyzer = function (isForResize) {
29586    var that = this;
29587    this.stopImgAnalyzerStarter();
29588    this.imgAnalyzerTimeout = setTimeout(function () {
29589      that.analyzeImages(isForResize);
29590    }, 0.001); // we can't start it immediately due to a IE different behaviour
29591  };
29592
29593  /**
29594   * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property,
29595   * because some browsers, with a 404 set complete = true.
29596   *
29597   * @param imageSrc the image src to load
29598   * @param onLoad callback that is called when the image has been loaded
29599   * @param onError callback that is called in case of an error
29600   */
29601  JustifiedGallery.prototype.onImageEvent = function (imageSrc, onLoad, onError) {
29602    if (!onLoad && !onError) return;
29603
29604    var memImage = new Image();
29605    var $memImage = $(memImage);
29606    if (onLoad) {
29607      $memImage.one('load', function () {
29608        $memImage.off('load error');
29609        onLoad(memImage);
29610      });
29611    }
29612    if (onError) {
29613      $memImage.one('error', function () {
29614        $memImage.off('load error');
29615        onError(memImage);
29616      });
29617    }
29618    memImage.src = imageSrc;
29619  };
29620
29621  /**
29622   * Init of Justified Gallery controlled
29623   * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images)
29624   */
29625  JustifiedGallery.prototype.init = function () {
29626    var imagesToLoad = false, skippedImages = false, that = this;
29627    $.each(this.entries, function (index, entry) {
29628      var $entry = $(entry);
29629      var $image = that.imgFromEntry($entry);
29630
29631      $entry.addClass('jg-entry');
29632
29633      if ($entry.data('jg.loaded') !== true && $entry.data('jg.loaded') !== 'skipped') {
29634
29635        // Link Rel global overwrite
29636        if (that.settings.rel !== null) $entry.attr('rel', that.settings.rel);
29637
29638        // Link Target global overwrite
29639        if (that.settings.target !== null) $entry.attr('target', that.settings.target);
29640
29641        if ($image !== null) {
29642
29643          // Image src
29644          var imageSrc = that.extractImgSrcFromImage($image);
29645
29646          /* If we have the height and the width, we don't wait that the image is loaded,
29647             but we start directly with the justification */
29648          if (that.settings.waitThumbnailsLoad === false || !imageSrc) {
29649            var width = parseFloat($image.attr('width'));
29650            var height = parseFloat($image.attr('height'));
29651            if ($image.prop('tagName') === 'svg') {
29652              width = parseFloat($image[0].getBBox().width);
29653              height = parseFloat($image[0].getBBox().height);
29654            }
29655            if (!isNaN(width) && !isNaN(height)) {
29656              $entry.data('jg.width', width);
29657              $entry.data('jg.height', height);
29658              $entry.data('jg.loaded', 'skipped');
29659              skippedImages = true;
29660              that.startImgAnalyzer(false);
29661              return true; // continue
29662            }
29663          }
29664
29665          $entry.data('jg.loaded', false);
29666          imagesToLoad = true;
29667
29668          // Spinner start
29669          if (!that.isSpinnerActive()) that.startLoadingSpinnerAnimation();
29670
29671          that.onImageEvent(imageSrc, function (loadImg) { // image loaded
29672            $entry.data('jg.width', loadImg.width);
29673            $entry.data('jg.height', loadImg.height);
29674            $entry.data('jg.loaded', true);
29675            that.startImgAnalyzer(false);
29676          }, function () { // image load error
29677            $entry.data('jg.loaded', 'error');
29678            that.startImgAnalyzer(false);
29679          });
29680
29681        } else {
29682          $entry.data('jg.loaded', true);
29683          $entry.data('jg.width', $entry.width() | parseFloat($entry.css('width')) | 1);
29684          $entry.data('jg.height', $entry.height() | parseFloat($entry.css('height')) | 1);
29685        }
29686
29687      }
29688
29689    });
29690
29691    if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false);
29692    this.checkWidth();
29693  };
29694
29695  /**
29696   * Checks that it is a valid number. If a string is passed it is converted to a number
29697   *
29698   * @param settingContainer the object that contains the setting (to allow the conversion)
29699   * @param settingName the setting name
29700   */
29701  JustifiedGallery.prototype.checkOrConvertNumber = function (settingContainer, settingName) {
29702    if ($.type(settingContainer[settingName]) === 'string') {
29703      settingContainer[settingName] = parseFloat(settingContainer[settingName]);
29704    }
29705
29706    if ($.type(settingContainer[settingName]) === 'number') {
29707      if (isNaN(settingContainer[settingName])) throw 'invalid number for ' + settingName;
29708    } else {
29709      throw settingName + ' must be a number';
29710    }
29711  };
29712
29713  /**
29714   * Checks the sizeRangeSuffixes and, if necessary, converts
29715   * its keys from string (e.g. old settings with 'lt100') to int.
29716   */
29717  JustifiedGallery.prototype.checkSizeRangesSuffixes = function () {
29718    if ($.type(this.settings.sizeRangeSuffixes) !== 'object') {
29719      throw 'sizeRangeSuffixes must be defined and must be an object';
29720    }
29721
29722    var suffixRanges = [];
29723    for (var rangeIdx in this.settings.sizeRangeSuffixes) {
29724      if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(rangeIdx);
29725    }
29726
29727    var newSizeRngSuffixes = { 0: '' };
29728    for (var i = 0; i < suffixRanges.length; i++) {
29729      if ($.type(suffixRanges[i]) === 'string') {
29730        try {
29731          var numIdx = parseInt(suffixRanges[i].replace(/^[a-z]+/, ''), 10);
29732          newSizeRngSuffixes[numIdx] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
29733        } catch (e) {
29734          throw 'sizeRangeSuffixes keys must contains correct numbers (' + e + ')';
29735        }
29736      } else {
29737        newSizeRngSuffixes[suffixRanges[i]] = this.settings.sizeRangeSuffixes[suffixRanges[i]];
29738      }
29739    }
29740
29741    this.settings.sizeRangeSuffixes = newSizeRngSuffixes;
29742  };
29743
29744  /**
29745   * check and convert the maxRowHeight setting
29746   * requires rowHeight to be already set
29747   * TODO: should be always called when only rowHeight is changed
29748   * @return number or null
29749   */
29750  JustifiedGallery.prototype.retrieveMaxRowHeight = function () {
29751    var newMaxRowHeight = null;
29752    var rowHeight = this.settings.rowHeight;
29753
29754    if ($.type(this.settings.maxRowHeight) === 'string') {
29755      if (this.settings.maxRowHeight.match(/^[0-9]+%$/)) {
29756        newMaxRowHeight = rowHeight * parseFloat(this.settings.maxRowHeight.match(/^([0-9]+)%$/)[1]) / 100;
29757      } else {
29758        newMaxRowHeight = parseFloat(this.settings.maxRowHeight);
29759      }
29760    } else if ($.type(this.settings.maxRowHeight) === 'number') {
29761      newMaxRowHeight = this.settings.maxRowHeight;
29762    } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight == null) {
29763      return null;
29764    } else {
29765      throw 'maxRowHeight must be a number or a percentage';
29766    }
29767
29768    // check if the converted value is not a number
29769    if (isNaN(newMaxRowHeight)) throw 'invalid number for maxRowHeight';
29770
29771    // check values, maxRowHeight must be >= rowHeight
29772    if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight;
29773
29774    return newMaxRowHeight;
29775  };
29776
29777  /**
29778   * Checks the settings
29779   */
29780  JustifiedGallery.prototype.checkSettings = function () {
29781    this.checkSizeRangesSuffixes();
29782
29783    this.checkOrConvertNumber(this.settings, 'rowHeight');
29784    this.checkOrConvertNumber(this.settings, 'margins');
29785    this.checkOrConvertNumber(this.settings, 'border');
29786    this.checkOrConvertNumber(this.settings, 'maxRowsCount');
29787
29788    var lastRowModes = [
29789      'justify',
29790      'nojustify',
29791      'left',
29792      'center',
29793      'right',
29794      'hide'
29795    ];
29796    if (lastRowModes.indexOf(this.settings.lastRow) === -1) {
29797      throw 'lastRow must be one of: ' + lastRowModes.join(', ');
29798    }
29799
29800    this.checkOrConvertNumber(this.settings, 'justifyThreshold');
29801    if (this.settings.justifyThreshold < 0 || this.settings.justifyThreshold > 1) {
29802      throw 'justifyThreshold must be in the interval [0,1]';
29803    }
29804    if ($.type(this.settings.cssAnimation) !== 'boolean') {
29805      throw 'cssAnimation must be a boolean';
29806    }
29807
29808    if ($.type(this.settings.captions) !== 'boolean') throw 'captions must be a boolean';
29809    this.checkOrConvertNumber(this.settings.captionSettings, 'animationDuration');
29810
29811    this.checkOrConvertNumber(this.settings.captionSettings, 'visibleOpacity');
29812    if (this.settings.captionSettings.visibleOpacity < 0 ||
29813      this.settings.captionSettings.visibleOpacity > 1) {
29814      throw 'captionSettings.visibleOpacity must be in the interval [0, 1]';
29815    }
29816
29817    this.checkOrConvertNumber(this.settings.captionSettings, 'nonVisibleOpacity');
29818    if (this.settings.captionSettings.nonVisibleOpacity < 0 ||
29819      this.settings.captionSettings.nonVisibleOpacity > 1) {
29820      throw 'captionSettings.nonVisibleOpacity must be in the interval [0, 1]';
29821    }
29822
29823    this.checkOrConvertNumber(this.settings, 'imagesAnimationDuration');
29824    this.checkOrConvertNumber(this.settings, 'refreshTime');
29825    this.checkOrConvertNumber(this.settings, 'refreshSensitivity');
29826    if ($.type(this.settings.randomize) !== 'boolean') throw 'randomize must be a boolean';
29827    if ($.type(this.settings.selector) !== 'string') throw 'selector must be a string';
29828
29829    if (this.settings.sort !== false && !$.isFunction(this.settings.sort)) {
29830      throw 'sort must be false or a comparison function';
29831    }
29832
29833    if (this.settings.filter !== false && !$.isFunction(this.settings.filter) &&
29834      $.type(this.settings.filter) !== 'string') {
29835      throw 'filter must be false, a string or a filter function';
29836    }
29837  };
29838
29839  /**
29840   * It brings all the indexes from the sizeRangeSuffixes and it orders them. They are then sorted and returned.
29841   * @returns {Array} sorted suffix ranges
29842   */
29843  JustifiedGallery.prototype.retrieveSuffixRanges = function () {
29844    var suffixRanges = [];
29845    for (var rangeIdx in this.settings.sizeRangeSuffixes) {
29846      if (this.settings.sizeRangeSuffixes.hasOwnProperty(rangeIdx)) suffixRanges.push(parseInt(rangeIdx, 10));
29847    }
29848    suffixRanges.sort(function (a, b) { return a > b ? 1 : a < b ? -1 : 0; });
29849    return suffixRanges;
29850  };
29851
29852  /**
29853   * Update the existing settings only changing some of them
29854   *
29855   * @param newSettings the new settings (or a subgroup of them)
29856   */
29857  JustifiedGallery.prototype.updateSettings = function (newSettings) {
29858    // In this case Justified Gallery has been called again changing only some options
29859    this.settings = $.extend({}, this.settings, newSettings);
29860    this.checkSettings();
29861
29862    // As reported in the settings: negative value = same as margins, 0 = disabled
29863    this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins;
29864
29865    this.maxRowHeight = this.retrieveMaxRowHeight();
29866    this.suffixRanges = this.retrieveSuffixRanges();
29867  };
29868
29869  JustifiedGallery.prototype.defaults = {
29870    sizeRangeSuffixes: {}, /* e.g. Flickr configuration
29871        {
29872          100: '_t',  // used when longest is less than 100px
29873          240: '_m',  // used when longest is between 101px and 240px
29874          320: '_n',  // ...
29875          500: '',
29876          640: '_z',
29877          1024: '_b'  // used as else case because it is the last
29878        }
29879    */
29880    thumbnailPath: undefined, /* If defined, sizeRangeSuffixes is not used, and this function is used to determine the
29881    path relative to a specific thumbnail size. The function should accept respectively three arguments:
29882    current path, width and height */
29883    rowHeight: 120, // required? required to be > 0?
29884    maxRowHeight: false, // false or negative value to deactivate. Positive number to express the value in pixels,
29885    // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height
29886    // can't exceed 3 * rowHeight)
29887    maxRowsCount: 0, // maximum number of rows to be displayed (0 = disabled)
29888    margins: 1,
29889    border: -1, // negative value = same as margins, 0 = disabled, any other value to set the border
29890
29891    lastRow: 'nojustify', // … which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide'
29892
29893    justifyThreshold: 0.90, /* if row width / available space > 0.90 it will be always justified
29894                             * (i.e. lastRow setting is not considered) */
29895    waitThumbnailsLoad: true,
29896    captions: true,
29897    cssAnimation: true,
29898    imagesAnimationDuration: 500, // ignored with css animations
29899    captionSettings: { // ignored with css animations
29900      animationDuration: 500,
29901      visibleOpacity: 0.7,
29902      nonVisibleOpacity: 0.0
29903    },
29904    rel: null, // rewrite the rel of each analyzed links
29905    target: null, // rewrite the target of all links
29906    extension: /\.[^.\\/]+$/, // regexp to capture the extension of an image
29907    refreshTime: 200, // time interval (in ms) to check if the page changes its width
29908    refreshSensitivity: 0, // change in width allowed (in px) without re-building the gallery
29909    randomize: false,
29910    rtl: false, // right-to-left mode
29911    sort: false, /*
29912      - false: to do not sort
29913      - function: to sort them using the function as comparator (see Array.prototype.sort())
29914    */
29915    filter: false, /*
29916      - false, null or undefined: for a disabled filter
29917      - a string: an entry is kept if entry.is(filter string) returns true
29918                  see jQuery's .is() function for further information
29919      - a function: invoked with arguments (entry, index, array). Return true to keep the entry, false otherwise.
29920                    It follows the specifications of the Array.prototype.filter() function of JavaScript.
29921    */
29922    selector: 'a', // The selector that is used to know what are the entries of the gallery
29923    imgSelector: '> img, > a > img, > svg, > a > svg', // The selector that is used to know what are the images of each entry
29924    triggerEvent: function (event) { // This is called to trigger events, the default behavior is to call $.trigger
29925      this.$gallery.trigger(event);  // Consider that 'this' is this set to the JustifiedGallery object, so it can
29926    }                                // access to fields such as $gallery, useful to trigger events with jQuery.
29927  };
29928
29929
29930  /**
29931   * Justified Gallery plugin for jQuery
29932   *
29933   * Events
29934   *  - jg.complete : called when all the gallery has been created
29935   *  - jg.resize : called when the gallery has been resized
29936   *  - jg.rowflush : when a new row appears
29937   *
29938   * @param arg the action (or the settings) passed when the plugin is called
29939   * @returns {*} the object itself
29940   */
29941  $.fn.justifiedGallery = function (arg) {
29942    return this.each(function (index, gallery) {
29943
29944      var $gallery = $(gallery);
29945      $gallery.addClass('justified-gallery');
29946
29947      var controller = $gallery.data('jg.controller');
29948      if (typeof controller === 'undefined') {
29949        // Create controller and assign it to the object data
29950        if (typeof arg !== 'undefined' && arg !== null && $.type(arg) !== 'object') {
29951          if (arg === 'destroy') return; // Just a call to an unexisting object
29952          throw 'The argument must be an object';
29953        }
29954        controller = new JustifiedGallery($gallery, $.extend({}, JustifiedGallery.prototype.defaults, arg));
29955        $gallery.data('jg.controller', controller);
29956      } else if (arg === 'norewind') {
29957        // In this case we don't rewind: we analyze only the latest images (e.g. to complete the last unfinished row
29958        // ... left to be more readable
29959      } else if (arg === 'destroy') {
29960        controller.destroy();
29961        return;
29962      } else {
29963        // In this case Justified Gallery has been called again changing only some options
29964        controller.updateSettings(arg);
29965        controller.rewind();
29966      }
29967
29968      // Update the entries list
29969      if (!controller.updateEntries(arg === 'norewind')) return;
29970
29971      // Init justified gallery
29972      controller.init();
29973
29974    });
29975  };
29976
29977}));
29978
29979/*!
29980* Customized version of iScroll.js 0.0.1
29981* It fixes bugs affecting its integration with fullpage.js
29982*/
29983/*! iScroll v5.2.0 ~ (c) 2008-2016 Matteo Spinelli ~ http://cubiq.org/license */
29984(function (window, document, Math) {
29985var rAF = window.requestAnimationFrame  ||
29986    window.webkitRequestAnimationFrame  ||
29987    window.mozRequestAnimationFrame     ||
29988    window.oRequestAnimationFrame       ||
29989    window.msRequestAnimationFrame      ||
29990    function (callback) { window.setTimeout(callback, 1000 / 60); };
29991
29992var utils = (function () {
29993    var me = {};
29994
29995    var _elementStyle = document.createElement('div').style;
29996    var _vendor = (function () {
29997        var vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT'],
29998            transform,
29999            i = 0,
30000            l = vendors.length;
30001
30002        for ( ; i < l; i++ ) {
30003            transform = vendors[i] + 'ransform';
30004            if ( transform in _elementStyle ) return vendors[i].substr(0, vendors[i].length-1);
30005        }
30006
30007        return false;
30008    })();
30009
30010    function _prefixStyle (style) {
30011        if ( _vendor === false ) return false;
30012        if ( _vendor === '' ) return style;
30013        return _vendor + style.charAt(0).toUpperCase() + style.substr(1);
30014    }
30015
30016    me.getTime = Date.now || function getTime () { return new Date().getTime(); };
30017
30018    me.extend = function (target, obj) {
30019        for ( var i in obj ) {
30020            target[i] = obj[i];
30021        }
30022    };
30023
30024    me.addEvent = function (el, type, fn, capture) {
30025        el.addEventListener(type, fn, !!capture);
30026    };
30027
30028    me.removeEvent = function (el, type, fn, capture) {
30029        el.removeEventListener(type, fn, !!capture);
30030    };
30031
30032    me.prefixPointerEvent = function (pointerEvent) {
30033        return window.MSPointerEvent ?
30034            'MSPointer' + pointerEvent.charAt(7).toUpperCase() + pointerEvent.substr(8):
30035            pointerEvent;
30036    };
30037
30038    me.momentum = function (current, start, time, lowerMargin, wrapperSize, deceleration) {
30039        var distance = current - start,
30040            speed = Math.abs(distance) / time,
30041            destination,
30042            duration;
30043
30044        deceleration = deceleration === undefined ? 0.0006 : deceleration;
30045
30046        destination = current + ( speed * speed ) / ( 2 * deceleration ) * ( distance < 0 ? -1 : 1 );
30047        duration = speed / deceleration;
30048
30049        if ( destination < lowerMargin ) {
30050            destination = wrapperSize ? lowerMargin - ( wrapperSize / 2.5 * ( speed / 8 ) ) : lowerMargin;
30051            distance = Math.abs(destination - current);
30052            duration = distance / speed;
30053        } else if ( destination > 0 ) {
30054            destination = wrapperSize ? wrapperSize / 2.5 * ( speed / 8 ) : 0;
30055            distance = Math.abs(current) + destination;
30056            duration = distance / speed;
30057        }
30058
30059        return {
30060            destination: Math.round(destination),
30061            duration: duration
30062        };
30063    };
30064
30065    var _transform = _prefixStyle('transform');
30066
30067    me.extend(me, {
30068        hasTransform: _transform !== false,
30069        hasPerspective: _prefixStyle('perspective') in _elementStyle,
30070        hasTouch: 'ontouchstart' in window,
30071        hasPointer: !!(window.PointerEvent || window.MSPointerEvent), // IE10 is prefixed
30072        hasTransition: _prefixStyle('transition') in _elementStyle
30073    });
30074
30075    /*
30076    This should find all Android browsers lower than build 535.19 (both stock browser and webview)
30077    - galaxy S2 is ok
30078    - 2.3.6 : `AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1`
30079    - 4.0.4 : `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30080   - galaxy S3 is badAndroid (stock brower, webview)
30081     `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30082   - galaxy S4 is badAndroid (stock brower, webview)
30083     `AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30`
30084   - galaxy S5 is OK
30085     `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
30086   - galaxy S6 is OK
30087     `AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Mobile Safari/537.36 (Chrome/)`
30088  */
30089    me.isBadAndroid = (function() {
30090        var appVersion = window.navigator.appVersion;
30091        // Android browser is not a chrome browser.
30092        if (/Android/.test(appVersion) && !(/Chrome\/\d/.test(appVersion))) {
30093            var safariVersion = appVersion.match(/Safari\/(\d+.\d)/);
30094            if(safariVersion && typeof safariVersion === "object" && safariVersion.length >= 2) {
30095                return parseFloat(safariVersion[1]) < 535.19;
30096            } else {
30097                return true;
30098            }
30099        } else {
30100            return false;
30101        }
30102    })();
30103
30104    me.extend(me.style = {}, {
30105        transform: _transform,
30106        transitionTimingFunction: _prefixStyle('transitionTimingFunction'),
30107        transitionDuration: _prefixStyle('transitionDuration'),
30108        transitionDelay: _prefixStyle('transitionDelay'),
30109        transformOrigin: _prefixStyle('transformOrigin')
30110    });
30111
30112    me.hasClass = function (e, c) {
30113        var re = new RegExp("(^|\\s)" + c + "(\\s|$)");
30114        return re.test(e.className);
30115    };
30116
30117    me.addClass = function (e, c) {
30118        if ( me.hasClass(e, c) ) {
30119            return;
30120        }
30121
30122        var newclass = e.className.split(' ');
30123        newclass.push(c);
30124        e.className = newclass.join(' ');
30125    };
30126
30127    me.removeClass = function (e, c) {
30128        if ( !me.hasClass(e, c) ) {
30129            return;
30130        }
30131
30132        var re = new RegExp("(^|\\s)" + c + "(\\s|$)", 'g');
30133        e.className = e.className.replace(re, ' ');
30134    };
30135
30136    me.offset = function (el) {
30137        var left = -el.offsetLeft,
30138            top = -el.offsetTop;
30139
30140        // jshint -W084
30141        while (el = el.offsetParent) {
30142            left -= el.offsetLeft;
30143            top -= el.offsetTop;
30144        }
30145        // jshint +W084
30146
30147        return {
30148            left: left,
30149            top: top
30150        };
30151    };
30152
30153    me.preventDefaultException = function (el, exceptions) {
30154        for ( var i in exceptions ) {
30155            if ( exceptions[i].test(el[i]) ) {
30156                return true;
30157            }
30158        }
30159
30160        return false;
30161    };
30162
30163    me.extend(me.eventType = {}, {
30164        touchstart: 1,
30165        touchmove: 1,
30166        touchend: 1,
30167
30168        mousedown: 2,
30169        mousemove: 2,
30170        mouseup: 2,
30171
30172        pointerdown: 3,
30173        pointermove: 3,
30174        pointerup: 3,
30175
30176        MSPointerDown: 3,
30177        MSPointerMove: 3,
30178        MSPointerUp: 3
30179    });
30180
30181    me.extend(me.ease = {}, {
30182        quadratic: {
30183            style: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
30184            fn: function (k) {
30185                return k * ( 2 - k );
30186            }
30187        },
30188        circular: {
30189            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)
30190            fn: function (k) {
30191                return Math.sqrt( 1 - ( --k * k ) );
30192            }
30193        },
30194        back: {
30195            style: 'cubic-bezier(0.175, 0.885, 0.32, 1.275)',
30196            fn: function (k) {
30197                var b = 4;
30198                return ( k = k - 1 ) * k * ( ( b + 1 ) * k + b ) + 1;
30199            }
30200        },
30201        bounce: {
30202            style: '',
30203            fn: function (k) {
30204                if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
30205                    return 7.5625 * k * k;
30206                } else if ( k < ( 2 / 2.75 ) ) {
30207                    return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
30208                } else if ( k < ( 2.5 / 2.75 ) ) {
30209                    return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
30210                } else {
30211                    return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
30212                }
30213            }
30214        },
30215        elastic: {
30216            style: '',
30217            fn: function (k) {
30218                var f = 0.22,
30219                    e = 0.4;
30220
30221                if ( k === 0 ) { return 0; }
30222                if ( k == 1 ) { return 1; }
30223
30224                return ( e * Math.pow( 2, - 10 * k ) * Math.sin( ( k - f / 4 ) * ( 2 * Math.PI ) / f ) + 1 );
30225            }
30226        }
30227    });
30228
30229    me.tap = function (e, eventName) {
30230        var ev = document.createEvent('Event');
30231        ev.initEvent(eventName, true, true);
30232        ev.pageX = e.pageX;
30233        ev.pageY = e.pageY;
30234        e.target.dispatchEvent(ev);
30235    };
30236
30237    me.click = function (e) {
30238        var target = e.target,
30239            ev;
30240
30241        if ( !(/(SELECT|INPUT|TEXTAREA)/i).test(target.tagName) ) {
30242            // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/initMouseEvent
30243            // initMouseEvent is deprecated.
30244            ev = document.createEvent(window.MouseEvent ? 'MouseEvents' : 'Event');
30245            ev.initEvent('click', true, true);
30246            ev.view = e.view || window;
30247            ev.detail = 1;
30248            ev.screenX = target.screenX || 0;
30249            ev.screenY = target.screenY || 0;
30250            ev.clientX = target.clientX || 0;
30251            ev.clientY = target.clientY || 0;
30252            ev.ctrlKey = !!e.ctrlKey;
30253            ev.altKey = !!e.altKey;
30254            ev.shiftKey = !!e.shiftKey;
30255            ev.metaKey = !!e.metaKey;
30256            ev.button = 0;
30257            ev.relatedTarget = null;
30258            ev._constructed = true;
30259            target.dispatchEvent(ev);
30260        }
30261    };
30262
30263    return me;
30264})();
30265function IScroll (el, options) {
30266    this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
30267    this.scroller = this.wrapper.children[0];
30268    this.scrollerStyle = this.scroller.style;       // cache style for better performance
30269
30270    this.options = {
30271
30272        resizeScrollbars: true,
30273
30274        mouseWheelSpeed: 20,
30275
30276        snapThreshold: 0.334,
30277
30278// INSERT POINT: OPTIONS
30279        disablePointer : !utils.hasPointer,
30280        disableTouch : utils.hasPointer || !utils.hasTouch,
30281        disableMouse : utils.hasPointer || utils.hasTouch,
30282        startX: 0,
30283        startY: 0,
30284        scrollY: true,
30285        directionLockThreshold: 5,
30286        momentum: true,
30287
30288        bounce: true,
30289        bounceTime: 600,
30290        bounceEasing: '',
30291
30292        preventDefault: true,
30293        preventDefaultException: { tagName: /^(INPUT|TEXTAREA|BUTTON|SELECT|LABEL)$/ },
30294
30295        HWCompositing: true,
30296        useTransition: true,
30297        useTransform: true,
30298        bindToWrapper: typeof window.onmousedown === "undefined"
30299    };
30300
30301    for ( var i in options ) {
30302        this.options[i] = options[i];
30303    }
30304
30305    // Normalize options
30306    this.translateZ = this.options.HWCompositing && utils.hasPerspective ? ' translateZ(0)' : '';
30307
30308    this.options.useTransition = utils.hasTransition && this.options.useTransition;
30309    this.options.useTransform = utils.hasTransform && this.options.useTransform;
30310
30311    this.options.eventPassthrough = this.options.eventPassthrough === true ? 'vertical' : this.options.eventPassthrough;
30312    this.options.preventDefault = !this.options.eventPassthrough && this.options.preventDefault;
30313
30314    // If you want eventPassthrough I have to lock one of the axes
30315    this.options.scrollY = this.options.eventPassthrough == 'vertical' ? false : this.options.scrollY;
30316    this.options.scrollX = this.options.eventPassthrough == 'horizontal' ? false : this.options.scrollX;
30317
30318    // With eventPassthrough we also need lockDirection mechanism
30319    this.options.freeScroll = this.options.freeScroll && !this.options.eventPassthrough;
30320    this.options.directionLockThreshold = this.options.eventPassthrough ? 0 : this.options.directionLockThreshold;
30321
30322    this.options.bounceEasing = typeof this.options.bounceEasing == 'string' ? utils.ease[this.options.bounceEasing] || utils.ease.circular : this.options.bounceEasing;
30323
30324    this.options.resizePolling = this.options.resizePolling === undefined ? 60 : this.options.resizePolling;
30325
30326    if ( this.options.tap === true ) {
30327        this.options.tap = 'tap';
30328    }
30329
30330    // https://github.com/cubiq/iscroll/issues/1029
30331    if (!this.options.useTransition && !this.options.useTransform) {
30332        if(!(/relative|absolute/i).test(this.scrollerStyle.position)) {
30333            this.scrollerStyle.position = "relative";
30334        }
30335    }
30336
30337    if ( this.options.shrinkScrollbars == 'scale' ) {
30338        this.options.useTransition = false;
30339    }
30340
30341    this.options.invertWheelDirection = this.options.invertWheelDirection ? -1 : 1;
30342
30343// INSERT POINT: NORMALIZATION
30344
30345    // Some defaults
30346    this.x = 0;
30347    this.y = 0;
30348    this.directionX = 0;
30349    this.directionY = 0;
30350    this._events = {};
30351
30352// INSERT POINT: DEFAULTS
30353
30354    this._init();
30355    this.refresh();
30356
30357    this.scrollTo(this.options.startX, this.options.startY);
30358    this.enable();
30359}
30360
30361IScroll.prototype = {
30362    version: '5.2.0',
30363
30364    _init: function () {
30365        this._initEvents();
30366
30367        if ( this.options.scrollbars || this.options.indicators ) {
30368            this._initIndicators();
30369        }
30370
30371        if ( this.options.mouseWheel ) {
30372            this._initWheel();
30373        }
30374
30375        if ( this.options.snap ) {
30376            this._initSnap();
30377        }
30378
30379        if ( this.options.keyBindings ) {
30380            this._initKeys();
30381        }
30382
30383// INSERT POINT: _init
30384
30385    },
30386
30387    destroy: function () {
30388        this._initEvents(true);
30389        clearTimeout(this.resizeTimeout);
30390        this.resizeTimeout = null;
30391        this._execEvent('destroy');
30392    },
30393
30394    _transitionEnd: function (e) {
30395        if ( e.target != this.scroller || !this.isInTransition ) {
30396            return;
30397        }
30398
30399        this._transitionTime();
30400        if ( !this.resetPosition(this.options.bounceTime) ) {
30401            this.isInTransition = false;
30402            this._execEvent('scrollEnd');
30403        }
30404    },
30405
30406    _start: function (e) {
30407        // React to left mouse button only
30408        if ( utils.eventType[e.type] != 1 ) {
30409          // for button property
30410          // http://unixpapa.com/js/mouse.html
30411          var button;
30412        if (!e.which) {
30413          /* IE case */
30414          button = (e.button < 2) ? 0 :
30415                   ((e.button == 4) ? 1 : 2);
30416        } else {
30417          /* All others */
30418          button = e.button;
30419        }
30420            if ( button !== 0 ) {
30421                return;
30422            }
30423        }
30424
30425        if ( !this.enabled || (this.initiated && utils.eventType[e.type] !== this.initiated) ) {
30426            return;
30427        }
30428
30429        if ( this.options.preventDefault && !utils.isBadAndroid && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
30430            e.preventDefault();
30431        }
30432
30433        var point = e.touches ? e.touches[0] : e,
30434            pos;
30435
30436        this.initiated  = utils.eventType[e.type];
30437        this.moved      = false;
30438        this.distX      = 0;
30439        this.distY      = 0;
30440        this.directionX = 0;
30441        this.directionY = 0;
30442        this.directionLocked = 0;
30443
30444        this.startTime = utils.getTime();
30445
30446        if ( this.options.useTransition && this.isInTransition ) {
30447            this._transitionTime();
30448            this.isInTransition = false;
30449            pos = this.getComputedPosition();
30450            this._translate(Math.round(pos.x), Math.round(pos.y));
30451            this._execEvent('scrollEnd');
30452        } else if ( !this.options.useTransition && this.isAnimating ) {
30453            this.isAnimating = false;
30454            this._execEvent('scrollEnd');
30455        }
30456
30457        this.startX    = this.x;
30458        this.startY    = this.y;
30459        this.absStartX = this.x;
30460        this.absStartY = this.y;
30461        this.pointX    = point.pageX;
30462        this.pointY    = point.pageY;
30463
30464        this._execEvent('beforeScrollStart');
30465    },
30466
30467    _move: function (e) {
30468        if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
30469            return;
30470        }
30471
30472        if ( this.options.preventDefault ) {    // increases performance on Android? TODO: check!
30473            e.preventDefault();
30474        }
30475
30476        var point       = e.touches ? e.touches[0] : e,
30477            deltaX      = point.pageX - this.pointX,
30478            deltaY      = point.pageY - this.pointY,
30479            timestamp   = utils.getTime(),
30480            newX, newY,
30481            absDistX, absDistY;
30482
30483        this.pointX     = point.pageX;
30484        this.pointY     = point.pageY;
30485
30486        this.distX      += deltaX;
30487        this.distY      += deltaY;
30488        absDistX        = Math.abs(this.distX);
30489        absDistY        = Math.abs(this.distY);
30490
30491        // We need to move at least 10 pixels for the scrolling to initiate
30492        if ( timestamp - this.endTime > 300 && (absDistX < 10 && absDistY < 10) ) {
30493            return;
30494        }
30495
30496        // If you are scrolling in one direction lock the other
30497        if ( !this.directionLocked && !this.options.freeScroll ) {
30498            if ( absDistX > absDistY + this.options.directionLockThreshold ) {
30499                this.directionLocked = 'h';     // lock horizontally
30500            } else if ( absDistY >= absDistX + this.options.directionLockThreshold ) {
30501                this.directionLocked = 'v';     // lock vertically
30502            } else {
30503                this.directionLocked = 'n';     // no lock
30504            }
30505        }
30506
30507        if ( this.directionLocked == 'h' ) {
30508            if ( this.options.eventPassthrough == 'vertical' ) {
30509                e.preventDefault();
30510            } else if ( this.options.eventPassthrough == 'horizontal' ) {
30511                this.initiated = false;
30512                return;
30513            }
30514
30515            deltaY = 0;
30516        } else if ( this.directionLocked == 'v' ) {
30517            if ( this.options.eventPassthrough == 'horizontal' ) {
30518                e.preventDefault();
30519            } else if ( this.options.eventPassthrough == 'vertical' ) {
30520                this.initiated = false;
30521                return;
30522            }
30523
30524            deltaX = 0;
30525        }
30526
30527        deltaX = this.hasHorizontalScroll ? deltaX : 0;
30528        deltaY = this.hasVerticalScroll ? deltaY : 0;
30529
30530        newX = this.x + deltaX;
30531        newY = this.y + deltaY;
30532
30533        // Slow down if outside of the boundaries
30534        if ( newX > 0 || newX < this.maxScrollX ) {
30535            newX = this.options.bounce ? this.x + deltaX / 3 : newX > 0 ? 0 : this.maxScrollX;
30536        }
30537        if ( newY > 0 || newY < this.maxScrollY ) {
30538            newY = this.options.bounce ? this.y + deltaY / 3 : newY > 0 ? 0 : this.maxScrollY;
30539        }
30540
30541        this.directionX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
30542        this.directionY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;
30543
30544        if ( !this.moved ) {
30545            this._execEvent('scrollStart');
30546        }
30547
30548        this.moved = true;
30549
30550        this._translate(newX, newY);
30551
30552/* REPLACE START: _move */
30553
30554        if ( timestamp - this.startTime > 300 ) {
30555            this.startTime = timestamp;
30556            this.startX = this.x;
30557            this.startY = this.y;
30558        }
30559
30560/* REPLACE END: _move */
30561
30562    },
30563
30564    _end: function (e) {
30565        if ( !this.enabled || utils.eventType[e.type] !== this.initiated ) {
30566            return;
30567        }
30568
30569        if ( this.options.preventDefault && !utils.preventDefaultException(e.target, this.options.preventDefaultException) ) {
30570            e.preventDefault();
30571        }
30572
30573        var point = e.changedTouches ? e.changedTouches[0] : e,
30574            momentumX,
30575            momentumY,
30576            duration = utils.getTime() - this.startTime,
30577            newX = Math.round(this.x),
30578            newY = Math.round(this.y),
30579            distanceX = Math.abs(newX - this.startX),
30580            distanceY = Math.abs(newY - this.startY),
30581            time = 0,
30582            easing = '';
30583
30584        this.isInTransition = 0;
30585        this.initiated = 0;
30586        this.endTime = utils.getTime();
30587
30588        // reset if we are outside of the boundaries
30589        if ( this.resetPosition(this.options.bounceTime) ) {
30590            return;
30591        }
30592
30593        this.scrollTo(newX, newY);  // ensures that the last position is rounded
30594
30595        // we scrolled less than 10 pixels
30596        if ( !this.moved ) {
30597            if ( this.options.tap ) {
30598                utils.tap(e, this.options.tap);
30599            }
30600
30601            if ( this.options.click ) {
30602                utils.click(e);
30603            }
30604
30605            this._execEvent('scrollCancel');
30606            return;
30607        }
30608
30609        if ( this._events.flick && duration < 200 && distanceX < 100 && distanceY < 100 ) {
30610            this._execEvent('flick');
30611            return;
30612        }
30613
30614        // start momentum animation if needed
30615        if ( this.options.momentum && duration < 300 ) {
30616            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 };
30617            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 };
30618            newX = momentumX.destination;
30619            newY = momentumY.destination;
30620            time = Math.max(momentumX.duration, momentumY.duration);
30621            this.isInTransition = 1;
30622        }
30623
30624
30625        if ( this.options.snap ) {
30626            var snap = this._nearestSnap(newX, newY);
30627            this.currentPage = snap;
30628            time = this.options.snapSpeed || Math.max(
30629                    Math.max(
30630                        Math.min(Math.abs(newX - snap.x), 1000),
30631                        Math.min(Math.abs(newY - snap.y), 1000)
30632                    ), 300);
30633            newX = snap.x;
30634            newY = snap.y;
30635
30636            this.directionX = 0;
30637            this.directionY = 0;
30638            easing = this.options.bounceEasing;
30639        }
30640
30641// INSERT POINT: _end
30642
30643        if ( newX != this.x || newY != this.y ) {
30644            // change easing function when scroller goes out of the boundaries
30645            if ( newX > 0 || newX < this.maxScrollX || newY > 0 || newY < this.maxScrollY ) {
30646                easing = utils.ease.quadratic;
30647            }
30648
30649            this.scrollTo(newX, newY, time, easing);
30650            return;
30651        }
30652
30653        this._execEvent('scrollEnd');
30654    },
30655
30656    _resize: function () {
30657        var that = this;
30658
30659        clearTimeout(this.resizeTimeout);
30660
30661        this.resizeTimeout = setTimeout(function () {
30662            that.refresh();
30663        }, this.options.resizePolling);
30664    },
30665
30666    resetPosition: function (time) {
30667        var x = this.x,
30668            y = this.y;
30669
30670        time = time || 0;
30671
30672        if ( !this.hasHorizontalScroll || this.x > 0 ) {
30673            x = 0;
30674        } else if ( this.x < this.maxScrollX ) {
30675            x = this.maxScrollX;
30676        }
30677
30678        if ( !this.hasVerticalScroll || this.y > 0 ) {
30679            y = 0;
30680        } else if ( this.y < this.maxScrollY ) {
30681            y = this.maxScrollY;
30682        }
30683
30684        if ( x == this.x && y == this.y ) {
30685            return false;
30686        }
30687
30688        this.scrollTo(x, y, time, this.options.bounceEasing);
30689
30690        return true;
30691    },
30692
30693    disable: function () {
30694        this.enabled = false;
30695    },
30696
30697    enable: function () {
30698        this.enabled = true;
30699    },
30700
30701    refresh: function () {
30702        var rf = this.wrapper.offsetHeight;     // Force reflow
30703
30704        this.wrapperWidth   = this.wrapper.clientWidth;
30705        this.wrapperHeight  = this.wrapper.clientHeight;
30706
30707/* REPLACE START: refresh */
30708
30709        this.scrollerWidth  = this.scroller.offsetWidth;
30710        this.scrollerHeight = this.scroller.offsetHeight;
30711
30712        this.maxScrollX     = this.wrapperWidth - this.scrollerWidth;
30713        this.maxScrollY     = this.wrapperHeight - this.scrollerHeight;
30714
30715/* REPLACE END: refresh */
30716
30717        this.hasHorizontalScroll    = this.options.scrollX && this.maxScrollX < 0;
30718        this.hasVerticalScroll      = this.options.scrollY && this.maxScrollY < 0;
30719
30720        if ( !this.hasHorizontalScroll ) {
30721            this.maxScrollX = 0;
30722            this.scrollerWidth = this.wrapperWidth;
30723        }
30724
30725        if ( !this.hasVerticalScroll ) {
30726            this.maxScrollY = 0;
30727            this.scrollerHeight = this.wrapperHeight;
30728        }
30729
30730        this.endTime = 0;
30731        this.directionX = 0;
30732        this.directionY = 0;
30733
30734        this.wrapperOffset = utils.offset(this.wrapper);
30735
30736        this._execEvent('refresh');
30737
30738        this.resetPosition();
30739
30740// INSERT POINT: _refresh
30741
30742    },
30743
30744
30745    on: function (type, fn) {
30746        if ( !this._events[type] ) {
30747            this._events[type] = [];
30748        }
30749
30750        this._events[type].push(fn);
30751    },
30752
30753    off: function (type, fn) {
30754        if ( !this._events[type] ) {
30755            return;
30756        }
30757
30758        var index = this._events[type].indexOf(fn);
30759
30760        if ( index > -1 ) {
30761            this._events[type].splice(index, 1);
30762        }
30763    },
30764
30765    _execEvent: function (type) {
30766        if ( !this._events[type] ) {
30767            return;
30768        }
30769
30770        var i = 0,
30771            l = this._events[type].length;
30772
30773        if ( !l ) {
30774            return;
30775        }
30776
30777        for ( ; i < l; i++ ) {
30778            this._events[type][i].apply(this, [].slice.call(arguments, 1));
30779        }
30780    },
30781
30782    scrollBy: function (x, y, time, easing) {
30783        x = this.x + x;
30784        y = this.y + y;
30785        time = time || 0;
30786
30787        this.scrollTo(x, y, time, easing);
30788    },
30789
30790    scrollTo: function (x, y, time, easing) {
30791        easing = easing || utils.ease.circular;
30792
30793        this.isInTransition = this.options.useTransition && time > 0;
30794        var transitionType = this.options.useTransition && easing.style;
30795        if ( !time || transitionType ) {
30796                if(transitionType) {
30797                    this._transitionTimingFunction(easing.style);
30798                    this._transitionTime(time);
30799                }
30800            this._translate(x, y);
30801        } else {
30802            this._animate(x, y, time, easing.fn);
30803        }
30804    },
30805
30806    scrollToElement: function (el, time, offsetX, offsetY, easing) {
30807        el = el.nodeType ? el : this.scroller.querySelector(el);
30808
30809        if ( !el ) {
30810            return;
30811        }
30812
30813        var pos = utils.offset(el);
30814
30815        pos.left -= this.wrapperOffset.left;
30816        pos.top  -= this.wrapperOffset.top;
30817
30818        // if offsetX/Y are true we center the element to the screen
30819        if ( offsetX === true ) {
30820            offsetX = Math.round(el.offsetWidth / 2 - this.wrapper.offsetWidth / 2);
30821        }
30822        if ( offsetY === true ) {
30823            offsetY = Math.round(el.offsetHeight / 2 - this.wrapper.offsetHeight / 2);
30824        }
30825
30826        pos.left -= offsetX || 0;
30827        pos.top  -= offsetY || 0;
30828
30829        pos.left = pos.left > 0 ? 0 : pos.left < this.maxScrollX ? this.maxScrollX : pos.left;
30830        pos.top  = pos.top  > 0 ? 0 : pos.top  < this.maxScrollY ? this.maxScrollY : pos.top;
30831
30832        time = time === undefined || time === null || time === 'auto' ? Math.max(Math.abs(this.x-pos.left), Math.abs(this.y-pos.top)) : time;
30833
30834        this.scrollTo(pos.left, pos.top, time, easing);
30835    },
30836
30837    _transitionTime: function (time) {
30838        if (!this.options.useTransition) {
30839            return;
30840        }
30841        time = time || 0;
30842        var durationProp = utils.style.transitionDuration;
30843        if(!durationProp) {
30844            return;
30845        }
30846
30847        this.scrollerStyle[durationProp] = time + 'ms';
30848
30849        if ( !time && utils.isBadAndroid ) {
30850            this.scrollerStyle[durationProp] = '0.0001ms';
30851            // remove 0.0001ms
30852            var self = this;
30853            rAF(function() {
30854                if(self.scrollerStyle[durationProp] === '0.0001ms') {
30855                    self.scrollerStyle[durationProp] = '0s';
30856                }
30857            });
30858        }
30859
30860
30861        if ( this.indicators ) {
30862            for ( var i = this.indicators.length; i--; ) {
30863                this.indicators[i].transitionTime(time);
30864            }
30865        }
30866
30867
30868// INSERT POINT: _transitionTime
30869
30870    },
30871
30872    _transitionTimingFunction: function (easing) {
30873        this.scrollerStyle[utils.style.transitionTimingFunction] = easing;
30874
30875
30876        if ( this.indicators ) {
30877            for ( var i = this.indicators.length; i--; ) {
30878                this.indicators[i].transitionTimingFunction(easing);
30879            }
30880        }
30881
30882
30883// INSERT POINT: _transitionTimingFunction
30884
30885    },
30886
30887    _translate: function (x, y) {
30888        //Uncode addition
30889        if ( (" " + this.wrapper.className + " ").replace(/[\n\t]/g, " ").indexOf(" no-scrolloverflow ") > -1 )
30890            return false;
30891
30892        if ( this.options.useTransform ) {
30893
30894/* REPLACE START: _translate */
30895
30896            this.scrollerStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.translateZ;
30897
30898/* REPLACE END: _translate */
30899
30900        } else {
30901            x = Math.round(x);
30902            y = Math.round(y);
30903            this.scrollerStyle.left = x + 'px';
30904            this.scrollerStyle.top = y + 'px';
30905        }
30906
30907        this.x = x;
30908        this.y = y;
30909
30910
30911        if ( this.indicators ) {
30912            for ( var i = this.indicators.length; i--; ) {
30913                this.indicators[i].updatePosition();
30914            }
30915        }
30916
30917        //Uncode addition
30918        var uncodevent = new CustomEvent('fp-slide-scroll');
30919        window.dispatchEvent(uncodevent);
30920
30921// INSERT POINT: _translate
30922
30923    },
30924
30925    _initEvents: function (remove) {
30926        var eventType = remove ? utils.removeEvent : utils.addEvent,
30927            target = this.options.bindToWrapper ? this.wrapper : window;
30928
30929        eventType(window, 'orientationchange', this);
30930        eventType(window, 'resize', this);
30931
30932        if ( this.options.click ) {
30933            eventType(this.wrapper, 'click', this, true);
30934        }
30935
30936        if ( !this.options.disableMouse ) {
30937            eventType(this.wrapper, 'mousedown', this);
30938            eventType(target, 'mousemove', this);
30939            eventType(target, 'mousecancel', this);
30940            eventType(target, 'mouseup', this);
30941        }
30942
30943        if ( utils.hasPointer && !this.options.disablePointer ) {
30944            eventType(this.wrapper, utils.prefixPointerEvent('pointerdown'), this);
30945            eventType(target, utils.prefixPointerEvent('pointermove'), this);
30946            eventType(target, utils.prefixPointerEvent('pointercancel'), this);
30947            eventType(target, utils.prefixPointerEvent('pointerup'), this);
30948        }
30949
30950        if ( utils.hasTouch && !this.options.disableTouch ) {
30951            eventType(this.wrapper, 'touchstart', this);
30952            eventType(target, 'touchmove', this);
30953            eventType(target, 'touchcancel', this);
30954            eventType(target, 'touchend', this);
30955        }
30956
30957        eventType(this.scroller, 'transitionend', this);
30958        eventType(this.scroller, 'webkitTransitionEnd', this);
30959        eventType(this.scroller, 'oTransitionEnd', this);
30960        eventType(this.scroller, 'MSTransitionEnd', this);
30961    },
30962
30963    getComputedPosition: function () {
30964        var matrix = window.getComputedStyle(this.scroller, null),
30965            x, y;
30966
30967        if ( this.options.useTransform ) {
30968            matrix = matrix[utils.style.transform].split(')')[0].split(', ');
30969            x = +(matrix[12] || matrix[4]);
30970            y = +(matrix[13] || matrix[5]);
30971        } else {
30972            x = +matrix.left.replace(/[^-\d.]/g, '');
30973            y = +matrix.top.replace(/[^-\d.]/g, '');
30974        }
30975
30976        return { x: x, y: y };
30977    },
30978    _initIndicators: function () {
30979        var interactive = this.options.interactiveScrollbars,
30980            customStyle = typeof this.options.scrollbars != 'string',
30981            indicators = [],
30982            indicator;
30983
30984        var that = this;
30985
30986        this.indicators = [];
30987
30988        if ( this.options.scrollbars ) {
30989            // Vertical scrollbar
30990            if ( this.options.scrollY ) {
30991                indicator = {
30992                    el: createDefaultScrollbar('v', interactive, this.options.scrollbars),
30993                    interactive: interactive,
30994                    defaultScrollbars: true,
30995                    customStyle: customStyle,
30996                    resize: this.options.resizeScrollbars,
30997                    shrink: this.options.shrinkScrollbars,
30998                    fade: this.options.fadeScrollbars,
30999                    listenX: false
31000                };
31001
31002                this.wrapper.appendChild(indicator.el);
31003                indicators.push(indicator);
31004            }
31005
31006            // Horizontal scrollbar
31007            if ( this.options.scrollX ) {
31008                indicator = {
31009                    el: createDefaultScrollbar('h', interactive, this.options.scrollbars),
31010                    interactive: interactive,
31011                    defaultScrollbars: true,
31012                    customStyle: customStyle,
31013                    resize: this.options.resizeScrollbars,
31014                    shrink: this.options.shrinkScrollbars,
31015                    fade: this.options.fadeScrollbars,
31016                    listenY: false
31017                };
31018
31019                this.wrapper.appendChild(indicator.el);
31020                indicators.push(indicator);
31021            }
31022        }
31023
31024        if ( this.options.indicators ) {
31025            // TODO: check concat compatibility
31026            indicators = indicators.concat(this.options.indicators);
31027        }
31028
31029        for ( var i = indicators.length; i--; ) {
31030            this.indicators.push( new Indicator(this, indicators[i]) );
31031        }
31032
31033        // TODO: check if we can use array.map (wide compatibility and performance issues)
31034        function _indicatorsMap (fn) {
31035            if (that.indicators) {
31036                for ( var i = that.indicators.length; i--; ) {
31037                    fn.call(that.indicators[i]);
31038                }
31039            }
31040        }
31041
31042        if ( this.options.fadeScrollbars ) {
31043            this.on('scrollEnd', function () {
31044                _indicatorsMap(function () {
31045                    this.fade();
31046                });
31047            });
31048
31049            this.on('scrollCancel', function () {
31050                _indicatorsMap(function () {
31051                    this.fade();
31052                });
31053            });
31054
31055            this.on('scrollStart', function () {
31056                _indicatorsMap(function () {
31057                    this.fade(1);
31058                });
31059            });
31060
31061            this.on('beforeScrollStart', function () {
31062                _indicatorsMap(function () {
31063                    this.fade(1, true);
31064                });
31065            });
31066        }
31067
31068
31069        this.on('refresh', function () {
31070            _indicatorsMap(function () {
31071                this.refresh();
31072            });
31073        });
31074
31075        this.on('destroy', function () {
31076            _indicatorsMap(function () {
31077                this.destroy();
31078            });
31079
31080            delete this.indicators;
31081        });
31082    },
31083
31084    _initWheel: function () {
31085        utils.addEvent(this.wrapper, 'wheel', this);
31086        utils.addEvent(this.wrapper, 'mousewheel', this);
31087        utils.addEvent(this.wrapper, 'DOMMouseScroll', this);
31088
31089        this.on('destroy', function () {
31090            clearTimeout(this.wheelTimeout);
31091            this.wheelTimeout = null;
31092            utils.removeEvent(this.wrapper, 'wheel', this);
31093            utils.removeEvent(this.wrapper, 'mousewheel', this);
31094            utils.removeEvent(this.wrapper, 'DOMMouseScroll', this);
31095        });
31096    },
31097
31098    _wheel: function (e) {
31099        if ( !this.enabled ) {
31100            return;
31101        }
31102
31103        var wheelDeltaX, wheelDeltaY,
31104            newX, newY,
31105            that = this;
31106
31107        if ( this.wheelTimeout === undefined ) {
31108            that._execEvent('scrollStart');
31109        }
31110
31111        // Execute the scrollEnd event after 400ms the wheel stopped scrolling
31112        clearTimeout(this.wheelTimeout);
31113        this.wheelTimeout = setTimeout(function () {
31114            if(!that.options.snap) {
31115                that._execEvent('scrollEnd');
31116            }
31117            that.wheelTimeout = undefined;
31118        }, 400);
31119
31120        if ( 'deltaX' in e ) {
31121            if (e.deltaMode === 1) {
31122                wheelDeltaX = -e.deltaX * this.options.mouseWheelSpeed;
31123                wheelDeltaY = -e.deltaY * this.options.mouseWheelSpeed;
31124            } else {
31125                wheelDeltaX = -e.deltaX;
31126                wheelDeltaY = -e.deltaY;
31127            }
31128        } else if ( 'wheelDeltaX' in e ) {
31129            wheelDeltaX = e.wheelDeltaX / 120 * this.options.mouseWheelSpeed;
31130            wheelDeltaY = e.wheelDeltaY / 120 * this.options.mouseWheelSpeed;
31131        } else if ( 'wheelDelta' in e ) {
31132            wheelDeltaX = wheelDeltaY = e.wheelDelta / 120 * this.options.mouseWheelSpeed;
31133        } else if ( 'detail' in e ) {
31134            wheelDeltaX = wheelDeltaY = -e.detail / 3 * this.options.mouseWheelSpeed;
31135        } else {
31136            return;
31137        }
31138
31139        wheelDeltaX *= this.options.invertWheelDirection;
31140        wheelDeltaY *= this.options.invertWheelDirection;
31141
31142        if ( !this.hasVerticalScroll ) {
31143            wheelDeltaX = wheelDeltaY;
31144            wheelDeltaY = 0;
31145        }
31146
31147        if ( this.options.snap ) {
31148            newX = this.currentPage.pageX;
31149            newY = this.currentPage.pageY;
31150
31151            if ( wheelDeltaX > 0 ) {
31152                newX--;
31153            } else if ( wheelDeltaX < 0 ) {
31154                newX++;
31155            }
31156
31157            if ( wheelDeltaY > 0 ) {
31158                newY--;
31159            } else if ( wheelDeltaY < 0 ) {
31160                newY++;
31161            }
31162
31163            this.goToPage(newX, newY);
31164
31165            return;
31166        }
31167
31168        newX = this.x + Math.round(this.hasHorizontalScroll ? wheelDeltaX : 0);
31169        newY = this.y + Math.round(this.hasVerticalScroll ? wheelDeltaY : 0);
31170
31171        this.directionX = wheelDeltaX > 0 ? -1 : wheelDeltaX < 0 ? 1 : 0;
31172        this.directionY = wheelDeltaY > 0 ? -1 : wheelDeltaY < 0 ? 1 : 0;
31173
31174        if ( newX > 0 ) {
31175            newX = 0;
31176        } else if ( newX < this.maxScrollX ) {
31177            newX = this.maxScrollX;
31178        }
31179
31180        if ( newY > 0 ) {
31181            newY = 0;
31182        } else if ( newY < this.maxScrollY ) {
31183            newY = this.maxScrollY;
31184        }
31185
31186        this.scrollTo(newX, newY, 0);
31187
31188// INSERT POINT: _wheel
31189    },
31190
31191    _initSnap: function () {
31192        this.currentPage = {};
31193
31194        if ( typeof this.options.snap == 'string' ) {
31195            this.options.snap = this.scroller.querySelectorAll(this.options.snap);
31196        }
31197
31198        this.on('refresh', function () {
31199            var i = 0, l,
31200                m = 0, n,
31201                cx, cy,
31202                x = 0, y,
31203                stepX = this.options.snapStepX || this.wrapperWidth,
31204                stepY = this.options.snapStepY || this.wrapperHeight,
31205                el;
31206
31207            this.pages = [];
31208
31209            if ( !this.wrapperWidth || !this.wrapperHeight || !this.scrollerWidth || !this.scrollerHeight ) {
31210                return;
31211            }
31212
31213            if ( this.options.snap === true ) {
31214                cx = Math.round( stepX / 2 );
31215                cy = Math.round( stepY / 2 );
31216
31217                while ( x > -this.scrollerWidth ) {
31218                    this.pages[i] = [];
31219                    l = 0;
31220                    y = 0;
31221
31222                    while ( y > -this.scrollerHeight ) {
31223                        this.pages[i][l] = {
31224                            x: Math.max(x, this.maxScrollX),
31225                            y: Math.max(y, this.maxScrollY),
31226                            width: stepX,
31227                            height: stepY,
31228                            cx: x - cx,
31229                            cy: y - cy
31230                        };
31231
31232                        y -= stepY;
31233                        l++;
31234                    }
31235
31236                    x -= stepX;
31237                    i++;
31238                }
31239            } else {
31240                el = this.options.snap;
31241                l = el.length;
31242                n = -1;
31243
31244                for ( ; i < l; i++ ) {
31245                    if ( i === 0 || el[i].offsetLeft <= el[i-1].offsetLeft ) {
31246                        m = 0;
31247                        n++;
31248                    }
31249
31250                    if ( !this.pages[m] ) {
31251                        this.pages[m] = [];
31252                    }
31253
31254                    x = Math.max(-el[i].offsetLeft, this.maxScrollX);
31255                    y = Math.max(-el[i].offsetTop, this.maxScrollY);
31256                    cx = x - Math.round(el[i].offsetWidth / 2);
31257                    cy = y - Math.round(el[i].offsetHeight / 2);
31258
31259                    this.pages[m][n] = {
31260                        x: x,
31261                        y: y,
31262                        width: el[i].offsetWidth,
31263                        height: el[i].offsetHeight,
31264                        cx: cx,
31265                        cy: cy
31266                    };
31267
31268                    if ( x > this.maxScrollX ) {
31269                        m++;
31270                    }
31271                }
31272            }
31273
31274            this.goToPage(this.currentPage.pageX || 0, this.currentPage.pageY || 0, 0);
31275
31276            // Update snap threshold if needed
31277            if ( this.options.snapThreshold % 1 === 0 ) {
31278                this.snapThresholdX = this.options.snapThreshold;
31279                this.snapThresholdY = this.options.snapThreshold;
31280            } else {
31281                this.snapThresholdX = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].width * this.options.snapThreshold);
31282                this.snapThresholdY = Math.round(this.pages[this.currentPage.pageX][this.currentPage.pageY].height * this.options.snapThreshold);
31283            }
31284        });
31285
31286        this.on('flick', function () {
31287            var time = this.options.snapSpeed || Math.max(
31288                    Math.max(
31289                        Math.min(Math.abs(this.x - this.startX), 1000),
31290                        Math.min(Math.abs(this.y - this.startY), 1000)
31291                    ), 300);
31292
31293            this.goToPage(
31294                this.currentPage.pageX + this.directionX,
31295                this.currentPage.pageY + this.directionY,
31296                time
31297            );
31298        });
31299    },
31300
31301    _nearestSnap: function (x, y) {
31302        if ( !this.pages.length ) {
31303            return { x: 0, y: 0, pageX: 0, pageY: 0 };
31304        }
31305
31306        var i = 0,
31307            l = this.pages.length,
31308            m = 0;
31309
31310        // Check if we exceeded the snap threshold
31311        if ( Math.abs(x - this.absStartX) < this.snapThresholdX &&
31312            Math.abs(y - this.absStartY) < this.snapThresholdY ) {
31313            return this.currentPage;
31314        }
31315
31316        if ( x > 0 ) {
31317            x = 0;
31318        } else if ( x < this.maxScrollX ) {
31319            x = this.maxScrollX;
31320        }
31321
31322        if ( y > 0 ) {
31323            y = 0;
31324        } else if ( y < this.maxScrollY ) {
31325            y = this.maxScrollY;
31326        }
31327
31328        for ( ; i < l; i++ ) {
31329            if ( x >= this.pages[i][0].cx ) {
31330                x = this.pages[i][0].x;
31331                break;
31332            }
31333        }
31334
31335        l = this.pages[i].length;
31336
31337        for ( ; m < l; m++ ) {
31338            if ( y >= this.pages[0][m].cy ) {
31339                y = this.pages[0][m].y;
31340                break;
31341            }
31342        }
31343
31344        if ( i == this.currentPage.pageX ) {
31345            i += this.directionX;
31346
31347            if ( i < 0 ) {
31348                i = 0;
31349            } else if ( i >= this.pages.length ) {
31350                i = this.pages.length - 1;
31351            }
31352
31353            x = this.pages[i][0].x;
31354        }
31355
31356        if ( m == this.currentPage.pageY ) {
31357            m += this.directionY;
31358
31359            if ( m < 0 ) {
31360                m = 0;
31361            } else if ( m >= this.pages[0].length ) {
31362                m = this.pages[0].length - 1;
31363            }
31364
31365            y = this.pages[0][m].y;
31366        }
31367
31368        return {
31369            x: x,
31370            y: y,
31371            pageX: i,
31372            pageY: m
31373        };
31374    },
31375
31376    goToPage: function (x, y, time, easing) {
31377        easing = easing || this.options.bounceEasing;
31378
31379        if ( x >= this.pages.length ) {
31380            x = this.pages.length - 1;
31381        } else if ( x < 0 ) {
31382            x = 0;
31383        }
31384
31385        if ( y >= this.pages[x].length ) {
31386            y = this.pages[x].length - 1;
31387        } else if ( y < 0 ) {
31388            y = 0;
31389        }
31390
31391        var posX = this.pages[x][y].x,
31392            posY = this.pages[x][y].y;
31393
31394        time = time === undefined ? this.options.snapSpeed || Math.max(
31395            Math.max(
31396                Math.min(Math.abs(posX - this.x), 1000),
31397                Math.min(Math.abs(posY - this.y), 1000)
31398            ), 300) : time;
31399
31400        this.currentPage = {
31401            x: posX,
31402            y: posY,
31403            pageX: x,
31404            pageY: y
31405        };
31406
31407        this.scrollTo(posX, posY, time, easing);
31408    },
31409
31410    next: function (time, easing) {
31411        var x = this.currentPage.pageX,
31412            y = this.currentPage.pageY;
31413
31414        x++;
31415
31416        if ( x >= this.pages.length && this.hasVerticalScroll ) {
31417            x = 0;
31418            y++;
31419        }
31420
31421        this.goToPage(x, y, time, easing);
31422    },
31423
31424    prev: function (time, easing) {
31425        var x = this.currentPage.pageX,
31426            y = this.currentPage.pageY;
31427
31428        x--;
31429
31430        if ( x < 0 && this.hasVerticalScroll ) {
31431            x = 0;
31432            y--;
31433        }
31434
31435        this.goToPage(x, y, time, easing);
31436    },
31437
31438    _initKeys: function (e) {
31439        // default key bindings
31440        var keys = {
31441            pageUp: 33,
31442            pageDown: 34,
31443            end: 35,
31444            home: 36,
31445            left: 37,
31446            up: 38,
31447            right: 39,
31448            down: 40
31449        };
31450        var i;
31451
31452        // if you give me characters I give you keycode
31453        if ( typeof this.options.keyBindings == 'object' ) {
31454            for ( i in this.options.keyBindings ) {
31455                if ( typeof this.options.keyBindings[i] == 'string' ) {
31456                    this.options.keyBindings[i] = this.options.keyBindings[i].toUpperCase().charCo
31456deAt(0);
31457                }
31458            }
31459        } else {
31460            this.options.keyBindings = {};
31461        }
31462
31463        for ( i in keys ) {
31464            this.options.keyBindings[i] = this.options.keyBindings[i] || keys[i];
31465        }
31466
31467        utils.addEvent(window, 'keydown', this);
31468
31469        this.on('destroy', function () {
31470            utils.removeEvent(window, 'keydown', this);
31471        });
31472    },
31473
31474    _key: function (e) {
31475        if ( !this.enabled ) {
31476            return;
31477        }
31478
31479        var snap = this.options.snap,   // we are using this alot, better to cache it
31480            newX = snap ? this.currentPage.pageX : this.x,
31481            newY = snap ? this.currentPage.pageY : this.y,
31482            now = utils.getTime(),
31483            prevTime = this.keyTime || 0,
31484            acceleration = 0.250,
31485            pos;
31486
31487        if ( this.options.useTransition && this.isInTransition ) {
31488            pos = this.getComputedPosition();
31489
31490            this._translate(Math.round(pos.x), Math.round(pos.y));
31491            this.isInTransition = false;
31492        }
31493
31494        this.keyAcceleration = now - prevTime < 200 ? Math.min(this.keyAcceleration + acceleration, 50) : 0;
31495
31496        switch ( e.keyCode ) {
31497            case this.options.keyBindings.pageUp:
31498                if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
31499                    newX += snap ? 1 : this.wrapperWidth;
31500                } else {
31501                    newY += snap ? 1 : this.wrapperHeight;
31502                }
31503                break;
31504            case this.options.keyBindings.pageDown:
31505                if ( this.hasHorizontalScroll && !this.hasVerticalScroll ) {
31506                    newX -= snap ? 1 : this.wrapperWidth;
31507                } else {
31508                    newY -= snap ? 1 : this.wrapperHeight;
31509                }
31510                break;
31511            case this.options.keyBindings.end:
31512                newX = snap ? this.pages.length-1 : this.maxScrollX;
31513                newY = snap ? this.pages[0].length-1 : this.maxScrollY;
31514                break;
31515            case this.options.keyBindings.home:
31516                newX = 0;
31517                newY = 0;
31518                break;
31519            case this.options.keyBindings.left:
31520                newX += snap ? -1 : 5 + this.keyAcceleration>>0;
31521                break;
31522            case this.options.keyBindings.up:
31523                newY += snap ? 1 : 5 + this.keyAcceleration>>0;
31524                break;
31525            case this.options.keyBindings.right:
31526                newX -= snap ? -1 : 5 + this.keyAcceleration>>0;
31527                break;
31528            case this.options.keyBindings.down:
31529                newY -= snap ? 1 : 5 + this.keyAcceleration>>0;
31530                break;
31531            default:
31532                return;
31533        }
31534
31535        if ( snap ) {
31536            this.goToPage(newX, newY);
31537            return;
31538        }
31539
31540        if ( newX > 0 ) {
31541            newX = 0;
31542            this.keyAcceleration = 0;
31543        } else if ( newX < this.maxScrollX ) {
31544            newX = this.maxScrollX;
31545            this.keyAcceleration = 0;
31546        }
31547
31548        if ( newY > 0 ) {
31549            newY = 0;
31550            this.keyAcceleration = 0;
31551        } else if ( newY < this.maxScrollY ) {
31552            newY = this.maxScrollY;
31553            this.keyAcceleration = 0;
31554        }
31555
31556        this.scrollTo(newX, newY, 0);
31557
31558        this.keyTime = now;
31559    },
31560
31561    _animate: function (destX, destY, duration, easingFn) {
31562        var that = this,
31563            startX = this.x,
31564            startY = this.y,
31565            startTime = utils.getTime(),
31566            destTime = startTime + duration;
31567
31568        function step () {
31569            var now = utils.getTime(),
31570                newX, newY,
31571                easing;
31572
31573            if ( now >= destTime ) {
31574                that.isAnimating = false;
31575                that._translate(destX, destY);
31576
31577                if ( !that.resetPosition(that.options.bounceTime) ) {
31578                    that._execEvent('scrollEnd');
31579                }
31580
31581                return;
31582            }
31583
31584            now = ( now - startTime ) / duration;
31585            easing = easingFn(now);
31586            newX = ( destX - startX ) * easing + startX;
31587            newY = ( destY - startY ) * easing + startY;
31588            that._translate(newX, newY);
31589
31590            if ( that.isAnimating ) {
31591                rAF(step);
31592            }
31593        }
31594
31595        this.isAnimating = true;
31596        step();
31597    },
31598    handleEvent: function (e) {
31599        switch ( e.type ) {
31600            case 'touchstart':
31601            case 'pointerdown':
31602            case 'MSPointerDown':
31603            case 'mousedown':
31604                this._start(e);
31605                break;
31606            case 'touchmove':
31607            case 'pointermove':
31608            case 'MSPointerMove':
31609            case 'mousemove':
31610                this._move(e);
31611                break;
31612            case 'touchend':
31613            case 'pointerup':
31614            case 'MSPointerUp':
31615            case 'mouseup':
31616            case 'touchcancel':
31617            case 'pointercancel':
31618            case 'MSPointerCancel':
31619            case 'mousecancel':
31620                this._end(e);
31621                break;
31622            case 'orientationchange':
31623            case 'resize':
31624                this._resize();
31625                break;
31626            case 'transitionend':
31627            case 'webkitTransitionEnd':
31628            case 'oTransitionEnd':
31629            case 'MSTransitionEnd':
31630                this._transitionEnd(e);
31631                break;
31632            case 'wheel':
31633            case 'DOMMouseScroll':
31634            case 'mousewheel':
31635                this._wheel(e);
31636                break;
31637            case 'keydown':
31638                this._key(e);
31639                break;
31640            case 'click':
31641                if ( this.enabled && !e._constructed ) {
31642                    e.preventDefault();
31643                    e.stopPropagation();
31644                }
31645                break;
31646        }
31647    }
31648};
31649function createDefaultScrollbar (direction, interactive, type) {
31650    var scrollbar = document.createElement('div'),
31651        indicator = document.createElement('div');
31652
31653    if ( type === true ) {
31654        scrollbar.style.cssText = 'position:absolute;z-index:9999';
31655        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';
31656    }
31657
31658    indicator.className = 'iScrollIndicator';
31659
31660    if ( direction == 'h' ) {
31661        if ( type === true ) {
31662            scrollbar.style.cssText += ';height:7px;left:2px;right:2px;bottom:0';
31663            indicator.style.height = '100%';
31664        }
31665        scrollbar.className = 'iScrollHorizontalScrollbar';
31666    } else {
31667        if ( type === true ) {
31668            scrollbar.style.cssText += ';width:7px;bottom:2px;top:2px;right:1px';
31669            indicator.style.width = '100%';
31670        }
31671        scrollbar.className = 'iScrollVerticalScrollbar';
31672    }
31673
31674    scrollbar.style.cssText += ';overflow:hidden';
31675
31676    if ( !interactive ) {
31677        scrollbar.style.pointerEvents = 'none';
31678    }
31679
31680    scrollbar.appendChild(indicator);
31681
31682    return scrollbar;
31683}
31684
31685function Indicator (scroller, options) {
31686    this.wrapper = typeof options.el == 'string' ? document.querySelector(options.el) : options.el;
31687    this.wrapperStyle = this.wrapper.style;
31688    this.indicator = this.wrapper.children[0];
31689    this.indicatorStyle = this.indicator.style;
31690    this.scroller = scroller;
31691
31692    this.options = {
31693        listenX: true,
31694        listenY: true,
31695        interactive: false,
31696        resize: true,
31697        defaultScrollbars: false,
31698        shrink: false,
31699        fade: false,
31700        speedRatioX: 0,
31701        speedRatioY: 0
31702    };
31703
31704    for ( var i in options ) {
31705        this.options[i] = options[i];
31706    }
31707
31708    this.sizeRatioX = 1;
31709    this.sizeRatioY = 1;
31710    this.maxPosX = 0;
31711    this.maxPosY = 0;
31712
31713    if ( this.options.interactive ) {
31714        if ( !this.options.disableTouch ) {
31715            utils.addEvent(this.indicator, 'touchstart', this);
31716            utils.addEvent(window, 'touchend', this);
31717        }
31718        if ( !this.options.disablePointer ) {
31719            utils.addEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
31720            utils.addEvent(window, utils.prefixPointerEvent('pointerup'), this);
31721        }
31722        if ( !this.options.disableMouse ) {
31723            utils.addEvent(this.indicator, 'mousedown', this);
31724            utils.addEvent(window, 'mouseup', this);
31725        }
31726    }
31727
31728    if ( this.options.fade ) {
31729        this.wrapperStyle[utils.style.transform] = this.scroller.translateZ;
31730        var durationProp = utils.style.transitionDuration;
31731        if(!durationProp) {
31732            return;
31733        }
31734        this.wrapperStyle[durationProp] = utils.isBadAndroid ? '0.0001ms' : '0ms';
31735        // remove 0.0001ms
31736        var self = this;
31737        if(utils.isBadAndroid) {
31738            rAF(function() {
31739                if(self.wrapperStyle[durationProp] === '0.0001ms') {
31740                    self.wrapperStyle[durationProp] = '0s';
31741                }
31742            });
31743        }
31744        this.wrapperStyle.opacity = '0';
31745    }
31746}
31747
31748Indicator.prototype = {
31749    handleEvent: function (e) {
31750        switch ( e.type ) {
31751            case 'touchstart':
31752            case 'pointerdown':
31753            case 'MSPointerDown':
31754            case 'mousedown':
31755                this._start(e);
31756                break;
31757            case 'touchmove':
31758            case 'pointermove':
31759            case 'MSPointerMove':
31760            case 'mousemove':
31761                this._move(e);
31762                break;
31763            case 'touchend':
31764            case 'pointerup':
31765            case 'MSPointerUp':
31766            case 'mouseup':
31767            case 'touchcancel':
31768            case 'pointercancel':
31769            case 'MSPointerCancel':
31770            case 'mousecancel':
31771                this._end(e);
31772                break;
31773        }
31774    },
31775
31776    destroy: function () {
31777        if ( this.options.fadeScrollbars ) {
31778            clearTimeout(this.fadeTimeout);
31779            this.fadeTimeout = null;
31780        }
31781        if ( this.options.interactive ) {
31782            utils.removeEvent(this.indicator, 'touchstart', this);
31783            utils.removeEvent(this.indicator, utils.prefixPointerEvent('pointerdown'), this);
31784            utils.removeEvent(this.indicator, 'mousedown', this);
31785
31786            utils.removeEvent(window, 'touchmove', this);
31787            utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
31788            utils.removeEvent(window, 'mousemove', this);
31789
31790            utils.removeEvent(window, 'touchend', this);
31791            utils.removeEvent(window, utils.prefixPointerEvent('pointerup'), this);
31792            utils.removeEvent(window, 'mouseup', this);
31793        }
31794
31795        if ( this.options.defaultScrollbars ) {
31796            this.wrapper.parentNode.removeChild(this.wrapper);
31797        }
31798    },
31799
31800    _start: function (e) {
31801        var point = e.touches ? e.touches[0] : e;
31802
31803        e.preventDefault();
31804        e.stopPropagation();
31805
31806        this.transitionTime();
31807
31808        this.initiated = true;
31809        this.moved = false;
31810        this.lastPointX = point.pageX;
31811        this.lastPointY = point.pageY;
31812
31813        this.startTime  = utils.getTime();
31814
31815        if ( !this.options.disableTouch ) {
31816            utils.addEvent(window, 'touchmove', this);
31817        }
31818        if ( !this.options.disablePointer ) {
31819            utils.addEvent(window, utils.prefixPointerEvent('pointermove'), this);
31820        }
31821        if ( !this.options.disableMouse ) {
31822            utils.addEvent(window, 'mousemove', this);
31823        }
31824
31825        this.scroller._execEvent('beforeScrollStart');
31826    },
31827
31828    _move: function (e) {
31829        var point = e.touches ? e.touches[0] : e,
31830            deltaX, deltaY,
31831            newX, newY,
31832            timestamp = utils.getTime();
31833
31834        if ( !this.moved ) {
31835            this.scroller._execEvent('scrollStart');
31836        }
31837
31838        this.moved = true;
31839
31840        deltaX = point.pageX - this.lastPointX;
31841        this.lastPointX = point.pageX;
31842
31843        deltaY = point.pageY - this.lastPointY;
31844        this.lastPointY = point.pageY;
31845
31846        newX = this.x + deltaX;
31847        newY = this.y + deltaY;
31848
31849        this._pos(newX, newY);
31850
31851// INSERT POINT: indicator._move
31852
31853        e.preventDefault();
31854        e.stopPropagation();
31855    },
31856
31857    _end: function (e) {
31858        if ( !this.initiated ) {
31859            return;
31860        }
31861
31862        this.initiated = false;
31863
31864        e.preventDefault();
31865        e.stopPropagation();
31866
31867        utils.removeEvent(window, 'touchmove', this);
31868        utils.removeEvent(window, utils.prefixPointerEvent('pointermove'), this);
31869        utils.removeEvent(window, 'mousemove', this);
31870
31871        if ( this.scroller.options.snap ) {
31872            var snap = this.scroller._nearestSnap(this.scroller.x, this.scroller.y);
31873
31874            var time = this.options.snapSpeed || Math.max(
31875                    Math.max(
31876                        Math.min(Math.abs(this.scroller.x - snap.x), 1000),
31877                        Math.min(Math.abs(this.scroller.y - snap.y), 1000)
31878                    ), 300);
31879
31880            if ( this.scroller.x != snap.x || this.scroller.y != snap.y ) {
31881                this.scroller.directionX = 0;
31882                this.scroller.directionY = 0;
31883                this.scroller.currentPage = snap;
31884                this.scroller.scrollTo(snap.x, snap.y, time, this.scroller.options.bounceEasing);
31885            }
31886        }
31887
31888        if ( this.moved ) {
31889            this.scroller._execEvent('scrollEnd');
31890        }
31891    },
31892
31893    transitionTime: function (time) {
31894        time = time || 0;
31895        var durationProp = utils.style.transitionDuration;
31896        if(!durationProp) {
31897            return;
31898        }
31899
31900        this.indicatorStyle[durationProp] = time + 'ms';
31901
31902        if ( !time && utils.isBadAndroid ) {
31903            this.indicatorStyle[durationProp] = '0.0001ms';
31904            // remove 0.0001ms
31905            var self = this;
31906            rAF(function() {
31907                if(self.indicatorStyle[durationProp] === '0.0001ms') {
31908                    self.indicatorStyle[durationProp] = '0s';
31909                }
31910            });
31911        }
31912    },
31913
31914    transitionTimingFunction: function (easing) {
31915        this.indicatorStyle[utils.style.transitionTimingFunction] = easing;
31916    },
31917
31918    refresh: function () {
31919        this.transitionTime();
31920
31921        if ( this.options.listenX && !this.options.listenY ) {
31922            this.indicatorStyle.display = this.scroller.hasHorizontalScroll ? 'block' : 'none';
31923        } else if ( this.options.listenY && !this.options.listenX ) {
31924            this.indicatorStyle.display = this.scroller.hasVerticalScroll ? 'block' : 'none';
31925        } else {
31926            this.indicatorStyle.display = this.scroller.hasHorizontalScroll || this.scroller.hasVerticalScroll ? 'block' : 'none';
31927        }
31928
31929        if ( this.scroller.hasHorizontalScroll && this.scroller.hasVerticalScroll ) {
31930            utils.addClass(this.wrapper, 'iScrollBothScrollbars');
31931            utils.removeClass(this.wrapper, 'iScrollLoneScrollbar');
31932
31933            if ( this.options.defaultScrollbars && this.options.customStyle ) {
31934                if ( this.options.listenX ) {
31935                    this.wrapper.style.right = '8px';
31936                } else {
31937                    this.wrapper.style.bottom = '8px';
31938                }
31939            }
31940        } else {
31941            utils.removeClass(this.wrapper, 'iScrollBothScrollbars');
31942            utils.addClass(this.wrapper, 'iScrollLoneScrollbar');
31943
31944            if ( this.options.defaultScrollbars && this.options.customStyle ) {
31945                if ( this.options.listenX ) {
31946                    this.wrapper.style.right = '2px';
31947                } else {
31948                    this.wrapper.style.bottom = '2px';
31949                }
31950            }
31951        }
31952
31953        var r = this.wrapper.offsetHeight;  // force refresh
31954
31955        if ( this.options.listenX ) {
31956            this.wrapperWidth = this.wrapper.clientWidth;
31957            if ( this.options.resize ) {
31958                this.indicatorWidth = Math.max(Math.round(this.wrapperWidth * this.wrapperWidth / (this.scroller.scrollerWidth || this.wrapperWidth || 1)), 8);
31959                this.indicatorStyle.width = this.indicatorWidth + 'px';
31960            } else {
31961                this.indicatorWidth = this.indicator.clientWidth;
31962            }
31963
31964            this.maxPosX = this.wrapperWidth - this.indicatorWidth;
31965
31966            if ( this.options.shrink == 'clip' ) {
31967                this.minBoundaryX = -this.indicatorWidth + 8;
31968                this.maxBoundaryX = this.wrapperWidth - 8;
31969            } else {
31970                this.minBoundaryX = 0;
31971                this.maxBoundaryX = this.maxPosX;
31972            }
31973
31974            this.sizeRatioX = this.options.speedRatioX || (this.scroller.maxScrollX && (this.maxPosX / this.scroller.maxScrollX));
31975        }
31976
31977        if ( this.options.listenY ) {
31978            this.wrapperHeight = this.wrapper.clientHeight;
31979            if ( this.options.resize ) {
31980                this.indicatorHeight = Math.max(Math.round(this.wrapperHeight * this.wrapperHeight / (this.scroller.scrollerHeight || this.wrapperHeight || 1)), 8);
31981                this.indicatorStyle.height = this.indicatorHeight + 'px';
31982            } else {
31983                this.indicatorHeight = this.indicator.clientHeight;
31984            }
31985
31986            this.maxPosY = this.wrapperHeight - this.indicatorHeight;
31987
31988            if ( this.options.shrink == 'clip' ) {
31989                this.minBoundaryY = -this.indicatorHeight + 8;
31990                this.maxBoundaryY = this.wrapperHeight - 8;
31991            } else {
31992                this.minBoundaryY = 0;
31993                this.maxBoundaryY = this.maxPosY;
31994            }
31995
31996            this.maxPosY = this.wrapperHeight - this.indicatorHeight;
31997            this.sizeRatioY = this.options.speedRatioY || (this.scroller.maxScrollY && (this.maxPosY / this.scroller.maxScrollY));
31998        }
31999
32000        this.updatePosition();
32001    },
32002
32003    updatePosition: function () {
32004        var x = this.options.listenX && Math.round(this.sizeRatioX * this.scroller.x) || 0,
32005            y = this.options.listenY && Math.round(this.sizeRatioY * this.scroller.y) || 0;
32006
32007        if ( !this.options.ignoreBoundaries ) {
32008            if ( x < this.minBoundaryX ) {
32009                if ( this.options.shrink == 'scale' ) {
32010                    this.width = Math.max(this.indicatorWidth + x, 8);
32011                    this.indicatorStyle.width = this.width + 'px';
32012                }
32013                x = this.minBoundaryX;
32014            } else if ( x > this.maxBoundaryX ) {
32015                if ( this.options.shrink == 'scale' ) {
32016                    this.width = Math.max(this.indicatorWidth - (x - this.maxPosX), 8);
32017                    this.indicatorStyle.width = this.width + 'px';
32018                    x = this.maxPosX + this.indicatorWidth - this.width;
32019                } else {
32020                    x = this.maxBoundaryX;
32021                }
32022            } else if ( this.options.shrink == 'scale' && this.width != this.indicatorWidth ) {
32023                this.width = this.indicatorWidth;
32024                this.indicatorStyle.width = this.width + 'px';
32025            }
32026
32027            if ( y < this.minBoundaryY ) {
32028                if ( this.options.shrink == 'scale' ) {
32029                    this.height = Math.max(this.indicatorHeight + y * 3, 8);
32030                    this.indicatorStyle.height = this.height + 'px';
32031                }
32032                y = this.minBoundaryY;
32033            } else if ( y > this.maxBoundaryY ) {
32034                if ( this.options.shrink == 'scale' ) {
32035                    this.height = Math.max(this.indicatorHeight - (y - this.maxPosY) * 3, 8);
32036                    this.indicatorStyle.height = this.height + 'px';
32037                    y = this.maxPosY + this.indicatorHeight - this.height;
32038                } else {
32039                    y = this.maxBoundaryY;
32040                }
32041            } else if ( this.options.shrink == 'scale' && this.height != this.indicatorHeight ) {
32042                this.height = this.indicatorHeight;
32043                this.indicatorStyle.height = this.height + 'px';
32044            }
32045        }
32046
32047        this.x = x;
32048        this.y = y;
32049
32050        if ( this.scroller.options.useTransform ) {
32051            this.indicatorStyle[utils.style.transform] = 'translate(' + x + 'px,' + y + 'px)' + this.scroller.translateZ;
32052        } else {
32053            this.indicatorStyle.left = x + 'px';
32054            this.indicatorStyle.top = y + 'px';
32055        }
32056    },
32057
32058    _pos: function (x, y) {
32059        if ( x < 0 ) {
32060            x = 0;
32061        } else if ( x > this.maxPosX ) {
32062            x = this.maxPosX;
32063        }
32064
32065        if ( y < 0 ) {
32066            y = 0;
32067        } else if ( y > this.maxPosY ) {
32068            y = this.maxPosY;
32069        }
32070
32071        x = this.options.listenX ? Math.round(x / this.sizeRatioX) : this.scroller.x;
32072        y = this.options.listenY ? Math.round(y / this.sizeRatioY) : this.scroller.y;
32073
32074        this.scroller.scrollTo(x, y);
32075    },
32076
32077    fade: function (val, hold) {
32078        if ( hold && !this.visible ) {
32079            return;
32080        }
32081
32082        clearTimeout(this.fadeTimeout);
32083        this.fadeTimeout = null;
32084
32085        var time = val ? 250 : 500,
32086            delay = val ? 0 : 300;
32087
32088        val = val ? '1' : '0';
32089
32090        this.wrapperStyle[utils.style.transitionDuration] = time + 'ms';
32091
32092        this.fadeTimeout = setTimeout((function (val) {
32093            this.wrapperStyle.opacity = val;
32094            this.visible = +val;
32095        }).bind(this, val), delay);
32096    }
32097};
32098
32099IScroll.utils = utils;
32100
32101if ( typeof module != 'undefined' && module.exports ) {
32102    module.exports = IScroll;
32103} else if ( typeof define == 'function' && define.amd ) {
32104        define( function () { return IScroll; } );
32105} else {
32106    window.IScroll = IScroll;
32107}
32108
32109})(window, document, Math);
32110/*!
32111 * fullPage 2.9.4
32112 * https://github.com/alvarotrigo/fullPage.js
32113 * @license MIT licensed
32114 *
32115 * Copyright (C) 2015 alvarotrigo.com - A project by Alvaro Trigo
32116 */
32117(function(global, factory) {
32118    'use strict';
32119    if (typeof define === 'function' && define.amd) {
32120        define(['jquery'], function($) {
32121          return factory($, global, global.document, global.Math);
32122        });
32123    } else if (typeof exports === "object" && exports) {
32124        module.exports = factory(require('jquery'), global, global.document, global.Math);
32125    } else {
32126        factory(jQuery, global, global.document, global.Math);
32127    }
32128})(typeof window !== 'undefined' ? window : this, function($, window, document, Math, undefined) {
32129    'use strict';
32130
32131    // keeping central set of classnames and selectors
32132    var WRAPPER =               'fullpage-wrapper';
32133    var WRAPPER_SEL =           '.' + WRAPPER;
32134
32135    // slimscroll
32136    var SCROLLABLE =            'fp-scrollable';
32137    var SCROLLABLE_SEL =        '.' + SCROLLABLE;
32138
32139    // util
32140    var RESPONSIVE =            'fp-responsive';
32141    var NO_TRANSITION =         'fp-notransition';
32142    var DESTROYED =             'fp-destroyed';
32143    var ENABLED =               'fp-enabled';
32144    var VIEWING_PREFIX =        'fp-viewing';
32145    var ACTIVE =                'active';
32146    var ACTIVE_SEL =            '.' + ACTIVE;
32147    var COMPLETELY =            'fp-completely';
32148    var COMPLETELY_SEL =        '.' + COMPLETELY;
32149
32150    // section
32151    var SECTION_DEFAULT_SEL =   '.section';
32152    var SECTION =               'fp-section';
32153    var SECTION_SEL =           '.' + SECTION;
32154    var SECTION_ACTIVE_SEL =    SECTION_SEL + ACTIVE_SEL;
32155    var SECTION_FIRST_SEL =     SECTION_SEL + ':first';
32156    var SECTION_LAST_SEL =      SECTION_SEL + ':last';
32157    var TABLE_CELL =            'fp-tableCell';
32158    var TABLE_CELL_SEL =        '.' + TABLE_CELL;
32159    var AUTO_HEIGHT =           'fp-auto-height';
32160    var AUTO_HEIGHT_SEL =       '.fp-auto-height';
32161    var NORMAL_SCROLL =         'fp-normal-scroll';
32162    var NORMAL_SCROLL_SEL =     '.fp-normal-scroll';
32163
32164    // section nav
32165    var SECTION_NAV =           'fp-nav';
32166    var SECTION_NAV_SEL =       '#' + SECTION_NAV;
32167    var SECTION_NAV_TOOLTIP =   'fp-tooltip';
32168    var SECTION_NAV_TOOLTIP_SEL='.'+SECTION_NAV_TOOLTIP;
32169    var SHOW_ACTIVE_TOOLTIP =   'fp-show-active';
32170
32171    // slide
32172    var SLIDE_DEFAULT_SEL =     '.slide';
32173    var SLIDE =                 'fp-slide';
32174    var SLIDE_SEL =             '.' + SLIDE;
32175    var SLIDE_ACTIVE_SEL =      SLIDE_SEL + ACTIVE_SEL;
32176    var SLIDES_WRAPPER =        'fp-slides';
32177    var SLIDES_WRAPPER_SEL =    '.' + SLIDES_WRAPPER;
32178    var SLIDES_CONTAINER =      'fp-slidesContainer';
32179    var SLIDES_CONTAINER_SEL =  '.' + SLIDES_CONTAINER;
32180    var TABLE =                 'fp-table';
32181
32182    // slide nav
32183    var SLIDES_NAV =            'fp-slidesNav';
32184    var SLIDES_NAV_SEL =        '.' + SLIDES_NAV;
32185    var SLIDES_NAV_LINK_SEL =   SLIDES_NAV_SEL + ' a';
32186    var SLIDES_ARROW =          'fp-controlArrow';
32187    var SLIDES_ARROW_SEL =      '.' + SLIDES_ARROW;
32188    var SLIDES_PREV =           'fp-prev';
32189    var SLIDES_PREV_SEL =       '.' + SLIDES_PREV;
32190    var SLIDES_ARROW_PREV =     SLIDES_ARROW + ' ' + SLIDES_PREV;
32191    var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL;
32192    var SLIDES_NEXT =           'fp-next';
32193    var SLIDES_NEXT_SEL =       '.' + SLIDES_NEXT;
32194    var SLIDES_ARROW_NEXT =     SLIDES_ARROW + ' ' + SLIDES_NEXT;
32195    var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL;
32196
32197    var $window = $(window);
32198    var $document = $(document);
32199
32200    // Default options for iScroll.js used when using scrollOverflow
32201    var iscrollOptions = {
32202        scrollbars: true,
32203        mouseWheel: true,
32204        hideScrollbars: false,
32205        fadeScrollbars: false,
32206        disableMouse: true,
32207        interactiveScrollbars: true,
32208        bounce: false,
32209    };
32210
32211    $.fn.fullpage = function(options) {
32212        //only once my friend!
32213        if($('html').hasClass(ENABLED)){ displayWarnings(); return; }
32214
32215        // common jQuery objects
32216        var $htmlBody = $('html, body');
32217        var $body = $('body');
32218
32219        var FP = $.fn.fullpage;
32220
32221        // Creating some defaults, extending them with any options that were provided
32222        options = $.extend({
32223            //navigation
32224            menu: false,
32225            anchors:[],
32226            lockAnchors: false,
32227            navigation: false,
32228            navigationPosition: 'right',
32229            navigationTooltips: [],
32230            showActiveTooltip: false,
32231            slidesNavigation: false,
32232            slidesNavPosition: 'bottom',
32233            scrollBar: false,
32234            hybrid: false,
32235
32236            //scrolling
32237            css3: true,
32238            scrollingSpeed: 700,
32239            autoScrolling: true,
32240            fitToSection: true,
32241            fitToSectionDelay: 1000,
32242            easing: 'easeInOutCubic',
32243            easingcss3: 'ease',
32244            loopBottom: false,
32245            loopTop: false,
32246            loopHorizontal: true,
32247            continuousVertical: false,
32248            continuousHorizontal: false,
32249            scrollHorizontally: false,
32250            interlockedSlides: false,
32251            dragAndMove: false,
32252            offsetSections: false,
32253            resetSliders: false,
32254            fadingEffect: false,
32255            normalScrollElements: null,
32256            scrollOverflow: false,
32257            scrollOverflowReset: false,
32258            scrollOverflowHandler: iscrollHandler,
32259            scrollOverflowOptions: null,
32260            touchSensitivity: 5,
32261            normalScrollElementTouchThreshold: 5,
32262            bigSectionsDestination: null,
32263
32264            //Accessibility
32265            keyboardScrolling: true,
32266            animateAnchor: true,
32267            recordHistory: true,
32268
32269            //design
32270            controlArrows: true,
32271            controlArrowColor: '#fff',
32272            verticalCentered: true,
32273            sectionsColor : [],
32274            paddingTop: 0,
32275            paddingBottom: 0,
32276            fixedElements: null,
32277            responsive: 0, //backwards compabitility with responsiveWiddth
32278            responsiveWidth: 0,
32279            responsiveHeight: 0,
32280            responsiveSlides: false,
32281            parallax: false,
32282            parallaxOptions: {
32283                type: 'reveal',
32284                percentage: 62,
32285                property: 'translate'
32286            },
32287
32288            //Custom selectors
32289            sectionSelector: SECTION_DEFAULT_SEL,
32290            slideSelector: SLIDE_DEFAULT_SEL,
32291
32292            //events
32293            afterLoad: null,
32294            onLeave: null,
32295            afterRender: null,
32296            afterResize: null,
32297            afterReBuild: null,
32298            afterSlideLoad: null,
32299            onSlideLeave: null,
32300            afterResponsive: null,
32301
32302            lazyLoading: true
32303        }, options);
32304
32305        //flag to avoid very fast sliding for landscape sliders
32306        var slideMoving = false;
32307
32308        var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/);
32309        var isTouch = (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0) || (navigator.maxTouchPoints));
32310        var container = $(this);
32311        var windowsHeight = $window.height();
32312        var isResizing = false;
32313        var isWindowFocused = true;
32314        var lastScrolledDestiny;
32315        var lastScrolledSlide;
32316        var canScroll = true;
32317        var scrollings = [];
32318        var controlPressed;
32319        var startingSection;
32320        var isScrollAllowed = {};
32321        isScrollAllowed.m = {  'up':true, 'down':true, 'left':true, 'right':true };
32322        isScrollAllowed.k = $.extend(true,{}, isScrollAllowed.m);
32323        var MSPointer = getMSPointer();
32324        var events = {
32325            touchmove: 'ontouchmove' in window ? 'touchmove' :  MSPointer.move,
32326            touchstart: 'ontouchstart' in window ? 'touchstart' :  MSPointer.down
32327        };
32328
32329        //cheks for passive event support
32330        //added by Uncode from new fullPage updates
32331        var g_supportsPassive = false;
32332        try {
32333          var opts = Object.defineProperty({}, 'passive', {
32334            get: function() {
32335              g_supportsPassive = true;
32336            }
32337          });
32338          window.addEventListener("testPassive", null, opts);
32339          window.removeEventListener("testPassive", null, opts);
32340        } catch (e) {}
32341
32342        //timeouts
32343        var resizeId;
32344        var afterSectionLoadsId;
32345        var afterSlideLoadsId;
32346        var scrollId;
32347        var scrollId2;
32348        var keydownId;
32349        var originals = $.extend(true, {}, options); //deep copy
32350
32351        //Uncode addition
32352        var $masthead = $('#masthead');
32353        var hideMenu = !$('body').hasClass('vmenu') && $('body').hasClass('uncode-fp-menu-hide') ? true : false;
32354        var menuHeight = $masthead.hasClass('menu-transparent') || hideMenu ? 0 : UNCODE.menuHeight;
32355        var bodyBorder = UNCODE.bodyBorder;
32356        var adminBarHeight = UNCODE.adminBarHeight;
32357
32358        displayWarnings();
32359
32360        //fixing bug in iScroll with links: https://github.com/cubiq/iscroll/issues/783
32361        iscrollOptions.click = isTouch; // see #2035
32362
32363        //extending iScroll options with the user custom ones
32364        iscrollOptions = $.extend(iscrollOptions, options.scrollOverflowOptions);
32365
32366        //easeInOutCubic animation included in the plugin
32367        $.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;}});
32368
32369        /**
32370        * Sets the autoScroll option.
32371        * It changes the scroll bar visibility and the history of the site as a result.
32372        */
32373        function setAutoScrolling(value, type){
32374            //removing the transformation
32375            if(!value){
32376                silentScroll(0);
32377            }
32378
32379            setVariableState('autoScrolling', value, type);
32380
32381            var element = $(SECTION_ACTIVE_SEL);
32382
32383            if(options.autoScrolling && !options.scrollBar){
32384                $htmlBody.css({
32385                    'overflow' : 'hidden !important',
32386                    'height' : '100%'
32387                });
32388
32389                //Uncode addition
32390                //setRecordHistory(originals.recordHistory, 'internal');
32391
32392                //for IE touch devices
32393                container.css({
32394                    '-ms-touch-action': 'none',
32395                    'touch-action': 'none'
32396                });
32397
32398                if(element.length){
32399                    //moving the container up
32400                    silentScroll(element.position().top);
32401                }
32402
32403            }else{
32404                $htmlBody.css({
32405                    'overflow' : 'visible !important',
32406                    'height' : 'initial'
32407                });
32408
32409                //Uncode addition
32410                //setRecordHistory(false, 'internal');
32411
32412                //for IE touch devices
32413                container.css({
32414                    '-ms-touch-action': '',
32415                    'touch-action': ''
32416                });
32417
32418                //scrolling the page to the section with no animation
32419                if (element.length) {
32420                    $htmlBody.scrollTop(element.position().top);
32421                }
32422            }
32423        }
32424
32425        /**
32426        * Defines wheter to record the history for each hash change in the URL.
32427        */
32428        function setRecordHistory(value, type){
32429            setVariableState('recordHistory', value, type);
32430        }
32431
32432        /**
32433        * Defines the scrolling speed
32434        */
32435        function setScrollingSpeed(value, type){
32436            setVariableState('scrollingSpeed', value, type);
32437        }
32438
32439        /**
32440        * Sets fitToSection
32441        */
32442        function setFitToSection(value, type){
32443            setVariableState('fitToSection', value, type);
32444        }
32445
32446        /**
32447        * Sets lockAnchors
32448        */
32449        function setLockAnchors(value){
32450            options.lockAnchors = value;
32451        }
32452
32453        /**
32454        * Adds or remove the possiblity of scrolling through sections by using the mouse wheel or the trackpad.
32455        */
32456        function setMouseWheelScrolling(value){
32457            if(value){
32458                addMouseWheelHandler();
32459                addMiddleWheelHandler();
32460            }else{
32461                removeMouseWheelHandler();
32462                removeMiddleWheelHandler();
32463            }
32464        }
32465
32466        /**
32467        * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures.
32468        * Optionally a second parameter can be used to specify the direction for which the action will be applied.
32469        *
32470        * @param directions string containing the direction or directions separated by comma.
32471        */
32472        function setAllowScrolling(value, directions){
32473            if(typeof directions !== 'undefined'){
32474                directions = directions.replace(/ /g,'').split(',');
32475
32476                $.each(directions, function (index, direction){
32477                    setIsScrollAllowed(value, direction, 'm');
32478                });
32479            }
32480            else if(value){
32481                setMouseWheelScrolling(true);
32482                addTouchHandler();
32483            }else{
32484                setMouseWheelScrolling(false);
32485                removeTouchHandler();
32486            }
32487        }
32488
32489        /**
32490        * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys
32491        */
32492        function setKeyboardScrolling(value, directions){
32493            if(typeof directions !== 'undefined'){
32494                directions = directions.replace(/ /g,'').split(',');
32495
32496                $.each(directions, function (index, direction){
32497                    setIsScrollAllowed(value, direction, 'k');
32498                });
32499            }else{
32500                options.keyboardScrolling = value;
32501            }
32502        }
32503
32504        /**
32505        * Moves the page up one section.
32506        */
32507        function moveSectionUp(){
32508            var prev = $(SECTION_ACTIVE_SEL).prev(SECTION_SEL);
32509
32510            //looping to the bottom if there's no more sections above
32511            if (!prev.length && (options.loopTop || options.continuousVertical)) {
32512                prev = $(SECTION_SEL).last();
32513            }
32514
32515            if (prev.length) {
32516                scrollPage(prev, null, true);
32517            }
32518        }
32519
32520        /**
32521        * Moves the page down one section.
32522        */
32523        function moveSectionDown(){
32524            var next = $(SECTION_ACTIVE_SEL).next(SECTION_SEL);
32525
32526            //looping to the top if there's no more sections below
32527            if(!next.length &&
32528                (options.loopBottom || options.continuousVertical)){
32529                next = $(SECTION_SEL).first();
32530            }
32531
32532            if(next.length){
32533                scrollPage(next, null, false);
32534            }
32535        }
32536
32537        /**
32538        * Moves the page to the given section and slide with no animation.
32539        * Anchors or index positions can be used as params.
32540        */
32541        function silentMoveTo(sectionAnchor, slideAnchor){
32542            setScrollingSpeed (0, 'internal');
32543            moveTo(sectionAnchor, slideAnchor);
32544            setScrollingSpeed (originals.scrollingSpeed, 'internal');
32545        }
32546
32547        /**
32548        * Moves the page to the given section and slide.
32549        * Anchors or index positions can be used as params.
32550        */
32551        function moveTo(sectionAnchor, slideAnchor){
32552            var destiny = getSectionByAnchor(sectionAnchor);
32553
32554            if (typeof slideAnchor !== 'undefined'){
32555                scrollPageAndSlide(sectionAnchor, slideAnchor);
32556            }else if(destiny.length > 0){
32557                scrollPage(destiny);
32558            }
32559        }
32560
32561        /**
32562        * Slides right the slider of the active section.
32563        * Optional `section` param.
32564        */
32565        function moveSlideRight(section){
32566            moveSlide('right', section);
32567        }
32568
32569        /**
32570        * Slides left the slider of the active section.
32571        * Optional `section` param.
32572        */
32573        function moveSlideLeft(section){
32574            moveSlide('left', section);
32575        }
32576
32577        /**
32578         * When resizing is finished, we adjust the slides sizes and positions
32579         */
32580        function reBuild(resizing){
32581            if(container.hasClass(DESTROYED)){ return; }  //nothing to do if the plugin was destroyed
32582
32583            isResizing = true;
32584
32585            windowsHeight = $window.height();  //updating global var
32586
32587            $(SECTION_SEL).each(function(){
32588                var slidesWrap = $(this).find(SLIDES_WRAPPER_SEL);
32589                var slides = $(this).find(SLIDE_SEL);
32590
32591                //adjusting the height of the table-cell for IE and Firefox
32592                if(options.verticalCentered){
32593                    $(this).find(TABLE_CELL_SEL).css('height', getTableHeight($(this)) + 'px');
32594                }
32595
32596                $(this).css('height', windowsHeight + 'px');
32597
32598                //resizing the scrolling divs
32599                if(options.scrollOverflow){
32600                    if(slides.length){
32601                        slides.each(function(){
32602                            createScrollBar($(this));
32603                        });
32604                    }else{
32605                        createScrollBar($(this));
32606                    }
32607                }
32608
32609                //adjusting the position fo the FULL WIDTH slides...
32610                if (slides.length > 1) {
32611                    landscapeScroll(slidesWrap, slidesWrap.find(SLIDE_ACTIVE_SEL));
32612                }
32613            });
32614
32615            var activeSection = $(SECTION_ACTIVE_SEL);
32616            var sectionIndex = activeSection.index(SECTION_SEL);
32617
32618            //isn't it the first section?
32619            if(sectionIndex){
32620                //adjusting the position for the current section
32621                silentMoveTo(sectionIndex + 1);
32622            }
32623
32624            isResizing = false;
32625            // Uncode change
32626            // $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container);
32627            $.isFunction( options.afterResize ) && resizing && options.afterResize.call(container, getTableHeight());
32628            $.isFunction( options.afterReBuild ) && !resizing && options.afterReBuild.call(container);
32629        }
32630
32631        /**
32632        * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height`
32633        * are smaller than the set limit values.
32634        */
32635        function setResponsive(active){
32636            var isResponsive = $body.hasClass(RESPONSIVE);
32637
32638            if(active){
32639                if(!isResponsive){
32640                    setAutoScrolling(false, 'internal');
32641                    setFitToSection(false, 'internal');
32642                    $(SECTION_NAV_SEL).hide();
32643                    $body.addClass(RESPONSIVE);
32644                    $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active);
32645                }
32646            }
32647            else if(isResponsive){
32648                setAutoScrolling(originals.autoScrolling, 'internal');
32649                setFitToSection(originals.autoScrolling, 'internal');
32650                $(SECTION_NAV_SEL).show();
32651                $body.removeClass(RESPONSIVE);
32652                $.isFunction( options.afterResponsive ) && options.afterResponsive.call( container, active);
32653            }
32654        }
32655
32656        if($(this).length){
32657            //public functions
32658            FP.setAutoScrolling = setAutoScrolling;
32659            FP.setRecordHistory = setRecordHistory;
32660            FP.setScrollingSpeed = setScrollingSpeed;
32661            FP.setFitToSection = setFitToSection;
32662            FP.setLockAnchors = setLockAnchors;
32663            FP.setMouseWheelScrolling = setMouseWheelScrolling;
32664            FP.setAllowScrolling = setAllowScrolling;
32665            FP.setKeyboardScrolling = setKeyboardScrolling;
32666            FP.moveSectionUp = moveSectionUp;
32667            FP.moveSectionDown = moveSectionDown;
32668            FP.silentMoveTo = silentMoveTo;
32669            FP.moveTo = moveTo;
32670            FP.moveSlideRight = moveSlideRight;
32671            FP.moveSlideLeft = moveSlideLeft;
32672            FP.fitToSection = fitToSection;
32673            FP.reBuild = reBuild;
32674            FP.setResponsive = setResponsive;
32675            FP.destroy = destroy;
32676
32677            init();
32678
32679            bindEvents();
32680        }
32681
32682        function init(){
32683            //if css3 is not supported, it will use jQuery animations
32684            if(options.css3){
32685                options.css3 = support3d();
32686            }
32687
32688            options.scrollBar = options.scrollBar || options.hybrid;
32689
32690            setOptionsFromDOM();
32691            prepareDom();
32692            setAllowScrolling(true);
32693            setAutoScrolling(options.autoScrolling, 'internal');
32694            responsive();
32695
32696            //setting the class for the body element
32697            setBodyClass();
32698
32699            //Uncode addition
32700            // if(document.readyState === 'complete'){
32701            //     scrollToAnchor();
32702            // }
32703            // $window.on('load', scrollToAnchor);
32704        }
32705
32706        function bindEvents(){
32707            $window
32708                //when scrolling...
32709                //.on('scroll', scrollHandler)
32710
32711                //detecting any change on the URL to scroll to the given anchor link
32712                //(a way to detect back history button as we play with the hashes on the URL)
32713                .on('hashchange', hashChangeHandler)
32714
32715                //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
32716                .blur(blurHandler)
32717
32718                //when resizing the site, we adjust the heights of the sections, slimScroll...
32719                .resize(resizeHandler);
32720
32721            $document
32722                //Sliding with arrow keys, both, vertical and horizontal
32723                .keydown(keydownHandler)
32724
32725                //to prevent scrolling while zooming
32726                .keyup(keyUpHandler)
32727
32728                //Scrolls to the section when clicking the navigation bullet
32729                .on('click touchstart', SECTION_NAV_SEL + ' a', sectionBulletHandler)
32730
32731                //Scrolls the slider to the given slide destination for the given section
32732                .on('click touchstart', SLIDES_NAV_LINK_SEL, slideBulletHandler)
32733
32734                .on('click', SECTION_NAV_TOOLTIP_SEL, tooltipTextHandler);
32735
32736            //Scrolling horizontally when clicking on the slider controls.
32737            $(SECTION_SEL).on('click touchstart', SLIDES_ARROW_SEL, slideArrowHandler);
32738
32739            /**
32740            * Applying normalScroll elements.
32741            * Ignoring the scrolls over the specified selectors.
32742            */
32743            if(options.normalScrollElements){
32744                $document.on('mouseenter', options.normalScrollElements, function () {
32745                    setMouseWheelScrolling(false);
32746                });
32747
32748                $document.on('mouseleave', options.normalScrollElements, function(){
32749                    setMouseWheelScrolling(true);
32750                });
32751            }
32752        }
32753
32754        /**
32755        * Setting options from DOM elements if they are not provided.
32756        */
32757        function setOptionsFromDOM(){
32758            var sections = container.find(options.sectionSelector);
32759
32760            //no anchors option? Checking for them in the DOM attributes
32761            if(!options.anchors.length){
32762                options.anchors = sections.filter('[data-anchor]').map(function(){
32763                    return $(this).data('anchor').toString();
32764                }).get();
32765            }
32766
32767            //no tooltips option? Checking for them in the DOM attributes
32768            if(!options.navigationTooltips.length){
32769                options.navigationTooltips = sections.filter('[data-tooltip]').map(function(){
32770                    return $(this).data('tooltip').toString();
32771                }).get();
32772            }
32773        }
32774
32775        /**
32776        * Works over the DOM structure to set it up for the current fullpage options.
32777        */
32778        function prepareDom(){
32779            container.css({
32780                'height': '100%',
32781                'position': 'relative'
32782            });
32783
32784            //adding a class to recognize the container internally in the code
32785            container.addClass(WRAPPER);
32786            $('html').addClass(ENABLED);
32787
32788            windowsHeight = $window.height();
32789
32790            container.removeClass(DESTROYED); //in case it was destroyed before initializing it again
32791
32792            addInternalSelectors();
32793
32794             //styling the sections / slides / menu
32795            $(SECTION_SEL).each(function(index){
32796                var section = $(this);
32797                var slides = section.find(SLIDE_SEL);
32798                var numSlides = slides.length;
32799
32800                styleSection(section, index);
32801                styleMenu(section, index);
32802
32803                // if there's any slide
32804                if (numSlides > 0) {
32805                    styleSlides(section, slides, numSlides);
32806                }else{
32807                    if(options.verticalCentered){
32808                        addTableClass(section);
32809                    }
32810                }
32811            });
32812
32813            //fixed elements need to be moved out of the plugin container due to problems with CSS3.
32814            if(options.fixedElements && options.css3){
32815                $(options.fixedElements).appendTo($body);
32816            }
32817
32818            //vertical centered of the navigation + active bullet
32819            if(options.navigation){
32820                addVerticalNavigation();
32821            }
32822
32823            enableYoutubeAPI();
32824
32825            if(options.scrollOverflow){
32826                if(document.readyState === 'complete'){
32827                    createScrollBarHandler();
32828                }
32829                //after DOM and images are loaded
32830                $window.on('load', createScrollBarHandler);
32831            }else{
32832                afterRenderActions();
32833            }
32834        }
32835
32836        /**
32837        * Styles the horizontal slides for a section.
32838        */
32839        function styleSlides(section, slides, numSlides){
32840            var sliderWidth = numSlides * 100;
32841            var slideWidth = 100 / numSlides;
32842
32843            slides.wrapAll('<div class="' + SLIDES_CONTAINER + '" />');
32844            slides.parent().wrap('<div class="' + SLIDES_WRAPPER + '" />');
32845
32846            section.find(SLIDES_CONTAINER_SEL).css('width', sliderWidth + '%');
32847
32848            if(numSlides > 1){
32849                if(options.controlArrows){
32850                    createSlideArrows(section);
32851                }
32852
32853                if(options.slidesNavigation){
32854                    addSlidesNavigation(section, numSlides);
32855                }
32856            }
32857
32858            slides.each(function(index) {
32859                $(this).css('width', slideWidth + '%');
32860
32861                if(options.verticalCentered){
32862                    addTableClass($(this));
32863                }
32864            });
32865
32866            var startingSlide = section.find(SLIDE_ACTIVE_SEL);
32867
32868            //if the slide won't be an starting point, the default will be the first one
32869            //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/sl
32869ide by default.
32870            if( startingSlide.length &&  ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) !== 0 || ($(SECTION_ACTIVE_SEL).index(SECTION_SEL) === 0 && startingSlide.index() !== 0))){
32871                silentLandscapeScroll(startingSlide, 'internal');
32872            }else{
32873                slides.eq(0).addClass(ACTIVE);
32874            }
32875        }
32876
32877        /**
32878        * Styling vertical sections
32879        */
32880        function styleSection(section, index){
32881            //if no active section is defined, the 1st one will be the default one
32882            if(!index && $(SECTION_ACTIVE_SEL).length === 0) {
32883                section.addClass(ACTIVE);
32884            }
32885            startingSection = $(SECTION_ACTIVE_SEL);
32886
32887            section.css('height', windowsHeight + 'px');
32888
32889            if(options.paddingTop){
32890                section.css('padding-top', options.paddingTop);
32891            }
32892
32893            if(options.paddingBottom){
32894                section.css('padding-bottom', options.paddingBottom);
32895            }
32896
32897            if (typeof options.sectionsColor[index] !==  'undefined') {
32898                section.css('background-color', options.sectionsColor[index]);
32899            }
32900
32901            if (typeof options.anchors[index] !== 'undefined') {
32902                section.attr('data-anchor', options.anchors[index]);
32903            }
32904        }
32905
32906        /**
32907        * Sets the data-anchor attributes to the menu elements and activates the current one.
32908        */
32909        function styleMenu(section, index){
32910            if (typeof options.anchors[index] !== 'undefined') {
32911                //activating the menu / nav element on load
32912                if(section.hasClass(ACTIVE)){
32913                    activateMenuAndNav(options.anchors[index], index);
32914                }
32915            }
32916
32917            //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms)
32918            if(options.menu && options.css3 && $(options.menu).closest(WRAPPER_SEL).length){
32919                $(options.menu).appendTo($body);
32920            }
32921        }
32922
32923        /**
32924        * Adds internal classes to be able to provide customizable selectors
32925        * keeping the link with the style sheet.
32926        */
32927        function addInternalSelectors(){
32928            container.find(options.sectionSelector).addClass(SECTION);
32929            container.find(options.slideSelector).addClass(SLIDE);
32930        }
32931
32932        /**
32933        * Creates the control arrows for the given section
32934        */
32935        function createSlideArrows(section){
32936            section.find(SLIDES_WRAPPER_SEL).after('<div class="' + SLIDES_ARROW_PREV + '"></div><div class="' + SLIDES_ARROW_NEXT + '"></div>');
32937
32938            if(options.controlArrowColor!='#fff'){
32939                section.find(SLIDES_ARROW_NEXT_SEL).css('border-color', 'transparent transparent transparent '+options.controlArrowColor);
32940                section.find(SLIDES_ARROW_PREV_SEL).css('border-color', 'transparent '+ options.controlArrowColor + ' transparent transparent');
32941            }
32942
32943            if(!options.loopHorizontal){
32944                section.find(SLIDES_ARROW_PREV_SEL).hide();
32945            }
32946        }
32947
32948        /**
32949        * Creates a vertical navigation bar.
32950        */
32951        function addVerticalNavigation(){
32952            $body.append('<div id="' + SECTION_NAV + '"><ul></ul></div>');
32953            var nav = $(SECTION_NAV_SEL);
32954
32955            nav.addClass(function() {
32956                return options.showActiveTooltip ? SHOW_ACTIVE_TOOLTIP + ' ' + options.navigationPosition : options.navigationPosition;
32957            });
32958
32959            for (var i = 0; i < $(SECTION_SEL).length; i++) {
32960                var link = '';
32961                if (options.anchors.length) {
32962                    link = options.anchors[i];
32963                }
32964
32965                var li = '<li><a href="#' + link + '"><span></span></a>';
32966
32967                // Only add tooltip if needed (defined by user)
32968                var tooltip = options.navigationTooltips[i];
32969
32970                if (typeof tooltip !== 'undefined' && tooltip !== '') {
32971                    li += '<div class="' + SECTION_NAV_TOOLTIP + ' ' + options.navigationPosition + '">' + tooltip + '</div>';
32972                }
32973
32974                li += '</li>';
32975
32976                nav.find('ul').append(li);
32977            }
32978
32979            //centering it vertically
32980            $(SECTION_NAV_SEL).css('margin-top', '-' + ($(SECTION_NAV_SEL).height()/2) + 'px');
32981
32982            //activating the current active section
32983            $(SECTION_NAV_SEL).find('li').eq($(SECTION_ACTIVE_SEL).index(SECTION_SEL)).find('a').addClass(ACTIVE);
32984        }
32985
32986        /**
32987        * Creates the slim scroll scrollbar for the sections and slides inside them.
32988        */
32989        function createScrollBarHandler(){
32990            $(SECTION_SEL).each(function(){
32991                var slides = $(this).find(SLIDE_SEL);
32992
32993                if(slides.length){
32994                    slides.each(function(){
32995                        createScrollBar($(this));
32996                    });
32997                }else{
32998                    createScrollBar($(this));
32999                }
33000
33001            });
33002            afterRenderActions();
33003        }
33004
33005        /*
33006        * Enables the Youtube videos API so we can control their flow if necessary.
33007        */
33008        function enableYoutubeAPI(){
33009            container.find('iframe[src*="youtube.com/embed/"]').each(function(){
33010                addURLParam($(this), 'enablejsapi=1');
33011            });
33012        }
33013
33014        /**
33015        * Adds a new parameter and its value to the `src` of a given element
33016        */
33017        function addURLParam(element, newParam){
33018            var originalSrc = element.attr('src');
33019            element.attr('src', originalSrc + getUrlParamSign(originalSrc) + newParam);
33020        }
33021
33022        /*
33023        * Returns the prefix sign to use for a new parameter in an existen URL.
33024        *
33025        * @return {String}  ? | &
33026        */
33027        function getUrlParamSign(url){
33028            return ( !/\?/.test( url ) ) ? '?' : '&';
33029        }
33030
33031        /**
33032        * Actions and callbacks to fire afterRender
33033        */
33034        function afterRenderActions(){
33035            var section = $(SECTION_ACTIVE_SEL);
33036
33037            section.addClass(COMPLETELY);
33038
33039            if(options.scrollOverflowHandler.afterRender){
33040                options.scrollOverflowHandler.afterRender(section);
33041            }
33042            lazyLoad(section);
33043            playMedia(section);
33044            options.scrollOverflowHandler.afterLoad();
33045
33046            if(isDestinyTheStartingSection()){
33047                $.isFunction( options.afterLoad ) && options.afterLoad.call(section, section.data('anchor'), (section.index(SECTION_SEL) + 1));
33048            }
33049
33050            // Uncode change
33051            // $.isFunction( options.afterRender ) && options.afterRender.call(container);
33052            $.isFunction( options.afterRender ) && options.afterRender.call(container, getTableHeight());
33053        }
33054
33055        /**
33056        * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization)
33057        */
33058        function isDestinyTheStartingSection(){
33059            var anchors =  window.location.hash.replace('#', '').split('/');
33060            var destinationSection = getSectionByAnchor(decodeURIComponent(anchors[0]));
33061
33062            return !destinationSection.length || destinationSection.length && destinationSection.index() === startingSection.index();
33063        }
33064
33065
33066        var isScrolling = false;
33067        var lastScroll = 0;
33068
33069        //when scrolling...
33070        function scrollHandler(){
33071            var currentSection;
33072
33073            if(!options.autoScrolling || options.scrollBar){
33074                var currentScroll = $window.scrollTop();
33075                var scrollDirection = getScrollDirection(currentScroll);
33076                var visibleSectionIndex = 0;
33077                var screen_mid = currentScroll + ($window.height() / 2.0);
33078                var isAtBottom = $body.height() - $window.height() === currentScroll;
33079                var sections =  document.querySelectorAll(SECTION_SEL);
33080
33081                //when using `auto-height` for a small last section it won't be centered in the viewport
33082                if(isAtBottom){
33083                    visibleSectionIndex = sections.length - 1;
33084                }
33085                //is at top? when using `auto-height` for a small first section it won't be centered in the viewport
33086                else if(!currentScroll){
33087                    visibleSectionIndex = 0;
33088                }
33089
33090                //taking the section which is showing more content in the viewport
33091                else{
33092                    for (var i = 0; i < sections.length; ++i) {
33093                        var section = sections[i];
33094
33095                        // Pick the the last section which passes the middle line of the screen.
33096                        if (section.offsetTop <= screen_mid)
33097                        {
33098                            visibleSectionIndex = i;
33099                        }
33100                    }
33101                }
33102
33103                if(isCompletelyInViewPort(scrollDirection)){
33104                    if(!$(SECTION_ACTIVE_SEL).hasClass(COMPLETELY)){
33105                        $(SECTION_ACTIVE_SEL).addClass(COMPLETELY).siblings().removeClass(COMPLETELY);
33106                    }
33107                }
33108
33109                //geting the last one, the current one on the screen
33110                currentSection = $(sections).eq(visibleSectionIndex);
33111
33112                //setting the visible section as active when manually scrolling
33113                //executing only once the first time we reach the section
33114                if(!currentSection.hasClass(ACTIVE)){
33115                    isScrolling = true;
33116                    var leavingSection = $(SECTION_ACTIVE_SEL);
33117                    var leavingSectionIndex = leavingSection.index(SECTION_SEL) + 1;
33118                    var yMovement = getYmovement(currentSection);
33119                    var anchorLink  = currentSection.data('anchor');
33120                    var sectionIndex = currentSection.index(SECTION_SEL) + 1;
33121                    var activeSlide = currentSection.find(SLIDE_ACTIVE_SEL);
33122                    var slideIndex;
33123                    var slideAnchorLink;
33124
33125                    if(activeSlide.length){
33126                        slideAnchorLink = activeSlide.data('anchor');
33127                        slideIndex = activeSlide.index();
33128                    }
33129
33130                    if(canScroll){
33131                        currentSection.addClass(ACTIVE).siblings().removeClass(ACTIVE);
33132
33133                        $.isFunction( options.onLeave ) && options.onLeave.call( leavingSection, leavingSectionIndex, sectionIndex, yMovement);
33134                        $.isFunction( options.afterLoad ) && options.afterLoad.call( currentSection, anchorLink, sectionIndex);
33135
33136                        stopMedia(leavingSection);
33137                        lazyLoad(currentSection);
33138                        playMedia(currentSection);
33139
33140                        activateMenuAndNav(anchorLink, sectionIndex - 1);
33141
33142                        if(options.anchors.length){
33143                            //needed to enter in hashChange event when using the menu with anchor links
33144                            lastScrolledDestiny = anchorLink;
33145                        }
33146                        setState(slideIndex, slideAnchorLink, anchorLink, sectionIndex);
33147                    }
33148
33149                    //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet
33150                    clearTimeout(scrollId);
33151                    scrollId = setTimeout(function(){
33152                        isScrolling = false;
33153                    }, 100);
33154                }
33155
33156                if(options.fitToSection){
33157                    //for the auto adjust of the viewport to fit a whole section
33158                    clearTimeout(scrollId2);
33159
33160                    scrollId2 = setTimeout(function(){
33161                        //checking it again in case it changed during the delay
33162                        if(options.fitToSection){
33163                            fitToSection();
33164                        }
33165                    }, options.fitToSectionDelay);
33166                }
33167            }
33168        }
33169
33170        /**
33171        * Fits the site to the nearest active section
33172        */
33173        function fitToSection(){
33174            //checking fitToSection again in case it was set to false before the timeout delay
33175            if(canScroll){
33176                //allows to scroll to an active section and
33177                //if the section is already active, we prevent firing callbacks
33178                isResizing = true;
33179
33180                scrollPage($(SECTION_ACTIVE_SEL));
33181                isResizing = false;
33182            }
33183        }
33184
33185        /**
33186        * Determines whether the active section has seen in its whole or not.
33187        */
33188        function isCompletelyInViewPort(movement){
33189            var top = $(SECTION_ACTIVE_SEL).position().top;
33190            var bottom = top + $window.height();
33191
33192            if(movement == 'up'){
33193                return bottom >= ($window.scrollTop() + $window.height());
33194            }
33195            return top <= $window.scrollTop();
33196        }
33197
33198        /**
33199        * Gets the directon of the the scrolling fired by the scroll event.
33200        */
33201        function getScrollDirection(currentScroll){
33202            var direction = currentScroll > lastScroll ? 'down' : 'up';
33203
33204            lastScroll = currentScroll;
33205
33206            //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination
33207            previousDestTop = currentScroll;
33208
33209            return direction;
33210        }
33211
33212        /**
33213        * Determines the way of scrolling up or down:
33214        * by 'automatically' scrolling a section or by using the default and normal scrolling.
33215        */
33216        function scrolling(type, scrollable){
33217            if (!isScrollAllowed.m[type]){
33218                return;
33219            }
33220            var check = (type === 'down') ? 'bottom' : 'top';
33221            var scrollSection = (type === 'down') ? moveSectionDown : moveSectionUp;
33222
33223            if(scrollable.length > 0 ){
33224                //is the scrollbar at the start/end of the scroll?
33225                if(options.scrollOverflowHandler.isScrolled(check, scrollable)){
33226                    scrollSection();
33227                }else{
33228                    return true;
33229                }
33230            }else{
33231                // moved up/down
33232                scrollSection();
33233            }
33234        }
33235
33236        /*
33237        * Preventing bouncing in iOS #2285
33238        */
33239        function preventBouncing(event){
33240            var e = event.originalEvent;
33241            if(!checkParentForNormalScrollElement(event.target) && options.autoScrolling && isReallyTouch(e) && isScrollAllowed.m.up){
33242                //preventing the easing on iOS devices
33243                event.preventDefault();
33244            }
33245        }
33246
33247        var touchStartY = 0;
33248        var touchStartX = 0;
33249        var touchEndY = 0;
33250        var touchEndX = 0;
33251
33252        /* Detecting touch events
33253
33254        * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it.
33255        * This way, the touchstart and the touch moves shows an small difference between them which is the
33256        * used one to determine the direction.
33257        */
33258        function touchMoveHandler(event){
33259            var e = event.originalEvent;
33260            var activeSection = $(e.target).closest(SECTION_SEL);
33261
33262            // additional: if one of the normalScrollElements isn't within options.normalScrollElementTouchThreshold hops up the DOM chain
33263            if (!checkParentForNormalScrollElement(event.target) && isReallyTouch(e) ) {
33264
33265                if(options.autoScrolling){
33266                    //preventing the easing on iOS devices
33267                    event.preventDefault();
33268                }
33269
33270                var scrollable = options.scrollOverflowHandler.scrollable(activeSection);
33271                var touchEvents = getEventsPage(e);
33272
33273                touchEndY = touchEvents.y;
33274                touchEndX = touchEvents.x;
33275
33276                //if movement in the X axys is greater than in the Y and the currect section has slides...
33277                if (activeSection.find(SLIDES_WRAPPER_SEL).length && Math.abs(touchStartX - touchEndX) > (Math.abs(touchStartY - touchEndY))) {
33278
33279                    //is the movement greater than the minimum resistance to scroll?
33280                    if (!slideMoving && Math.abs(touchStartX - touchEndX) > ($window.outerWidth() / 100 * options.touchSensitivity)) {
33281                        if (touchStartX > touchEndX) {
33282                            if(isScrollAllowed.m.right){
33283                                moveSlideRight(activeSection); //next
33284                            }
33285                        } else {
33286                            if(isScrollAllowed.m.left){
33287                                moveSlideLeft(activeSection); //prev
33288                            }
33289                        }
33290                    }
33291                }
33292
33293                //vertical scrolling (only when autoScrolling is enabled)
33294                else if(options.autoScrolling && canScroll){
33295
33296                    //is the movement greater than the minimum resistance to scroll?
33297                    if (Math.abs(touchStartY - touchEndY) > ($window.height() / 100 * options.touchSensitivity)) {
33298                        if (touchStartY > touchEndY) {
33299                            scrolling('down', scrollable);
33300                        } else if (touchEndY > touchStartY) {
33301                            scrolling('up', scrollable);
33302                        }
33303                    }
33304                }
33305            }
33306        }
33307
33308        /**
33309         * recursive function to loop up the parent nodes to check if one of them exists in options.normalScrollElements
33310         * Currently works well for iOS - Android might need some testing
33311         * @param  {Element} el  target element / jquery selector (in subsequent nodes)
33312         * @param  {int}     hop current hop compared to options.normalScrollElementTouchThreshold
33313         * @return {boolean} true if there is a match to options.normalScrollElements
33314         */
33315        function checkParentForNormalScrollElement (el, hop) {
33316            hop = hop || 0;
33317            var parent = $(el).parent();
33318
33319            if (hop < options.normalScrollElementTouchThreshold &&
33320                parent.is(options.normalScrollElements) ) {
33321                return true;
33322            } else if (hop == options.normalScrollElementTouchThreshold) {
33323                return false;
33324            } else {
33325                return checkParentForNormalScrollElement(parent, ++hop);
33326            }
33327        }
33328
33329        /**
33330        * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen
33331        * this way we make sure that is really a touch event what IE is detecting.
33332        */
33333        function isReallyTouch(e){
33334            //if is not IE   ||  IE is detecting `touch` or `pen`
33335            return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse';
33336        }
33337
33338        /**
33339        * Handler for the touch start event.
33340        */
33341        function touchStartHandler(event){
33342            var e = event.originalEvent;
33343
33344            //stopping the auto scroll to adjust to a section
33345            if(options.fitToSection){
33346                $htmlBody.stop();
33347            }
33348
33349            if(isReallyTouch(e)){
33350                var touchEvents = getEventsPage(e);
33351                touchStartY = touchEvents.y;
33352                touchStartX = touchEvents.x;
33353            }
33354        }
33355
33356        /**
33357        * Gets the average of the last `number` elements of the given array.
33358        */
33359        function getAverage(elements, number){
33360            var sum = 0;
33361
33362            //taking `number` elements from the end to make the average, if there are not enought, 1
33363            var lastElements = elements.slice(Math.max(elements.length - number, 1));
33364
33365            for(var i = 0; i < lastElements.length; i++){
33366                sum = sum + lastElements[i];
33367            }
33368
33369            return Math.ceil(sum/number);
33370        }
33371
33372        /**
33373         * Detecting mousewheel scrolling
33374         *
33375         * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html
33376         * http://www.sitepoint.com/html5-javascript-mouse-wheel/
33377         */
33378        var prevTime = new Date().getTime();
33379
33380        function MouseWheelHandler(e) {
33381            var curTime = new Date().getTime();
33382            var isNormalScroll = $(COMPLETELY_SEL).hasClass(NORMAL_SCROLL);
33383
33384            //autoscrolling and not zooming?
33385            if(options.autoScrolling && !controlPressed && !isNormalScroll){
33386                // cross-browser wheel delta
33387                e = e || window.event;
33388                var value = e.wheelDelta || -e.deltaY || -e.detail;
33389                var delta = Math.max(-1, Math.min(1, value));
33390
33391                var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined';
33392                var isScrollingVertically = (Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta)) || (Math.abs(e.deltaX ) < Math.abs(e.deltaY) || !horizontalDetection);
33393
33394                //Limiting the array to 150 (lets not waste memory!)
33395                if(scrollings.length > 149){
33396                    scrollings.shift();
33397                }
33398
33399                //keeping record of the previous scrollings
33400                scrollings.push(Math.abs(value));
33401
33402                //preventing to scroll the site on mouse wheel when scrollbar is present
33403                if(options.scrollBar){
33404                    e.preventDefault ? e.preventDefault() : e.returnValue = false;
33405                }
33406
33407                var activeSection = $(SECTION_ACTIVE_SEL);
33408                var scrollable = options.scrollOverflowHandler.scrollable(activeSection);
33409
33410                //time difference between the last scroll and the current one
33411                var timeDiff = curTime-prevTime;
33412                prevTime = curTime;
33413
33414                //haven't they scrolled in a while?
33415                //(enough to be consider a different scrolling action to scroll another section)
33416                if(timeDiff > 200){
33417                    //emptying the array, we dont care about old scrollings for our averages
33418                    scrollings = [];
33419                }
33420
33421                if(canScroll){
33422                    var averageEnd = getAverage(scrollings, 10);
33423                    var averageMiddle = getAverage(scrollings, 70);
33424                    var isAccelerating = averageEnd >= averageMiddle;
33425
33426                    //to avoid double swipes...
33427                    if(isAccelerating && isScrollingVertically){
33428                        //scrolling down?
33429                        if (delta < 0) {
33430                            scrolling('down', scrollable);
33431
33432                        //scrolling up?
33433                        }else {
33434                            scrolling('up', scrollable);
33435                        }
33436                    }
33437                }
33438
33439                return false;
33440            }
33441
33442            if(options.fitToSection){
33443                //stopping the auto scroll to adjust to a section
33444                $htmlBody.stop();
33445            }
33446        }
33447
33448        /**
33449        * Slides a slider to the given direction.
33450        * Optional `section` param.
33451        */
33452        function moveSlide(direction, section){
33453            var activeSection = typeof section === 'undefined' ? $(SECTION_ACTIVE_SEL) : section;
33454            var slides = activeSection.find(SLIDES_WRAPPER_SEL);
33455            var numSlides = slides.find(SLIDE_SEL).length;
33456
33457            // more than one slide needed and nothing should be sliding
33458            if (!slides.length || slideMoving || numSlides < 2) {
33459                return;
33460            }
33461
33462            var currentSlide = slides.find(SLIDE_ACTIVE_SEL);
33463            var destiny = null;
33464
33465            if(direction === 'left'){
33466                destiny = currentSlide.prev(SLIDE_SEL);
33467            }else{
33468                destiny = currentSlide.next(SLIDE_SEL);
33469            }
33470
33471            //isn't there a next slide in the secuence?
33472            if(!destiny.length){
33473                //respect loopHorizontal settin
33474                if (!options.loopHorizontal) return;
33475
33476                if(direction === 'left'){
33477                    destiny = currentSlide.siblings(':last');
33478                }else{
33479                    destiny = currentSlide.siblings(':first');
33480                }
33481            }
33482
33483            slideMoving = true;
33484
33485            landscapeScroll(slides, destiny, direction);
33486        }
33487
33488        /**
33489        * Maintains the active slides in the viewport
33490        * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical)
33491        */
33492        function keepSlidesPosition(){
33493            $(SLIDE_ACTIVE_SEL).each(function(){
33494                silentLandscapeScroll($(this), 'internal');
33495            });
33496        }
33497
33498        var previousDestTop = 0;
33499        /**
33500        * Returns the destination Y position based on the scrolling direction and
33501        * the height of the section.
33502        */
33503        function getDestinationPosition(element){
33504            var elemPosition = element.position();
33505
33506            //top of the desination will be at the top of the viewport
33507            var position = elemPosition.top;
33508            var isScrollingDown =  elemPosition.top > previousDestTop;
33509            var sectionBottom = position - windowsHeight + element.outerHeight();
33510            var bigSectionsDestination = options.bigSectionsDestination;
33511
33512            //Uncode addition
33513            var containerH = container.outerHeight();
33514            var containerPosition = container.offset();
33515
33516            //########### Commented by Uncode - START ###########
33517            //is the destination element bigger than the viewport?
33518            // if(element.outerHeight() > windowsHeight){
33519            //     //scrolling up?
33520            //     if(!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom' ){
33521            //         position = sectionBottom;
33522            //     }
33523            // }
33524
33525            // //sections equal or smaller than the viewport height && scrolling down? ||  is resizing and its in the last section
33526            // else if(isScrollingDown || (isResizing && element.is(':last-child')) ){
33527            //     //The bottom of the destination will be at the bottom of the viewport
33528            //     position = sectionBottom;
33529            // }
33530            //########### Commented by Uncode - END ###########
33531
33532            //Uncode addition
33533            if ( !$masthead.hasClass('menu-transparent') && $('body').hasClass('uncode-fp-menu-shrink') && !element.is(':first-child') )
33534                position += 18;
33535            if ( ( containerH + menuHeight + bodyBorder + adminBarHeight - windowsHeight ) < position || ( isResizing && element.is(':last-child') ) ) {
33536                position = sectionBottom + menuHeight + bodyBorder*2 + adminBarHeight;
33537            }
33538
33539            /*
33540            Keeping record of the last scrolled position to determine the scrolling direction.
33541            No conventional methods can be used as the scroll bar might not be present
33542            AND the section might not be active if it is auto-height and didnt reach the middle
33543            of the viewport.
33544            */
33545            previousDestTop = position;
33546            return position;
33547        }
33548
33549        /**
33550        * Scrolls the site to the given element and scrolls to the slide if a callback is given.
33551        */
33552        function scrollPage(element, callback, isMovementUp){
33553            if(typeof element === 'undefined'){ return; } //there's no element to scroll, leaving the function
33554
33555            var dtop = getDestinationPosition(element);
33556            var slideAnchorLink;
33557            var slideIndex;
33558
33559            //local variables
33560            var v = {
33561                element: element,
33562                callback: callback,
33563                isMovementUp: isMovementUp,
33564                dtop: dtop,
33565                yMovement: getYmovement(element),
33566                anchorLink: element.data('anchor'),
33567                sectionIndex: element.index(SECTION_SEL),
33568                activeSlide: element.find(SLIDE_ACTIVE_SEL),
33569                activeSection: $(SECTION_ACTIVE_SEL),
33570                leavingSection: $(SECTION_ACTIVE_SEL).index(SECTION_SEL) + 1,
33571
33572                //caching the value of isResizing at the momment the function is called
33573                //because it will be checked later inside a setTimeout and the value might change
33574                localIsResizing: isResizing
33575            };
33576
33577            //quiting when destination scroll is the same as the current one
33578            if((v.activeSection.is(element) && !isResizing) || (options.scrollBar && $window.scrollTop() === v.dtop && !element.hasClass(AUTO_HEIGHT) )){ return; }
33579
33580            if(v.activeSlide.length){
33581                slideAnchorLink = v.activeSlide.data('anchor');
33582                slideIndex = v.activeSlide.index();
33583            }
33584
33585            // If continuousVertical && we need to wrap around
33586            if (options.autoScrolling && options.continuousVertical && typeof (v.isMovementUp) !== "undefined" &&
33587                ((!v.isMovementUp && v.yMovement == 'up') || // Intending to scroll down but about to go up or
33588                (v.isMovementUp && v.yMovement == 'down'))) { // intending to scroll up but about to go down
33589
33590                v = createInfiniteSections(v);
33591            }
33592
33593            //callback (onLeave) if the site is not just resizing and readjusting the slides
33594            if($.isFunction(options.onLeave) && !v.localIsResizing){
33595                if(options.onLeave.call(v.activeSection, v.leavingSection, (v.sectionIndex + 1), v.yMovement) === false){
33596                    return;
33597                }
33598            }
33599
33600            //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one)
33601            if(!v.localIsResizing){
33602                stopMedia(v.activeSection);
33603            }
33604
33605            options.scrollOverflowHandler.beforeLeave();
33606            element.addClass(ACTIVE).siblings().removeClass(ACTIVE);
33607            lazyLoad(element);
33608            options.scrollOverflowHandler.onLeave();
33609
33610
33611            //preventing from activating the MouseWheelHandler event
33612            //more than once if the page is scrolling
33613            canScroll = false;
33614
33615            setState(slideIndex, slideAnchorLink, v.anchorLink, v.sectionIndex);
33616
33617            performMovement(v);
33618
33619            //flag to avoid callingn `scrollPage()` twice in case of using anchor links
33620            lastScrolledDestiny = v.anchorLink;
33621
33622            //avoid firing it twice (as it does also on scroll)
33623            activateMenuAndNav(v.anchorLink, v.sectionIndex);
33624        }
33625
33626        /**
33627        * Performs the vertical movement (by CSS3 or by jQuery)
33628        */
33629        function performMovement(v){
33630            // using CSS3 translate functionality
33631            if (options.css3 && options.autoScrolling && !options.scrollBar) {
33632
33633                // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
33634                // that's why we round it to 0.
33635                var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)';
33636                transformContainer(translate3d, true);
33637
33638                //even when the scrollingSpeed is 0 there's a little delay, which might cause the
33639                //scrollingSpeed to change in case of using silentMoveTo();
33640                if(options.scrollingSpeed){
33641                    clearTimeout(afterSectionLoadsId);
33642                    afterSectionLoadsId = setTimeout(function () {
33643                        afterSectionLoads(v);
33644                    }, options.scrollingSpeed);
33645                }else{
33646                    afterSectionLoads(v);
33647                }
33648            }
33649
33650            // using jQuery animate
33651            else{
33652                var scrollSettings = getScrollSettings(v);
33653
33654                $(scrollSettings.element).animate(
33655                    scrollSettings.options,
33656                options.scrollingSpeed, options.easing).promise().done(function () { //only one single callback in case of animating  `html, body`
33657                    if(options.scrollBar){
33658
33659                        /* Hack!
33660                        The timeout prevents setting the most dominant section in the viewport as "active" when the user
33661                        scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar.
33662
33663                        When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished.
33664                        */
33665                        setTimeout(function(){
33666                            afterSectionLoads(v);
33667                        },30);
33668                    }else{
33669                        afterSectionLoads(v);
33670                    }
33671                });
33672            }
33673        }
33674
33675        /**
33676        * Gets the scrolling settings depending on the plugin autoScrolling option
33677        */
33678        function getScrollSettings(v){
33679            var scroll = {};
33680
33681            if(options.autoScrolling && !options.scrollBar){
33682                scroll.options = { 'top': -v.dtop};
33683                scroll.element = WRAPPER_SEL;
33684            }else{
33685                scroll.options = { 'scrollTop': v.dtop};
33686                scroll.element = 'html, body';
33687            }
33688
33689            return scroll;
33690        }
33691
33692        /**
33693        * Adds sections before or after the current one to create the infinite effect.
33694        */
33695        function createInfiniteSections(v){
33696            // Scrolling down
33697            if (!v.isMovementUp) {
33698                // Move all previous sections to after the active section
33699                $(SECTION_ACTIVE_SEL).after(v.activeSection.prevAll(SECTION_SEL).get().reverse());
33700            }
33701            else { // Scrolling up
33702                // Move all next sections to before the active section
33703                $(SECTION_ACTIVE_SEL).before(v.activeSection.nextAll(SECTION_SEL));
33704            }
33705
33706            // Maintain the displayed position (now that we changed the element order)
33707            silentScroll($(SECTION_ACTIVE_SEL).position().top);
33708
33709            // Maintain the active slides visible in the viewport
33710            keepSlidesPosition();
33711
33712            // save for later the elements that still need to be reordered
33713            v.wrapAroundElements = v.activeSection;
33714
33715            // Recalculate animation variables
33716            v.dtop = v.element.position().top;
33717            v.yMovement = getYmovement(v.element);
33718
33719            return v;
33720        }
33721
33722        /**
33723        * Fix section order after continuousVertical changes have been animated
33724        */
33725        function continuousVerticalFixSectionOrder (v) {
33726            // If continuousVertical is in effect (and autoScrolling would also be in effect then),
33727            // finish moving the elements around so the direct navigation will function more simply
33728            if (!v.wrapAroundElements || !v.wrapAroundElements.length) {
33729                return;
33730            }
33731
33732            if (v.isMovementUp) {
33733                $(SECTION_FIRST_SEL).before(v.wrapAroundElements);
33734            }
33735            else {
33736                $(SECTION_LAST_SEL).after(v.wrapAroundElements);
33737            }
33738
33739            silentScroll($(SECTION_ACTIVE_SEL).position().top);
33740
33741            // Maintain the active slides visible in the viewport
33742            keepSlidesPosition();
33743        }
33744
33745
33746        /**
33747        * Actions to do once the section is loaded.
33748        */
33749        function afterSectionLoads (v){
33750            continuousVerticalFixSectionOrder(v);
33751
33752            //callback (afterLoad) if the site is not just resizing and readjusting the slides
33753            $.isFunction(options.afterLoad) && !v.localIsResizing && options.afterLoad.call(v.element, v.anchorLink, (v.sectionIndex + 1));
33754            options.scrollOverflowHandler.afterLoad();
33755
33756            if(!v.localIsResizing){
33757                playMedia(v.element);
33758            }
33759
33760            v.element.addClass(COMPLETELY).siblings().removeClass(COMPLETELY);
33761
33762            canScroll = true;
33763
33764            $.isFunction(v.callback) && v.callback.call(this);
33765        }
33766
33767        /**
33768        * Sets the value for the given attribute from the `data-` attribute with the same suffix
33769        * ie: data-srcset ==> srcset  |  data-src ==> src
33770        */
33771        function setSrc(element, attribute){
33772            element
33773                .attr(attribute, element.data(attribute))
33774                .removeAttr('data-' + attribute);
33775        }
33776
33777        /**
33778        * Lazy loads image, video and audio elements.
33779        */
33780        function lazyLoad(destiny){
33781            if (!options.lazyLoading){
33782                return;
33783            }
33784
33785            var panel = getSlideOrSection(destiny);
33786            var element;
33787
33788            panel.find('img[data-src], img[data-srcset], source[data-src], audio[data-src], iframe[data-src]').each(function(){
33789                element = $(this);
33790
33791                $.each(['src', 'srcset'], function(index, type){
33792                    var attribute = element.attr('data-' + type);
33793                    if(typeof attribute !== 'undefined' && attribute){
33794                        setSrc(element, type);
33795                    }
33796                });
33797
33798                if(element.is('source')){
33799                    element.closest('video').get(0).load();
33800                }
33801            });
33802        }
33803
33804        /**
33805        * Plays video and audio elements.
33806        */
33807        function playMedia(destiny){
33808            var panel = getSlideOrSection(destiny);
33809
33810            //playing HTML5 media elements
33811            panel.find('video, audio').each(function(){
33812                var element = $(this).get(0);
33813
33814                if( element.hasAttribute('data-autoplay') && typeof element.play === 'function' ) {
33815                    element.play();
33816                }
33817            });
33818
33819            //youtube videos
33820            panel.find('iframe[src*="youtube.com/embed/"]').each(function(){
33821                var element = $(this).get(0);
33822
33823                if ( element.hasAttribute('data-autoplay') ){
33824                    playYoutube(element);
33825                }
33826
33827                //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load.
33828                element.onload = function() {
33829                    if ( element.hasAttribute('data-autoplay') ){
33830                        playYoutube(element);
33831                    }
33832                };
33833            });
33834        }
33835
33836        /**
33837        * Plays a youtube video
33838        */
33839        function playYoutube(element){
33840            element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
33841        }
33842
33843        /**
33844        * Stops video and audio elements.
33845        */
33846        function stopMedia(destiny){
33847            var panel = getSlideOrSection(destiny);
33848
33849            //stopping HTML5 media elements
33850            panel.find('video, audio').each(function(){
33851                var element = $(this).get(0);
33852
33853                if( !element.hasAttribute('data-keepplaying') && typeof element.pause === 'function' ) {
33854                    element.pause();
33855                }
33856            });
33857
33858            //youtube videos
33859            panel.find('iframe[src*="youtube.com/embed/"]').each(function(){
33860                var element = $(this).get(0);
33861
33862                if( /youtube\.com\/embed\//.test($(this).attr('src')) && !element.hasAttribute('data-keepplaying')){
33863                    $(this).get(0).contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}','*');
33864                }
33865            });
33866        }
33867
33868        /**
33869        * Gets the active slide (or section) for the given section
33870        */
33871        function getSlideOrSection(destiny){
33872            var slide = destiny.find(SLIDE_ACTIVE_SEL);
33873            if( slide.length ) {
33874                destiny = $(slide);
33875            }
33876
33877            return destiny;
33878        }
33879
33880        /**
33881        * Scrolls to the anchor in the URL when loading the site
33882        */
33883        function scrollToAnchor(){
33884            //getting the anchor link in the URL and deleting the `#`
33885            var value =  window.location.hash.replace('#', '').split('/');
33886            var sectionAnchor = decodeURIComponent(value[0]);
33887            var slideAnchor = decodeURIComponent(value[1]);
33888
33889            if(sectionAnchor){  //if theres any #
33890                if(options.animateAnchor){
33891                    scrollPageAndSlide(sectionAnchor, slideAnchor);
33892                }else{
33893                    silentMoveTo(sectionAnchor, slideAnchor);
33894                }
33895            }
33896        }
33897
33898        /**
33899        * Detecting any change on the URL to scroll to the given anchor link
33900        * (a way to detect back history button as we play with the hashes on the URL)
33901        */
33902        function hashChangeHandler(){
33903            if(!isScrolling && !options.lockAnchors){
33904                var value =  window.location.hash.replace('#', '').split('/');
33905                var sectionAnchor = decodeURIComponent(value[0]);
33906                var slideAnchor = decodeURIComponent(value[1]);
33907
33908                    //when moving to a slide in the first section for the first time (first time to add an anchor to the URL)
33909                    var isFirstSlideMove =  (typeof lastScrolledDestiny === 'undefined');
33910                    var isFirstScrollMove = (typeof lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !slideMoving);
33911
33912
33913                if(sectionAnchor.length){
33914                    /*in order to call scrollpage() only once for each destination at a time
33915                    It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange`
33916                    event is fired on every scroll too.*/
33917                    if ((sectionAnchor && sectionAnchor !== lastScrolledDestiny) && !isFirstSlideMove || isFirstScrollMove || (!slideMoving && lastScrolledSlide != slideAnchor ))  {
33918                        scrollPageAndSlide(sectionAnchor, slideAnchor);
33919                    }
33920                }
33921            }
33922        }
33923
33924        //Sliding with arrow keys, both, vertical and horizontal
33925        function keydownHandler(e) {
33926
33927            clearTimeout(keydownId);
33928
33929            var activeElement = $(':focus');
33930
33931            if(!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select') &&
33932                activeElement.attr('contentEditable') !== "true" && activeElement.attr('contentEditable') !== '' &&
33933                options.keyboardScrolling && options.autoScrolling){
33934                var keyCode = e.which;
33935
33936                //preventing the scroll with arrow keys & spacebar & Page Up & Down keys
33937                var keyControls = [40, 38, 32, 33, 34];
33938                if($.inArray(keyCode, keyControls) > -1){
33939                    e.preventDefault();
33940                }
33941
33942                controlPressed = e.ctrlKey;
33943
33944                keydownId = setTimeout(function(){
33945                    onkeydown(e);
33946                },150);
33947            }
33948        }
33949
33950        function tooltipTextHandler(){
33951            $(this).prev().trigger('click');
33952        }
33953
33954        //to prevent scrolling while zooming
33955        function keyUpHandler(e){
33956            if(isWindowFocused){ //the keyup gets fired on new tab ctrl + t in Firefox
33957                controlPressed = e.ctrlKey;
33958            }
33959        }
33960
33961        //binding the mousemove when the mouse's middle button is released
33962        function mouseDownHandler(e){
33963            //middle button
33964            if (e.which == 2){
33965                oldPageY = e.pageY;
33966                container.on('mousemove', mouseMoveHandler);
33967            }
33968        }
33969
33970        //unbinding the mousemove when the mouse's middle button is released
33971        function mouseUpHandler(e){
33972            //middle button
33973            if (e.which == 2){
33974                container.off('mousemove');
33975            }
33976        }
33977
33978        //Scrolling horizontally when clicking on the slider controls.
33979        function slideArrowHandler(){
33980            var section = $(this).closest(SECTION_SEL);
33981
33982            if ($(this).hasClass(SLIDES_PREV)) {
33983                if(isScrollAllowed.m.left){
33984                    moveSlideLeft(section);
33985                }
33986            } else {
33987                if(isScrollAllowed.m.right){
33988                    moveSlideRight(section);
33989                }
33990            }
33991        }
33992
33993        //when opening a new tab (ctrl + t), `control` won't be pressed when coming back.
33994        function blurHandler(){
33995            isWindowFocused = false;
33996            controlPressed = false;
33997        }
33998
33999        //Scrolls to the section when clicking the navigation bullet
34000        function sectionBulletHandler(e){
34001            e.preventDefault();
34002            var index = $(this).parent().index();
34003            scrollPage($(SECTION_SEL).eq(index));
34004        }
34005
34006        //Scrolls the slider to the given slide destination for the given section
34007        function slideBulletHandler(e){
34008            e.preventDefault();
34009            var slides = $(this).closest(SECTION_SEL).find(SLIDES_WRAPPER_SEL);
34010            var destiny = slides.find(SLIDE_SEL).eq($(this).closest('li').index());
34011
34012            landscapeScroll(slides, destiny);
34013        }
34014
34015        /**
34016        * Keydown event
34017        */
34018        function onkeydown(e){
34019            var shiftPressed = e.shiftKey;
34020
34021            //do nothing if we can not scroll or we are not using horizotnal key arrows.
34022            if(!canScroll && [37,39].indexOf(e.which) < 0){
34023                return;
34024            }
34025
34026            switch (e.which) {
34027                //up
34028                case 38:
34029                case 33:
34030                    if(isScrollAllowed.k.up){
34031                        moveSectionUp();
34032                    }
34033                    break;
34034
34035                //down
34036                case 32: //spacebar
34037                    if(shiftPressed && isScrollAllowed.k.up){
34038                        moveSectionUp();
34039                        break;
34040                    }
34041                /* falls through */
34042                case 40:
34043                case 34:
34044                    if(isScrollAllowed.k.down){
34045                        moveSectionDown();
34046                    }
34047                    break;
34048
34049                //Home
34050                case 36:
34051                    if(isScrollAllowed.k.up){
34052                        moveTo(1);
34053                    }
34054                    break;
34055
34056                //End
34057                case 35:
34058                     if(isScrollAllowed.k.down){
34059                        moveTo( $(SECTION_SEL).length );
34060                    }
34061                    break;
34062
34063                //left
34064                case 37:
34065                    if(isScrollAllowed.k.left){
34066                        moveSlideLeft();
34067                    }
34068                    break;
34069
34070                //right
34071                case 39:
34072                    if(isScrollAllowed.k.right){
34073                        moveSlideRight();
34074                    }
34075                    break;
34076
34077                default:
34078                    return; // exit this handler for other keys
34079            }
34080        }
34081
34082        /**
34083        * Detecting the direction of the mouse movement.
34084        * Used only for the middle button of the mouse.
34085        */
34086        var oldPageY = 0;
34087        function mouseMoveHandler(e){
34088            if(canScroll){
34089                // moving up
34090                if (e.pageY < oldPageY && isScrollAllowed.m.up){
34091                    moveSectionUp();
34092                }
34093
34094                // moving down
34095                else if(e.pageY > oldPageY && isScrollAllowed.m.down){
34096                    moveSectionDown();
34097                }
34098            }
34099            oldPageY = e.pageY;
34100        }
34101
34102        /**
34103        * Scrolls horizontal sliders.
34104        */
34105        function landscapeScroll(slides, destiny, direction){
34106            var section = slides.closest(SECTION_SEL);
34107            var v = {
34108                slides: slides,
34109                destiny: destiny,
34110                direction: direction,
34111                destinyPos: destiny.position(),
34112                slideIndex: destiny.index(),
34113                section: section,
34114                sectionIndex: section.index(SECTION_SEL),
34115                anchorLink: section.data('anchor'),
34116                slidesNav: section.find(SLIDES_NAV_SEL),
34117                slideAnchor:  getAnchor(destiny),
34118                prevSlide: section.find(SLIDE_ACTIVE_SEL),
34119                prevSlideIndex: section.find(SLIDE_ACTIVE_SEL).index(),
34120
34121                //caching the value of isResizing at the momment the function is called
34122                //because it will be checked later inside a setTimeout and the value might change
34123                localIsResizing: isResizing
34124            };
34125            v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex);
34126            v.direction = v.direction ? v.direction : v.xMovement;
34127
34128            //important!! Only do it when not resizing
34129            if(!v.localIsResizing){
34130                //preventing from scrolling to the next/prev section when using scrollHorizontally
34131                canScroll = false;
34132            }
34133
34134            if(options.onSlideLeave){
34135
34136                //if the site is not just resizing and readjusting the slides
34137                if(!v.localIsResizing && v.xMovement!=='none'){
34138                    if($.isFunction( options.onSlideLeave )){
34139                        if(options.onSlideLeave.call( v.prevSlide, v.anchorLink, (v.sectionIndex + 1), v.prevSlideIndex, v.xMovement, v.slideIndex ) === false){
34140                            slideMoving = false;
34141                            return;
34142                        }
34143                    }
34144                }
34145            }
34146
34147            destiny.addClass(ACTIVE).siblings().removeClass(ACTIVE);
34148
34149            if(!v.localIsResizing){
34150                stopMedia(v.prevSlide);
34151                lazyLoad(destiny);
34152            }
34153
34154            if(!options.loopHorizontal && options.controlArrows){
34155                //hidding it for the fist slide, showing for the rest
34156                section.find(SLIDES_ARROW_PREV_SEL).toggle(v.slideIndex!==0);
34157
34158                //hidding it for the last slide, showing for the rest
34159                section.find(SLIDES_ARROW_NEXT_SEL).toggle(!destiny.is(':last-child'));
34160            }
34161
34162            //only changing the URL if the slides are in the current section (not for resize re-adjusting)
34163            if(section.hasClass(ACTIVE) && !v.localIsResizing){
34164                setState(v.slideIndex, v.slideAnchor, v.anchorLink, v.sectionIndex);
34165            }
34166
34167            performHorizontalMove(slides, v, true);
34168        }
34169
34170
34171        function afterSlideLoads(v){
34172            activeSlidesNavigation(v.slidesNav, v.slideIndex);
34173
34174            //if the site is not just resizing and readjusting the slides
34175            if(!v.localIsResizing){
34176                $.isFunction( options.afterSlideLoad ) && options.afterSlideLoad.call( v.destiny, v.anchorLink, (v.sectionIndex + 1), v.slideAnchor, v.slideIndex);
34177
34178                //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally
34179                //and to prevent double scroll right after a windows resize
34180                canScroll = true;
34181
34182                playMedia(v.destiny);
34183            }
34184
34185            //letting them slide again
34186            slideMoving = false;
34187        }
34188
34189        /**
34190        * Performs the horizontal movement. (CSS3 or jQuery)
34191        *
34192        * @param fireCallback {Bool} - determines whether or not to fire the callback
34193        */
34194        function performHorizontalMove(slides, v, fireCallback){
34195            var destinyPos = v.destinyPos;
34196
34197            if(options.css3){
34198                var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)';
34199
34200                addAnimation(slides.find(SLIDES_CONTAINER_SEL)).css(getTransforms(translate3d), v);
34201
34202                afterSlideLoadsId = setTimeout(function(){
34203                    fireCallback && afterSlideLoads(v);
34204                }, options.scrollingSpeed, options.easing);
34205            }else{
34206                slides.animate({
34207                    scrollLeft : Math.round(destinyPos.left)
34208                }, options.scrollingSpeed, options.easing, function() {
34209
34210                    fireCallback && afterSlideLoads(v);
34211                });
34212            }
34213        }
34214
34215        /**
34216        * Sets the state for the horizontal bullet navigations.
34217        */
34218        function activeSlidesNavigation(slidesNav, slideIndex){
34219            slidesNav.find(ACTIVE_SEL).removeClass(ACTIVE);
34220            slidesNav.find('li').eq(slideIndex).find('a').addClass(ACTIVE);
34221        }
34222
34223        var previousHeight = windowsHeight;
34224
34225        //when resizing the site, we adjust the heights of the sections, slimScroll...
34226        function resizeHandler(){
34227            //checking if it needs to get responsive
34228            responsive();
34229
34230            // rebuild immediately on touch devices
34231            if (isTouchDevice) {
34232                var activeElement = $(document.activeElement);
34233
34234                //if the keyboard is NOT visible
34235                if (!activeElement.is('textarea') && !activeElement.is('input') && !activeElement.is('select')) {
34236                    var currentHeight = $window.height();
34237
34238                    //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)
34239                    if( Math.abs(currentHeight - previousHeight) > (20 * Math.max(previousHeight, currentHeight) / 100) ){
34240                        reBuild(true);
34241                        previousHeight = currentHeight;
34242                    }
34243                }
34244            }else{
34245                //in order to call the functions only when the resize is finished
34246                //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing
34247                clearTimeout(resizeId);
34248
34249                resizeId = setTimeout(function(){
34250                    reBuild(true);
34251                }, 350);
34252            }
34253        }
34254
34255        /**
34256        * Checks if the site needs to get responsive and disables autoScrolling if so.
34257        * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS.
34258        */
34259        function responsive(){
34260            var widthLimit = options.responsive || options.responsiveWidth; //backwards compatiblity
34261            var heightLimit = options.responsiveHeight;
34262
34263            //only calculating what we need. Remember its called on the resize event.
34264            var isBreakingPointWidth = widthLimit && $window.outerWidth() < widthLimit;
34265            var isBreakingPointHeight = heightLimit && $window.height() < heightLimit;
34266
34267            if(widthLimit && heightLimit){
34268                setResponsive(isBreakingPointWidth || isBreakingPointHeight);
34269            }
34270            else if(widthLimit){
34271                setResponsive(isBreakingPointWidth);
34272            }
34273            else if(heightLimit){
34274                setResponsive(isBreakingPointHeight);
34275            }
34276        }
34277
34278        /**
34279        * Adds transition animations for the given element
34280        */
34281        function addAnimation(container, element){
34282            var transition = 'all ' + options.scrollingSpeed + 'ms ' + options.easingcss3;
34283
34284            container.removeClass(NO_TRANSITION);
34285            return container.css({
34286                '-webkit-transition': transition,
34287                'transition': transition
34288            });
34289        }
34290
34291        /**
34292        * Remove transition animations for the given element
34293        */
34294        function removeAnimation(element){
34295            return element.addClass(NO_TRANSITION);
34296        }
34297
34298        /**
34299        * Activating the vertical navigation bullets according to the given slide name.
34300        */
34301        function activateNavDots(name, sectionIndex){
34302            if(options.navigation){
34303                $(SECTION_NAV_SEL).find(ACTIVE_SEL).removeClass(ACTIVE);
34304                if(name){
34305                    $(SECTION_NAV_SEL).find('a[href="#' + name + '"]').addClass(ACTIVE);
34306                }else{
34307                    $(SECTION_NAV_SEL).find('li').eq(sectionIndex).find('a').addClass(ACTIVE);
34308                }
34309            }
34310        }
34311
34312        /**
34313        * Activating the website main menu elements according to the given slide name.
34314        */
34315        function activateMenuElement(name){
34316            if(options.menu){
34317                $(options.menu).find(ACTIVE_SEL).removeClass(ACTIVE);
34318                $(options.menu).find('[data-menuanchor="'+name+'"]').addClass(ACTIVE);
34319            }
34320        }
34321
34322        /**
34323        * Sets to active the current menu and vertical nav items.
34324        */
34325        function activateMenuAndNav(anchor, index){
34326            activateMenuElement(anchor);
34327            activateNavDots(anchor, index);
34328        }
34329
34330        /**
34331        * Retuns `up` or `down` depending on the scrolling movement to reach its destination
34332        * from the current section.
34333        */
34334        function getYmovement(destiny){
34335            var fromIndex = $(SECTION_ACTIVE_SEL).index(SECTION_SEL);
34336            var toIndex = destiny.index(SECTION_SEL);
34337            if( fromIndex == toIndex){
34338                return 'none';
34339            }
34340            if(fromIndex > toIndex){
34341                return 'up';
34342            }
34343            return 'down';
34344        }
34345
34346        /**
34347        * Retuns `right` or `left` depending on the scrolling movement to reach its destination
34348        * from the current slide.
34349        */
34350        function getXmovement(fromIndex, toIndex){
34351            if( fromIndex == toIndex){
34352                return 'none';
34353            }
34354            if(fromIndex > toIndex){
34355                return 'left';
34356            }
34357            return 'right';
34358        }
34359
34360        /**
34361        * Checks if the element needs scrollbar and if the user wants to apply it.
34362        * If so it creates it.
34363        *
34364        * @param {Object} element   jQuery object of the section or slide
34365        */
34366        function createScrollBar(element){
34367            //User doesn't want scrollbar here? Sayonara baby!
34368            if(element.hasClass('fp-noscroll')) return;
34369
34370            //needed to make `scrollHeight` work under Opera 12
34371            element.css('overflow', 'hidden');
34372
34373            var scrollOverflowHandler = options.scrollOverflowHandler;
34374            var wrap = scrollOverflowHandler.wrapContent();
34375            //in case element is a slide
34376            var section = element.closest(SECTION_SEL);
34377            var scrollable = scrollOverflowHandler.scrollable(element);
34378            var contentHeight;
34379
34380            //if there was scroll, the contentHeight will be the one in the scrollable section
34381            if(scrollable.length){
34382                contentHeight = scrollOverflowHandler.scrollHeight(element);
34383            }else{
34384                contentHeight = element.get(0).scrollHeight;
34385                if(options.verticalCentered){
34386                    contentHeight = element.find(TABLE_CELL_SEL).get(0).scrollHeight;
34387                }
34388            }
34389
34390            var scrollHeight = windowsHeight - parseInt(section.css('padding-bottom')) - parseInt(section.css('padding-top'));
34391
34392            //needs scroll?
34393            if ( contentHeight > scrollHeight) {
34394                //did we already have an scrollbar ? Updating it
34395                if(scrollable.length){
34396                    scrollOverflowHandler.update(element, scrollHeight);
34397                }
34398                //creating the scrolling
34399                else{
34400                    if(options.verticalCentered){
34401                        element.find(TABLE_CELL_SEL).wrapInner(wrap);
34402                    }else{
34403                        element.wrapInner(wrap);
34404                    }
34405                    scrollOverflowHandler.create(element, scrollHeight);
34406                }
34407            }
34408            //removing the scrolling when it is not necessary anymore
34409            else{
34410                scrollOverflowHandler.remove(element);
34411            }
34412
34413            //undo
34414            element.css('overflow', '');
34415        }
34416
34417        function addTableClass(element){
34418            //In case we are styling for the 2nd time as in with reponsiveSlides
34419            if(!element.hasClass(TABLE)){
34420                element.addClass(TABLE).wrapInner('<div class="' + TABLE_CELL + '" style="height:' + getTableHeight(element) + 'px;" />');
34421            }
34422        }
34423
34424        function getTableHeight(element){
34425            var sectionHeight = windowsHeight;
34426
34427            if(options.paddingTop || options.paddingBottom){
34428                var section = element;
34429                if(!section.hasClass(SECTION)){
34430                    section = element.closest(SECTION_SEL);
34431                }
34432
34433                var paddings = parseInt(section.css('padding-top')) + parseInt(section.css('padding-bottom'));
34434                sectionHeight = (windowsHeight - paddings);
34435            }
34436
34437            return sectionHeight;
34438        }
34439
34440        /**
34441        * Adds a css3 transform property to the container class with or without animation depending on the animated param.
34442        */
34443        function transformContainer(translate3d, animated){
34444            if(animated){
34445                addAnimation(container);
34446            }else{
34447                removeAnimation(container);
34448            }
34449
34450            container.css(getTransforms(translate3d));
34451
34452            //syncronously removing the class after the animation has been applied.
34453            setTimeout(function(){
34454                container.removeClass(NO_TRANSITION);
34455            },10);
34456        }
34457
34458        /**
34459        * Gets a section by its anchor / index
34460        */
34461        function getSectionByAnchor(sectionAnchor){
34462            if(!sectionAnchor) return [];
34463
34464            var section = container.find(SECTION_SEL + '[data-anchor="'+sectionAnchor+'"]');
34465            if(!section.length){
34466                section = $(SECTION_SEL).eq( sectionAnchor -1);
34467            }
34468
34469            return section;
34470        }
34471
34472        /**
34473        * Gets a slide inside a given section by its anchor / index
34474        */
34475        function getSlideByAnchor(slideAnchor, section){
34476            var slides = section.find(SLIDES_WRAPPER_SEL);
34477            var slide =  slides.find(SLIDE_SEL + '[data-anchor="'+slideAnchor+'"]');
34478
34479            if(!slide.length){
34480                slide = slides.find(SLIDE_SEL).eq(slideAnchor);
34481            }
34482
34483            return slide;
34484        }
34485
34486        /**
34487        * Scrolls to the given section and slide anchors
34488        */
34489        function scrollPageAndSlide(destiny, slide){
34490            var section = getSectionByAnchor(destiny);
34491
34492            //do nothing if there's no section with the given anchor name
34493            if(!section.length) return;
34494
34495            //default slide
34496            if (typeof slide === 'undefined') {
34497                slide = 0;
34498            }
34499
34500            //we need to scroll to the section and then to the slide
34501            if (destiny !== lastScrolledDestiny && !section.hasClass(ACTIVE)){
34502                scrollPage(section, function(){
34503                    scrollSlider(section, slide);
34504                });
34505            }
34506            //if we were already in the section
34507            else{
34508                scrollSlider(section, slide);
34509            }
34510        }
34511
34512        /**
34513        * Scrolls the slider to the given slide destination for the given section
34514        */
34515        function scrollSlider(section, slideAnchor){
34516            if(typeof slideAnchor !== 'undefined'){
34517                var slides = section.find(SLIDES_WRAPPER_SEL);
34518                var destiny =  getSlideByAnchor(slideAnchor, section);
34519
34520                if(destiny.length){
34521                    landscapeScroll(slides, destiny);
34522                }
34523            }
34524        }
34525
34526        /**
34527        * Creates a landscape navigation bar with dots for horizontal sliders.
34528        */
34529        function addSlidesNavigation(section, numSlides){
34530            section.append('<div class="' + SLIDES_NAV + '"><ul></ul></div>');
34531            var nav = section.find(SLIDES_NAV_SEL);
34532
34533            //top or bottom
34534            nav.addClass(options.slidesNavPosition);
34535
34536            for(var i=0; i< numSlides; i++){
34537                nav.find('ul').append('<li><a href="#"><span></span></a></li>');
34538            }
34539
34540            //centering it
34541            nav.css('margin-left', '-' + (nav.width()/2) + 'px');
34542
34543            nav.find('li').first().find('a').addClass(ACTIVE);
34544        }
34545
34546
34547        /**
34548        * Sets the state of the website depending on the active section/slide.
34549        * It changes the URL hash when needed and updates the body class.
34550        */
34551        function setState(slideIndex, slideAnchor, anchorLink, sectionIndex){
34552            var sectionHash = '';
34553
34554            if(options.anchors.length && !options.lockAnchors){
34555
34556                //isn't it the first slide?
34557                if(slideIndex){
34558                    if(typeof anchorLink !== 'undefined'){
34559                        sectionHash = anchorLink;
34560                    }
34561
34562                    //slide without anchor link? We take the index instead.
34563                    if(typeof slideAnchor === 'undefined'){
34564                        slideAnchor = slideIndex;
34565                    }
34566
34567                    lastScrolledSlide = slideAnchor;
34568                    setUrlHash(sectionHash + '/' + slideAnchor);
34569
34570                //first slide won't have slide anchor, just the section one
34571                }else if(typeof slideIndex !== 'undefined'){
34572                    lastScrolledSlide = slideAnchor;
34573                    setUrlHash(anchorLink);
34574                }
34575
34576                //section without slides
34577                else{
34578                    setUrlHash(anchorLink);
34579                }
34580            }
34581
34582            setBodyClass();
34583        }
34584
34585        /**
34586        * Sets the URL hash.
34587        */
34588        function setUrlHash(url){
34589            //Uncode addition
34590            if ( typeof SiteParameters.slide_footer != 'undefined' && url == SiteParameters.slide_footer )
34591                return false;
34592
34593            if(options.recordHistory){
34594                location.hash = url;
34595            }else{
34596                //Uncode addition
34597                //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :)
34598                // if(isTouchDevice || isTouch){
34599                //     window.history.replaceState(undefined, undefined, '#' + url);
34600                // }else{
34601                //     var baseUrl = window.location.href.split('#')[0];
34602                //     window.location.replace( baseUrl + '#' + url );
34603                // }
34604                return false;
34605            }
34606        }
34607
34608        /**
34609        * Gets the anchor for the given slide / section. Its index will be used if there's none.
34610        */
34611        function getAnchor(element){
34612            var anchor = element.data('anchor');
34613            var index = element.index();
34614
34615            //Slide without anchor link? We take the index instead.
34616            if(typeof anchor === 'undefined'){
34617                anchor = index;
34618            }
34619
34620            return anchor;
34621        }
34622
34623        /**
34624        * Sets a class for the body of the page depending on the active section / slide
34625        */
34626        function setBodyClass(){
34627            var section = $(SECTION_ACTIVE_SEL);
34628            var slide = section.find(SLIDE_ACTIVE_SEL);
34629
34630            var sectionAnchor = getAnchor(section);
34631            var slideAnchor = getAnchor(slide);
34632
34633            var text = String(sectionAnchor);
34634
34635            if(slide.length){
34636                text = text + '-' + slideAnchor;
34637            }
34638
34639            //changing slash for dash to make it a valid CSS style
34640            text = text.replace('/', '-').replace('#','');
34641
34642            //removing previous anchor classes
34643            var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g");
34644            $body[0].className = $body[0].className.replace(classRe, '');
34645
34646            //adding the current anchor
34647            $body.addClass(VIEWING_PREFIX + '-' + text);
34648        }
34649
34650        /**
34651        * Checks for translate3d support
34652        * @return boolean
34653        * http://stackoverflow.com/questions/5661671/detecting-transform-translate3d-support
34654        */
34655        function support3d() {
34656            var el = document.createElement('p'),
34657                has3d,
34658                transforms = {
34659                    'webkitTransform':'-webkit-transform',
34660                    'OTransform':'-o-transform',
34661                    'msTransform':'-ms-transform',
34662                    'MozTransform':'-moz-transform',
34663                    'transform':'transform'
34664                };
34665
34666            // Add it to the body to get the computed style.
34667            document.body.insertBefore(el, null);
34668
34669            for (var t in transforms) {
34670                if (el.style[t] !== undefined) {
34671                    el.style[t] = 'translate3d(1px,1px,1px)';
34672                    has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
34673                }
34674            }
34675
34676            document.body.removeChild(el);
34677
34678            return (has3d !== undefined && has3d.length > 0 && has3d !== 'none');
34679        }
34680
34681        /**
34682        * Removes the auto scrolling action fired by the mouse wheel and trackpad.
34683        * After this function is called, the mousewheel and trackpad movements won't scroll through sections.
34684        */
34685        function removeMouseWheelHandler(){
34686            if (document.addEventListener) {
34687                document.removeEventListener('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper
34688                document.removeEventListener('wheel', MouseWheelHandler, false); //Firefox
34689                document.removeEventListener('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox
34690            } else {
34691                document.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8
34692            }
34693        }
34694
34695        /**
34696        * Adds the auto scrolling action for the mouse wheel and trackpad.
34697        * After this function is called, the mousewheel and trackpad movements will scroll through sections
34698        * https://developer.mozilla.org/en-US/docs/Web/Events/wheel
34699        */
34700        function addMouseWheelHandler(){
34701            var prefix = '';
34702            var _addEventListener;
34703
34704            if (window.addEventListener){
34705                _addEventListener = "addEventListener";
34706            }else{
34707                _addEventListener = "attachEvent";
34708                prefix = 'on';
34709            }
34710
34711             // detect available wheel event
34712            var support = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel"
34713                      document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel"
34714                      'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox
34715            var passiveEvent = g_supportsPassive ? {passive: false }
34715: false;
34716
34717
34718            if(support == 'DOMMouseScroll'){
34719                document[ _addEventListener ](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent);
34720            }
34721
34722            //handle MozMousePixelScroll in older Firefox
34723            else{
34724                document[ _addEventListener ](prefix + support, MouseWheelHandler, passiveEvent);
34725            }
34726        }
34727
34728        /**
34729        * Binding the mousemove when the mouse's middle button is pressed
34730        */
34731        function addMiddleWheelHandler(){
34732            container
34733                .on('mousedown', mouseDownHandler)
34734                .on('mouseup', mouseUpHandler);
34735        }
34736
34737        /**
34738        * Unbinding the mousemove when the mouse's middle button is released
34739        */
34740        function removeMiddleWheelHandler(){
34741            container
34742                .off('mousedown', mouseDownHandler)
34743                .off('mouseup', mouseUpHandler);
34744        }
34745
34746        /**
34747        * Adds the possibility to auto scroll through sections on touch devices.
34748        */
34749        function addTouchHandler(){
34750            if(isTouchDevice || isTouch){
34751                if(options.autoScrolling){
34752                    $body.off(events.touchmove).on(events.touchmove, preventBouncing);
34753                }
34754
34755                $(WRAPPER_SEL)
34756                    .off(events.touchstart).on(events.touchstart, touchStartHandler)
34757                    .off(events.touchmove).on(events.touchmove, touchMoveHandler);
34758            }
34759        }
34760
34761        /**
34762        * Removes the auto scrolling for touch devices.
34763        */
34764        function removeTouchHandler(){
34765            if(isTouchDevice || isTouch){
34766                $(WRAPPER_SEL)
34767                    .off(events.touchstart)
34768                    .off(events.touchmove);
34769            }
34770        }
34771
34772        /*
34773        * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11)
34774        * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx
34775        */
34776        function getMSPointer(){
34777            var pointer;
34778
34779            //IE >= 11 & rest of browsers
34780            if(window.PointerEvent){
34781                pointer = { down: 'pointerdown', move: 'pointermove'};
34782            }
34783
34784            //IE < 11
34785            else{
34786                pointer = { down: 'MSPointerDown', move: 'MSPointerMove'};
34787            }
34788
34789            return pointer;
34790        }
34791
34792        /**
34793        * Gets the pageX and pageY properties depending on the browser.
34794        * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854
34795        */
34796        function getEventsPage(e){
34797            var events = [];
34798
34799            events.y = (typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY);
34800            events.x = (typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX);
34801
34802            //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008
34803            if(isTouch && isReallyTouch(e) && options.scrollBar){
34804                events.y = e.touches[0].pageY;
34805                events.x = e.touches[0].pageX;
34806            }
34807
34808            return events;
34809        }
34810
34811        /**
34812        * Slides silently (with no animation) the active slider to the given slide.
34813        * @param noCallback {bool} true or defined -> no callbacks
34814        */
34815        function silentLandscapeScroll(activeSlide, noCallbacks){
34816            setScrollingSpeed (0, 'internal');
34817
34818            if(typeof noCallbacks !== 'undefined'){
34819                //preventing firing callbacks afterSlideLoad etc.
34820                isResizing = true;
34821            }
34822
34823            landscapeScroll(activeSlide.closest(SLIDES_WRAPPER_SEL), activeSlide);
34824
34825            if(typeof noCallbacks !== 'undefined'){
34826                isResizing = false;
34827            }
34828
34829            setScrollingSpeed(originals.scrollingSpeed, 'internal');
34830        }
34831
34832        /**
34833        * Scrolls silently (with no animation) the page to the given Y position.
34834        */
34835        function silentScroll(top){
34836            // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625
34837            // that's why we round it to 0.
34838            var roundedTop = Math.round(top);
34839
34840            if (options.css3 && options.autoScrolling && !options.scrollBar){
34841                var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)';
34842                transformContainer(translate3d, false);
34843            }
34844            else if(options.autoScrolling && !options.scrollBar){
34845                container.css('top', -roundedTop);
34846            }
34847            else{
34848                $htmlBody.scrollTop(roundedTop);
34849            }
34850        }
34851
34852        /**
34853        * Returns the cross-browser transform string.
34854        */
34855        function getTransforms(translate3d){
34856            return {
34857                '-webkit-transform': translate3d,
34858                '-moz-transform': translate3d,
34859                '-ms-transform':translate3d,
34860                'transform': translate3d
34861            };
34862        }
34863
34864        /**
34865        * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard)
34866        * @type  m (mouse) or k (keyboard)
34867        */
34868        function setIsScrollAllowed(value, direction, type){
34869            switch (direction){
34870                case 'up': isScrollAllowed[type].up = value; break;
34871                case 'down': isScrollAllowed[type].down = value; break;
34872                case 'left': isScrollAllowed[type].left = value; break;
34873                case 'right': isScrollAllowed[type].right = value; break;
34874                case 'all':
34875                    if(type == 'm'){
34876                        setAllowScrolling(value);
34877                    }else{
34878                        setKeyboardScrolling(value);
34879                    }
34880            }
34881        }
34882
34883        /*
34884        * Destroys fullpage.js plugin events and optinally its html markup and styles
34885        */
34886        function destroy(all){
34887            setAutoScrolling(false, 'internal');
34888            setAllowScrolling(false);
34889            setKeyboardScrolling(false);
34890            container.addClass(DESTROYED);
34891
34892            clearTimeout(afterSlideLoadsId);
34893            clearTimeout(afterSectionLoadsId);
34894            clearTimeout(resizeId);
34895            clearTimeout(scrollId);
34896            clearTimeout(scrollId2);
34897
34898            $window
34899                .off('scroll', scrollHandler)
34900                .off('hashchange', hashChangeHandler)
34901                .off('resize', resizeHandler);
34902
34903            $document
34904                .off('click touchstart', SECTION_NAV_SEL + ' a')
34905                .off('mouseenter', SECTION_NAV_SEL + ' li')
34906                .off('mouseleave', SECTION_NAV_SEL + ' li')
34907                .off('click touchstart', SLIDES_NAV_LINK_SEL)
34908                .off('mouseover', options.normalScrollElements)
34909                .off('mouseout', options.normalScrollElements);
34910
34911            $(SECTION_SEL)
34912                .off('click touchstart', SLIDES_ARROW_SEL);
34913
34914            clearTimeout(afterSlideLoadsId);
34915            clearTimeout(afterSectionLoadsId);
34916
34917            //lets make a mess!
34918            if(all){
34919                destroyStructure();
34920            }
34921        }
34922
34923        /*
34924        * Removes inline styles added by fullpage.js
34925        */
34926        function destroyStructure(){
34927            //reseting the `top` or `translate` properties to 0
34928            silentScroll(0);
34929
34930            //loading all the lazy load content
34931            container.find('img[data-src], source[data-src], audio[data-src], iframe[data-src]').each(function(){
34932                setSrc($(this), 'src');
34933            });
34934
34935            container.find('img[data-srcset]').each(function(){
34936                setSrc($(this), 'srcset');
34937            });
34938
34939            $(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL +  ', ' + SLIDES_ARROW_SEL).remove();
34940
34941            //removing inline styles
34942            $(SECTION_SEL).css( {
34943                'height': '',
34944                'background-color' : '',
34945                'padding': ''
34946            });
34947
34948            $(SLIDE_SEL).css( {
34949                'width': ''
34950            });
34951
34952            container.css({
34953                'height': '',
34954                'position': '',
34955                '-ms-touch-action': '',
34956                'touch-action': ''
34957            });
34958
34959            $htmlBody.css({
34960                'overflow': '',
34961                'height': ''
34962            });
34963
34964            // remove .fp-enabled class
34965            $('html').removeClass(ENABLED);
34966
34967            // remove .fp-responsive class
34968            $body.removeClass(RESPONSIVE);
34969
34970            // remove all of the .fp-viewing- classes
34971            $.each($body.get(0).className.split(/\s+/), function (index, className) {
34972                if (className.indexOf(VIEWING_PREFIX) === 0) {
34973                    $body.removeClass(className);
34974                }
34975            });
34976
34977            //removing added classes
34978            $(SECTION_SEL + ', ' + SLIDE_SEL).each(function(){
34979                options.scrollOverflowHandler.remove($(this));
34980                $(this).removeClass(TABLE + ' ' + ACTIVE);
34981            });
34982
34983            removeAnimation(container);
34984
34985            //Unwrapping content
34986            container.find(TABLE_CELL_SEL + ', ' + SLIDES_CONTAINER_SEL + ', ' + SLIDES_WRAPPER_SEL).each(function(){
34987                //unwrap not being use in case there's no child element inside and its just text
34988                $(this).replaceWith(this.childNodes);
34989            });
34990
34991            //removing the applied transition from the fullpage wrapper
34992            container.css({
34993                '-webkit-transition': 'none',
34994                'transition': 'none'
34995            });
34996
34997            //scrolling the page to the top with no animation
34998            $htmlBody.scrollTop(0);
34999
35000            //removing selectors
35001            var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER];
35002            $.each(usedSelectors, function(index, value){
35003                $('.' + value).removeClass(value);
35004            });
35005        }
35006
35007        /*
35008        * Sets the state for a variable with multiple states (original, and temporal)
35009        * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`.
35010        * This function is used to keep track of both states, the original and the temporal one.
35011        * If type is not 'internal', then we assume the user is globally changing the variable.
35012        */
35013        function setVariableState(variable, value, type){
35014            options[variable] = value;
35015            if(type !== 'internal'){
35016                originals[variable] = value;
35017            }
35018        }
35019
35020        /**
35021        * Displays warnings
35022        */
35023        function displayWarnings(){
35024            var extensions = ['fadingEffect', 'continuousHorizontal', 'scrollHorizontally', 'interlockedSlides', 'resetSliders', 'responsiveSlides', 'offsetSections', 'dragAndMove', 'scrollOverflowReset', 'parallax'];
35025            //UNCODE.addition
35026            // if($('html').hasClass(ENABLED)){
35027            //     showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!');
35028            //     return;
35029            // }
35030
35031            // Disable mutually exclusive settings
35032            //UNCODE.addition
35033            // if (options.continuousVertical &&
35034            //     (options.loopTop || options.loopBottom)) {
35035            //     options.continuousVertical = false;
35036            //     showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
35037            // }
35038
35039            // if(options.scrollBar && options.scrollOverflow){
35040            //     showError('warn', 'Option `scrollBar` is mutually exclusive with `scrollOverflow`. Sections with scrollOverflow might not work well in Firefox');
35041            // }
35042
35043            // if(options.continuousVertical && (options.scrollBar || !options.autoScrolling)){
35044            //     options.continuousVertical = false;
35045            //     showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled');
35046            // }
35047
35048            //using extensions? Wrong file!
35049            $.each(extensions, function(index, extension){
35050                //is the option set to true?
35051                if(options[extension]){
35052                    showError('warn', 'fullpage.js extensions require jquery.fullpage.extensions.min.js file instead of the usual jquery.fullpage.js. Requested: '+ extension);
35053                }
35054            });
35055
35056            //anchors can not have the same value as any element ID or NAME
35057            $.each(options.anchors, function(index, name){
35058
35059                //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396)
35060                var nameAttr = $document.find('[name]').filter(function() {
35061                    return $(this).attr('name') && $(this).attr('name').toLowerCase() == name.toLowerCase();
35062                });
35063
35064                var idAttr = $document.find('[id]').filter(function() {
35065                    return $(this).attr('id') && $(this).attr('id').toLowerCase() == name.toLowerCase();
35066                });
35067
35068                if(idAttr.length || nameAttr.length ){
35069                    showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).');
35070                    idAttr.length && showError('error', '"' + name + '" is is being used by another element `id` property');
35071                    nameAttr.length && showError('error', '"' + name + '" is is being used by another element `name` property');
35072                }
35073            });
35074        }
35075
35076        /**
35077        * Shows a message in the console of the given type.
35078        */
35079        function showError(type, text){
35080            console && console[type] && console[type]('fullPage: ' + text);
35081        }
35082
35083    }; //end of $.fn.fullpage
35084
35085    if(typeof IScroll !== 'undefined'){
35086        /*
35087        * Turns iScroll `mousewheel` option off dynamically
35088        * https://github.com/cubiq/iscroll/issues/1036
35089        */
35090        IScroll.prototype.wheelOn = function () {
35091            this.wrapper.addEventListener('wheel', this);
35092            this.wrapper.addEventListener('mousewheel', this);
35093            this.wrapper.addEventListener('DOMMouseScroll', this);
35094        };
35095
35096        /*
35097        * Turns iScroll `mousewheel` option on dynamically
35098        * https://github.com/cubiq/iscroll/issues/1036
35099        */
35100        IScroll.prototype.wheelOff = function () {
35101            this.wrapper.removeEventListener('wheel', this);
35102            this.wrapper.removeEventListener('mousewheel', this);
35103            this.wrapper.removeEventListener('DOMMouseScroll', this);
35104        };
35105    }
35106
35107    /**
35108     * An object to handle overflow scrolling.
35109     * This uses jquery.slimScroll to accomplish overflow scrolling.
35110     * It is possible to pass in an alternate scrollOverflowHandler
35111     * to the fullpage.js option that implements the same functions
35112     * as this handler.
35113     *
35114     * @type {Object}
35115     */
35116    var iscrollHandler = {
35117        refreshId: null,
35118        iScrollInstances: [],
35119
35120        // Enables or disables the mouse wheel for the active section or all slides in it
35121        toggleWheel: function(value){
35122            var scrollable = $(SECTION_ACTIVE_SEL).find(SCROLLABLE_SEL);
35123            scrollable.each(function(){
35124                var iScrollInstance = $(this).data('iscrollInstance');
35125                if(typeof iScrollInstance !== 'undefined' && iScrollInstance){
35126                    if(value){
35127                        iScrollInstance.wheelOn();
35128                    }
35129                    else{
35130                        iScrollInstance.wheelOff();
35131                    }
35132                }
35133            });
35134        },
35135
35136        /**
35137        * Turns off iScroll for the destination section.
35138        * When scrolling very fast on some trackpads (and Apple laptops) the inertial scrolling would
35139        * scroll the destination section/slide before the sections animations ends.
35140        */
35141        onLeave: function(){
35142            iscrollHandler.toggleWheel(false);
35143        },
35144
35145        // Turns off iScroll for the leaving section
35146        beforeLeave: function(){
35147            iscrollHandler.onLeave()
35148        },
35149
35150        // Turns on iScroll on section load
35151        afterLoad: function(){
35152            iscrollHandler.toggleWheel(true);
35153        },
35154
35155        /**
35156         * Called when overflow scrolling is needed for a section.
35157         *
35158         * @param  {Object} element      jQuery object containing current section
35159         * @param  {Number} scrollHeight Current window height in pixels
35160         */
35161        create: function(element, scrollHeight) {
35162            var scrollable = element.find(SCROLLABLE_SEL);
35163
35164            scrollable.height(scrollHeight);
35165            scrollable.each(function() {
35166                var $this = $(this);
35167                var iScrollInstance = $this.data('iscrollInstance');
35168                if (iScrollInstance) {
35169                    $.each(iscrollHandler.iScrollInstances, function(){
35170                        $(this).destroy();
35171                    });
35172                }
35173
35174                iScrollInstance = new IScroll($this.get(0), iscrollOptions);
35175                iscrollHandler.iScrollInstances.push(iScrollInstance);
35176
35177                //off by default until the section gets active
35178                iScrollInstance.wheelOff();
35179
35180                $this.data('iscrollInstance', iScrollInstance);
35181            });
35182        },
35183
35184        /**
35185         * Return a boolean depending on whether the scrollable element is a
35186         * the end or at the start of the scrolling depending on the given type.
35187         *
35188         * @param  {String}  type       Either 'top' or 'bottom'
35189         * @param  {Object}  scrollable jQuery object for the scrollable element
35190         * @return {Boolean}
35191         */
35192        isScrolled: function(type, scrollable) {
35193            var scroller = scrollable.data('iscrollInstance');
35194
35195            //no scroller?
35196            if (!scroller) {
35197                return true;
35198            }
35199
35200            //Uncode addition
35201            var uncode_body_borders = parseFloat($('.body-borders').attr('data-border')) || 0;
35202            //End Uncode addition
35203
35204            if (type === 'top') {
35205                return scroller.y >= 0 && !scrollable.scrollTop();
35206            } else if (type === 'bottom') {
35207                //Uncode change
35208                // return (0 - scroller.y) + scrollable.scrollTop() + 1 + scrollable.innerHeight() >= scrollable[0].scrollHeight;
35209                return (0 - scroller.y) + scrollable.scrollTop() + 1 + ( uncode_body_borders * 2 ) + scrollable.innerHeight() >= scrollable[0].scrollHeight;
35210                //End Uncode change
35211            }
35212        },
35213
35214        /**
35215         * Returns the scrollable element for the given section.
35216         * If there are landscape slides, will only return a scrollable element
35217         * if it is in the active slide.
35218         *
35219         * @param  {Object}  activeSection jQuery object containing current section
35220         * @return {Boolean}
35221         */
35222        scrollable: function(activeSection){
35223            // if there are landscape slides, we check if the scrolling bar is in the current one or not
35224            if (activeSection.find(SLIDES_WRAPPER_SEL).length) {
35225                return activeSection.find(SLIDE_ACTIVE_SEL).find(SCROLLABLE_SEL);
35226            }
35227            return activeSection.find(SCROLLABLE_SEL);
35228        },
35229
35230        /**
35231         * Returns the scroll height of the wrapped content.
35232         * If this is larger than the window height minus section padding,
35233         * overflow scrolling is needed.
35234         *
35235         * @param  {Object} element jQuery object containing current section
35236         * @return {Number}
35237         */
35238        scrollHeight: function(element) {
35239            return element.find(SCROLLABLE_SEL).children().first().get(0).scrollHeight;
35240        },
35241
35242        /**
35243         * Called when overflow scrolling is no longer needed for a section.
35244         *
35245         * @param  {Object}
vendor: 5,435 bytes, lines 35245-35396
35245 element      jQuery object containing current section
35246         */
35247        remove: function(element) {
35248            var scrollable = element.find(SCROLLABLE_SEL);
35249            if (scrollable.length) {
35250                var iScrollInstance = scrollable.data('iscrollInstance');
35251                iScrollInstance.destroy();
35252
35253                scrollable.data('iscrollInstance', null);
35254            }
35255            element.find(SCROLLABLE_SEL).children().first().children().first().unwrap().unwrap();
35256        },
35257
35258        /**
35259         * Called when overflow scrolling has already been setup but the
35260         * window height has potentially changed.
35261         *
35262         * @param  {Object} element      jQuery object containing current section
35263         * @param  {Number} scrollHeight Current window height in pixels
35264         */
35265        update: function(element, scrollHeight) {
35266            //using a timeout in order to execute the refresh function only once when `update` is called multiple times in a
35267            //short period of time.
35268            //it also comes on handy because iScroll requires the use of timeout when using `refresh`.
35269            clearTimeout(iscrollHandler.refreshId);
35270            iscrollHandler.refreshId = setTimeout(function(){
35271                $.each(iscrollHandler.iScrollInstances, function(){
35272                    $(this).get(0).refresh();
35273                });
35274            }, 150);
35275
35276            //updating the wrappers height
35277            element.find(SCROLLABLE_SEL).css('height', scrollHeight + 'px').parent().css('height', scrollHeight + 'px');
35278        },
35279
35280        /**
35281         * Called to get any additional elements needed to wrap the section
35282         * content in order to facilitate overflow scrolling.
35283         *
35284         * @return {String|Object} Can be a string containing HTML,
35285         *                         a DOM element, or jQuery object.
35286         */
35287        wrapContent: function() {
35288            return '<div class="' + SCROLLABLE + '"><div class="fp-scroller"></div></div>';
35289        }
35290    };
35291});
35292
35293(function (global, factory) {
35294	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
35295	typeof define === 'function' && define.amd ? define(['exports'], factory) :
35296	(global = global || self, factory(global.window = global.window || {}));
35297  }(this, (function (exports) { 'use strict';
35298  
35299	function _defineProperties(target, props) {
35300	  for (var i = 0; i < props.length; i++) {
35301		var descriptor = props[i];
35302		descriptor.enumerable = descriptor.enumerable || false;
35303		descriptor.configurable = true;
35304		if ("value" in descriptor) descriptor.writable = true;
35305		Object.defineProperty(target, descriptor.key, descriptor);
35306	  }
35307	}
35308  
35309	function _createClass(Constructor, protoProps, staticProps) {
35310	  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
35311	  if (staticProps) _defineProperties(Constructor, staticProps);
35312	  return Constructor;
35313	}
35314  
35315	/*!
35316	 * Observer 3.12.5
35317	 * https://gsap.com
35318	 *
35319	 * @license Copyright 2008-2024, GreenSock. All rights reserved.
35320	 * Subject to the terms at https://gsap.com/standard-license or for
35321	 * Club GSAP members, the agreement issued with that membership.
35322	 * @author: Jack Doyle, [email protected]
35323	*/
35324	var gsap,
35325		_coreInitted,
35326		_clamp,
35327		_win,
35328		_doc,
35329		_docEl,
35330		_body,
35331		_isTouch,
35332		_pointerType,
35333		ScrollTrigger,
35334		_root,
35335		_normalizer,
35336		_eventTypes,
35337		_context,
35338		_getGSAP = function _getGSAP() {
35339	  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;
35340	},
35341		_startup = 1,
35342		_observers = [],
35343		_scrollers = [],
35344		_proxies = [],
35345		_getTime = Date.now,
35346		_bridge = function _bridge(name, value) {
35347	  return value;
35348	},
35349		_integrate = function _integrate() {
35350	  var core = ScrollTrigger.core,
35351		  data = core.bridge || {},
35352		  scrollers = core._scrollers,
35353		  proxies = core._proxies;
35354	  scrollers.push.apply(scrollers, _scrollers);
35355	  proxies.push.apply(proxies, _proxies);
35356	  _scrollers = scrollers;
35357	  _proxies = proxies;
35358  
35359	  _bridge = function _bridge(name, value) {
35360		return data[name](value);
35361	  };
35362	},
35363		_getProxyProp = function _getProxyProp(element, property) {
35364	  return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property];
35365	},
35366		_isViewport = function _isViewport(el) {
35367	  return !!~_root.indexOf(el);
35368	},
35369		_addListener = function _addListener(element, type, func, passive, capture) {
35370	  return element.addEventListener(type, func, {
35371		passive: passive !== false,
35372		capture: !!capture
35373	  });
35374	},
35375		_removeListener = function _removeListener(element, type, func, capture) {
35376	  return element.removeEventListener(type, func, !!capture);
35377	},
35378		_scrollLeft = "scrollLeft",
35379		_scrollTop = "scrollTop",
35380		_onScroll = function _onScroll() {
35381	  return _normalizer && _normalizer.isPressed || _scrollers.cache++;
35382	},
35383		_scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) {
35384	  var cachingFunc = function cachingFunc(value) {
35385		if (value || value === 0) {
35386		  _startup && (_win.history.scrollRestoration = "manual");
35387		  var isNormalizing = _normalizer && _normalizer.isPressed;
35388		  value = cachingFunc.v = Math.round(value) || (_normalizer && _normalizer.iOS ? 1 : 0);
35389		  f(value);
35390		  cachingFunc.cacheID = _scrollers.cache;
35391		  isNormalizing && _bridge("ss", value);
35392		} else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge("ref")) {
35393		  cachingFunc.cacheID = _scrollers.cache;
35394		  cachingFunc.v = f();
35395		}
35396  
vendor: 13,754 bytes, lines 35397-35850
35397		return cachingFunc.v + cachingFunc.offset;
35398	  };
35399  
35400	  cachingFunc.offset = 0;
35401	  return f && cachingFunc;
35402	},
35403		_horizontal = {
35404	  s: _scrollLeft,
35405	  p: "left",
35406	  p2: "Left",
35407	  os: "right",
35408	  os2: "Right",
35409	  d: "width",
35410	  d2: "Width",
35411	  a: "x",
35412	  sc: _scrollCacheFunc(function (value) {
35413		return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0;
35414	  })
35415	},
35416		_vertical = {
35417	  s: _scrollTop,
35418	  p: "top",
35419	  p2: "Top",
35420	  os: "bottom",
35421	  os2: "Bottom",
35422	  d: "height",
35423	  d2: "Height",
35424	  a: "y",
35425	  op: _horizontal,
35426	  sc: _scrollCacheFunc(function (value) {
35427		return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0;
35428	  })
35429	},
35430		_getTarget = function _getTarget(t, self) {
35431	  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);
35432	},
35433		_getScrollFunc = function _getScrollFunc(element, _ref) {
35434	  var s = _ref.s,
35435		  sc = _ref.sc;
35436	  _isViewport(element) && (element = _doc.scrollingElement || _docEl);
35437  
35438	  var i = _scrollers.indexOf(element),
35439		  offset = sc === _vertical.sc ? 1 : 2;
35440  
35441	  !~i && (i = _scrollers.push(element) - 1);
35442	  _scrollers[i + offset] || _addListener(element, "scroll", _onScroll);
35443	  var prev = _scrollers[i + offset],
35444		  func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) {
35445		return arguments.length ? element[s] = value : element[s];
35446	  })));
35447	  func.target = element;
35448	  prev || (func.smooth = gsap.getProperty(element, "scrollBehavior") === "smooth");
35449	  return func;
35450	},
35451		_getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) {
35452	  var v1 = value,
35453		  v2 = value,
35454		  t1 = _getTime(),
35455		  t2 = t1,
35456		  min = minTimeRefresh || 50,
35457		  dropToZeroTime = Math.max(500, min * 3),
35458		  update = function update(value, force) {
35459		var t = _getTime();
35460  
35461		if (force || t - t1 > min) {
35462		  v2 = v1;
35463		  v1 = value;
35464		  t2 = t1;
35465		  t1 = t;
35466		} else if (useDelta) {
35467		  v1 += value;
35468		} else {
35469		  v1 = v2 + (value - v2) / (t - t2) * (t1 - t2);
35470		}
35471	  },
35472		  reset = function reset() {
35473		v2 = v1 = useDelta ? 0 : v1;
35474		t2 = t1 = 0;
35475	  },
35476		  getVelocity = function getVelocity(latestValue) {
35477		var tOld = t2,
35478			vOld = v2,
35479			t = _getTime();
35480  
35481		(latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue);
35482		return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000;
35483	  };
35484  
35485	  return {
35486		update: update,
35487		reset: reset,
35488		getVelocity: getVelocity
35489	  };
35490	},
35491		_getEvent = function _getEvent(e, preventDefault) {
35492	  preventDefault && !e._gsapAllow && e.preventDefault();
35493	  return e.changedTouches ? e.changedTouches[0] : e;
35494	},
35495		_getAbsoluteMax = function _getAbsoluteMax(a) {
35496	  var max = Math.max.apply(Math, a),
35497		  min = Math.min.apply(Math, a);
35498	  return Math.abs(max) >= Math.abs(min) ? max : min;
35499	},
35500		_setScrollTrigger = function _setScrollTrigger() {
35501	  ScrollTrigger = gsap.core.globals().ScrollTrigger;
35502	  ScrollTrigger && ScrollTrigger.core && _integrate();
35503	},
35504		_initCore = function _initCore(core) {
35505	  gsap = core || _getGSAP();
35506  
35507	  if (!_coreInitted && gsap && typeof document !== "undefined" && document.body) {
35508		_win = window;
35509		_doc = document;
35510		_docEl = _doc.documentElement;
35511		_body = _doc.body;
35512		_root = [_win, _doc, _docEl, _body];
35513		_clamp = gsap.utils.clamp;
35514  
35515		_context = gsap.core.context || function () {};
35516  
35517		_pointerType = "onpointerenter" in _body ? "pointer" : "mouse";
35518		_isTouch = Observer.isTouch = _win.matchMedia && _win.matchMedia("(hover: none), (pointer: coarse)").matches ? 1 : "ontouchstart" in _win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0;
35519		_eventTypes = Observer.eventTypes = ("ontouchstart" in _docEl ? "touchstart,touchmove,touchcancel,touchend" : !("onpointerdown" in _docEl) ? "mousedown,mousemove,mouseup,mouseup" : "pointerdown,pointermove,pointercancel,pointerup").split(",");
35520		setTimeout(function () {
35521		  return _startup = 0;
35522		}, 500);
35523  
35524		_setScrollTrigger();
35525  
35526		_coreInitted = 1;
35527	  }
35528  
35529	  return _coreInitted;
35530	};
35531  
35532	_horizontal.op = _vertical;
35533	_scrollers.cache = 0;
35534	var Observer = function () {
35535	  function Observer(vars) {
35536		this.init(vars);
35537	  }
35538  
35539	  var _proto = Observer.prototype;
35540  
35541	  _proto.init = function init(vars) {
35542		_coreInitted || _initCore(gsap) || console.warn("Please gsap.registerPlugin(Observer)");
35543		ScrollTrigger || _setScrollTrigger();
35544		var tolerance = vars.tolerance,
35545			dragMinimum = vars.dragMinimum,
35546			type = vars.type,
35547			target = vars.target,
35548			lineHeight = vars.lineHeight,
35549			debounce = vars.debounce,
35550			preventDefault = vars.preventDefault,
35551			onStop = vars.onStop,
35552			onStopDelay = vars.onStopDelay,
35553			ignore = vars.ignore,
35554			wheelSpeed = vars.wheelSpeed,
35555			event = vars.event,
35556			onDragStart = vars.onDragStart,
35557			onDragEnd = vars.onDragEnd,
35558			onDrag = vars.onDrag,
35559			onPress = vars.onPress,
35560			onRelease = vars.onRelease,
35561			onRight = vars.onRight,
35562			onLeft = vars.onLeft,
35563			onUp = vars.onUp,
35564			onDown = vars.onDown,
35565			onChangeX = vars.onChangeX,
35566			onChangeY = vars.onChangeY,
35567			onChange = vars.onChange,
35568			onToggleX = vars.onToggleX,
35569			onToggleY = vars.onToggleY,
35570			onHover = vars.onHover,
35571			onHoverEnd = vars.onHoverEnd,
35572			onMove = vars.onMove,
35573			ignoreCheck = vars.ignoreCheck,
35574			isNormalizer = vars.isNormalizer,
35575			onGestureStart = vars.onGestureStart,
35576			onGestureEnd = vars.onGestureEnd,
35577			onWheel = vars.onWheel,
35578			onEnable = vars.onEnable,
35579			onDisable = vars.onDisable,
35580			onClick = vars.onClick,
35581			scrollSpeed = vars.scrollSpeed,
35582			capture = vars.capture,
35583			allowClicks = vars.allowClicks,
35584			lockAxis = vars.lockAxis,
35585			onLockAxis = vars.onLockAxis;
35586		this.target = target = _getTarget(target) || _docEl;
35587		this.vars = vars;
35588		ignore && (ignore = gsap.utils.toArray(ignore));
35589		tolerance = tolerance || 1e-9;
35590		dragMinimum = dragMinimum || 0;
35591		wheelSpeed = wheelSpeed || 1;
35592		scrollSpeed = scrollSpeed || 1;
35593		type = type || "wheel,touch,pointer";
35594		debounce = debounce !== false;
35595		lineHeight || (lineHeight = parseFloat(_win.getComputedStyle(_body).lineHeight) || 22);
35596  
35597		var id,
35598			onStopDelayedCall,
35599			dragged,
35600			moved,
35601			wheeled,
35602			locked,
35603			axis,
35604			self = this,
35605			prevDeltaX = 0,
35606			prevDeltaY = 0,
35607			passive = vars.passive || !preventDefault,
35608			scrollFuncX = _getScrollFunc(target, _horizontal),
35609			scrollFuncY = _getScrollFunc(target, _vertical),
35610			scrollX = scrollFuncX(),
35611			scrollY = scrollFuncY(),
35612			limitToTouch = ~type.indexOf("touch") && !~type.indexOf("pointer") && _eventTypes[0] === "pointerdown",
35613			isViewport = _isViewport(target),
35614			ownerDoc = target.ownerDocument || _doc,
35615			deltaX = [0, 0, 0],
35616			deltaY = [0, 0, 0],
35617			onClickTime = 0,
35618			clickCapture = function clickCapture() {
35619		  return onClickTime = _getTime();
35620		},
35621			_ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) {
35622		  return (self.event = e) && ignore && ~ignore.indexOf(e.target) || isPointerOrTouch && limitToTouch && e.pointerType !== "touch" || ignoreCheck && ignoreCheck(e, isPointerOrTouch);
35623		},
35624			onStopFunc = function onStopFunc() {
35625		  self._vx.reset();
35626  
35627		  self._vy.reset();
35628  
35629		  onStopDelayedCall.pause();
35630		  onStop && onStop(self);
35631		},
35632			update = function update() {
35633		  var dx = self.deltaX = _getAbsoluteMax(deltaX),
35634			  dy = self.deltaY = _getAbsoluteMax(deltaY),
35635			  changedX = Math.abs(dx) >= tolerance,
35636			  changedY = Math.abs(dy) >= tolerance;
35637  
35638		  onChange && (changedX || changedY) && onChange(self, dx, dy, deltaX, deltaY);
35639  
35640		  if (changedX) {
35641			onRight && self.deltaX > 0 && onRight(self);
35642			onLeft && self.deltaX < 0 && onLeft(self);
35643			onChangeX && onChangeX(self);
35644			onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self);
35645			prevDeltaX = self.deltaX;
35646			deltaX[0] = deltaX[1] = deltaX[2] = 0;
35647		  }
35648  
35649		  if (changedY) {
35650			onDown && self.deltaY > 0 && onDown(self);
35651			onUp && self.deltaY < 0 && onUp(self);
35652			onChangeY && onChangeY(self);
35653			onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self);
35654			prevDeltaY = self.deltaY;
35655			deltaY[0] = deltaY[1] = deltaY[2] = 0;
35656		  }
35657  
35658		  if (moved || dragged) {
35659			onMove && onMove(self);
35660  
35661			if (dragged) {
35662			  onDrag(self);
35663			  dragged = false;
35664			}
35665  
35666			moved = false;
35667		  }
35668  
35669		  locked && !(locked = false) && onLockAxis && onLockAxis(self);
35670  
35671		  if (wheeled) {
35672			onWheel(self);
35673			wheeled = false;
35674		  }
35675  
35676		  id = 0;
35677		},
35678			onDelta = function onDelta(x, y, index) {
35679		  deltaX[index] += x;
35680		  deltaY[index] += y;
35681  
35682		  self._vx.update(x);
35683  
35684		  self._vy.update(y);
35685  
35686		  debounce ? id || (id = requestAnimationFrame(update)) : update();
35687		},
35688			onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) {
35689		  if (lockAxis && !axis) {
35690			self.axis = axis = Math.abs(x) > Math.abs(y) ? "x" : "y";
35691			locked = true;
35692		  }
35693  
35694		  if (axis !== "y") {
35695			deltaX[2] += x;
35696  
35697			self._vx.update(x, true);
35698		  }
35699  
35700		  if (axis !== "x") {
35701			deltaY[2] += y;
35702  
35703			self._vy.update(y, true);
35704		  }
35705  
35706		  debounce ? id || (id = requestAnimationFrame(update)) : update();
35707		},
35708			_onDrag = function _onDrag(e) {
35709		  if (_ignoreCheck(e, 1)) {
35710			return;
35711		  }
35712  
35713		  e = _getEvent(e, preventDefault);
35714		  var x = e.clientX,
35715			  y = e.clientY,
35716			  dx = x - self.x,
35717			  dy = y - self.y,
35718			  isDragging = self.isDragging;
35719		  self.x = x;
35720		  self.y = y;
35721  
35722		  if (isDragging || Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum) {
35723			onDrag && (dragged = true);
35724			isDragging || (self.isDragging = true);
35725			onTouchOrPointerDelta(dx, dy);
35726			isDragging || onDragStart && onDragStart(self);
35727		  }
35728		},
35729			_onPress = self.onPress = function (e) {
35730		  if (_ignoreCheck(e, 1) || e && e.button) {
35731			return;
35732		  }
35733  
35734		  self.axis = axis = null;
35735		  onStopDelayedCall.pause();
35736		  self.isPressed = true;
35737		  e = _getEvent(e);
35738		  prevDeltaX = prevDeltaY = 0;
35739		  self.startX = self.x = e.clientX;
35740		  self.startY = self.y = e.clientY;
35741  
35742		  self._vx.reset();
35743  
35744		  self._vy.reset();
35745  
35746		  _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, passive, true);
35747  
35748		  self.deltaX = self.deltaY = 0;
35749		  onPress && onPress(self);
35750		},
35751			_onRelease = self.onRelease = function (e) {
35752		  if (_ignoreCheck(e, 1)) {
35753			return;
35754		  }
35755  
35756		  _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);
35757  
35758		  var isTrackingDrag = !isNaN(self.y - self.startY),
35759			  wasDragging = self.isDragging,
35760			  isDragNotClick = wasDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3),
35761			  eventData = _getEvent(e);
35762  
35763		  if (!isDragNotClick && isTrackingDrag) {
35764			self._vx.reset();
35765  
35766			self._vy.reset();
35767  
35768			if (preventDefault && allowClicks) {
35769			  gsap.delayedCall(0.08, function () {
35770				if (_getTime() - onClickTime > 300 && !e.defaultPrevented) {
35771				  if (e.target.click) {
35772					e.target.click();
35773				  } else if (ownerDoc.createEvent) {
35774					var syntheticEvent = ownerDoc.createEvent("MouseEvents");
35775					syntheticEvent.initMouseEvent("click", true, true, _win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null);
35776					e.target.dispatchEvent(syntheticEvent);
35777				  }
35778				}
35779			  });
35780			}
35781		  }
35782  
35783		  self.isDragging = self.isGesturing = self.isPressed = false;
35784		  onStop && wasDragging && !isNormalizer && onStopDelayedCall.restart(true);
35785		  onDragEnd && wasDragging && onDragEnd(self);
35786		  onRelease && onRelease(self, isDragNotClick);
35787		},
35788			_onGestureStart = function _onGestureStart(e) {
35789		  return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging);
35790		},
35791			_onGestureEnd = function _onGestureEnd() {
35792		  return (self.isGesturing = false) || onGestureEnd(self);
35793		},
35794			onScroll = function onScroll(e) {
35795		  if (_ignoreCheck(e)) {
35796			return;
35797		  }
35798  
35799		  var x = scrollFuncX(),
35800			  y = scrollFuncY();
35801		  onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1);
35802		  scrollX = x;
35803		  scrollY = y;
35804		  onStop && onStopDelayedCall.restart(true);
35805		},
35806			_onWheel = function _onWheel(e) {
35807		  if (_ignoreCheck(e)) {
35808			return;
35809		  }
35810  
35811		  e = _getEvent(e, preventDefault);
35812		  onWheel && (wheeled = true);
35813		  var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? _win.innerHeight : 1) * wheelSpeed;
35814		  onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0);
35815		  onStop && !isNormalizer && onStopDelayedCall.restart(true);
35816		},
35817			_onMove = function _onMove(e) {
35818		  if (_ignoreCheck(e)) {
35819			return;
35820		  }
35821  
35822		  var x = e.clientX,
35823			  y = e.clientY,
35824			  dx = x - self.x,
35825			  dy = y - self.y;
35826		  self.x = x;
35827		  self.y = y;
35828		  moved = true;
35829		  onStop && onStopDelayedCall.restart(true);
35830		  (dx || dy) && onTouchOrPointerDelta(dx, dy);
35831		},
35832			_onHover = function _onHover(e) {
35833		  self.event = e;
35834		  onHover(self);
35835		},
35836			_onHoverEnd = function _onHoverEnd(e) {
35837		  self.event = e;
35838		  onHoverEnd(self);
35839		},
35840			_onClick = function _onClick(e) {
35841		  return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self);
35842		};
35843  
35844		onStopDelayedCall = self._dc = gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause();
35845		self.deltaX = self.deltaY = 0;
35846		self._vx = _getVelocityProp(0, 50, true);
35847		self._vy = _getVelocityProp(0, 50, true);
35848		self.scrollX = scrollFuncX;
35849		self.scrollY = scrollFuncY;
35850		self.isDragging = self.isGesturing = self.isPressed = false;
vendor: 7,173 bytes, lines 35851-36093
35851  
35852		_context(this);
35853  
35854		self.enable = function (e) {
35855		  if (!self.isEnabled) {
35856			_addListener(isViewport ? ownerDoc : target, "scroll", _onScroll);
35857  
35858			type.indexOf("scroll") >= 0 && _addListener(isViewport ? ownerDoc : target, "scroll", onScroll, passive, capture);
35859			type.indexOf("wheel") >= 0 && _addListener(target, "wheel", _onWheel, passive, capture);
35860  
35861			if (type.indexOf("touch") >= 0 && _isTouch || type.indexOf("pointer") >= 0) {
35862			  _addListener(target, _eventTypes[0], _onPress, passive, capture);
35863  
35864			  _addListener(ownerDoc, _eventTypes[2], _onRelease);
35865  
35866			  _addListener(ownerDoc, _eventTypes[3], _onRelease);
35867  
35868			  allowClicks && _addListener(target, "click", clickCapture, true, true);
35869			  onClick && _addListener(target, "click", _onClick);
35870			  onGestureStart && _addListener(ownerDoc, "gesturestart", _onGestureStart);
35871			  onGestureEnd && _addListener(ownerDoc, "gestureend", _onGestureEnd);
35872			  onHover && _addListener(target, _pointerType + "enter", _onHover);
35873			  onHoverEnd && _addListener(target, _pointerType + "leave", _onHoverEnd);
35874			  onMove && _addListener(target, _pointerType + "move", _onMove);
35875			}
35876  
35877			self.isEnabled = true;
35878			e && e.type && _onPress(e);
35879			onEnable && onEnable(self);
35880		  }
35881  
35882		  return self;
35883		};
35884  
35885		self.disable = function () {
35886		  if (self.isEnabled) {
35887			_observers.filter(function (o) {
35888			  return o !== self && _isViewport(o.target);
35889			}).length || _removeListener(isViewport ? ownerDoc : target, "scroll", _onScroll);
35890  
35891			if (self.isPressed) {
35892			  self._vx.reset();
35893  
35894			  self._vy.reset();
35895  
35896			  _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);
35897			}
35898  
35899			_removeListener(isViewport ? ownerDoc : target, "scroll", onScroll, capture);
35900  
35901			_removeListener(target, "wheel", _onWheel, capture);
35902  
35903			_removeListener(target, _eventTypes[0], _onPress, capture);
35904  
35905			_removeListener(ownerDoc, _eventTypes[2], _onRelease);
35906  
35907			_removeListener(ownerDoc, _eventTypes[3], _onRelease);
35908  
35909			_removeListener(target, "click", clickCapture, true);
35910  
35911			_removeListener(target, "click", _onClick);
35912  
35913			_removeListener(ownerDoc, "gesturestart", _onGestureStart);
35914  
35915			_removeListener(ownerDoc, "gestureend", _onGestureEnd);
35916  
35917			_removeListener(target, _pointerType + "enter", _onHover);
35918  
35919			_removeListener(target, _pointerType + "leave", _onHoverEnd);
35920  
35921			_removeListener(target, _pointerType + "move", _onMove);
35922  
35923			self.isEnabled = self.isPressed = self.isDragging = false;
35924			onDisable && onDisable(self);
35925		  }
35926		};
35927  
35928		self.kill = self.revert = function () {
35929		  self.disable();
35930  
35931		  var i = _observers.indexOf(self);
35932  
35933		  i >= 0 && _observers.splice(i, 1);
35934		  _normalizer === self && (_normalizer = 0);
35935		};
35936  
35937		_observers.push(self);
35938  
35939		isNormalizer && _isViewport(target) && (_normalizer = self);
35940		self.enable(event);
35941	  };
35942  
35943	  _createClass(Observer, [{
35944		key: "velocityX",
35945		get: function get() {
35946		  return this._vx.getVelocity();
35947		}
35948	  }, {
35949		key: "velocityY",
35950		get: function get() {
35951		  return this._vy.getVelocity();
35952		}
35953	  }]);
35954  
35955	  return Observer;
35956	}();
35957	Observer.version = "3.12.5";
35958  
35959	Observer.create = function (vars) {
35960	  return new Observer(vars);
35961	};
35962  
35963	Observer.register = _initCore;
35964  
35965	Observer.getAll = function () {
35966	  return _observers.slice();
35967	};
35968  
35969	Observer.getById = function (id) {
35970	  return _observers.filter(function (o) {
35971		return o.vars.id === id;
35972	  })[0];
35973	};
35974  
35975	_getGSAP() && gsap.registerPlugin(Observer);
35976  
35977	/*!
35978	 * ScrollTrigger 3.12.5
35979	 * https://gsap.com
35980	 *
35981	 * @license Copyright 2008-2024, GreenSock. All rights reserved.
35982	 * Subject to the terms at https://gsap.com/standard-license or for
35983	 * Club GSAP members, the agreement issued with that membership.
35984	 * @author: Jack Doyle, [email protected]
35985	*/
35986  
35987	var gsap$1,
35988		_coreInitted$1,
35989		_win$1,
35990		_doc$1,
35991		_docEl$1,
35992		_body$1,
35993		_root$1,
35994		_resizeDelay,
35995		_toArray,
35996		_clamp$1,
35997		_time2,
35998		_syncInterval,
35999		_refreshing,
36000		_pointerIsDown,
36001		_transformProp,
36002		_i,
36003		_prevWidth,
36004		_prevHeight,
36005		_autoRefresh,
36006		_sort,
36007		_suppressOverwrites,
36008		_ignoreResize,
36009		_normalizer$1,
36010		_ignoreMobileResize,
36011		_baseScreenHeight,
36012		_baseScreenWidth,
36013		_fixIOSBug,
36014		_context$1,
36015		_scrollRestoration,
36016		_div100vh,
36017		_100vh,
36018		_isReverted,
36019		_clampingMax,
36020		_limitCallbacks,
36021		_startup$1 = 1,
36022		_getTime$1 = Date.now,
36023		_time1 = _getTime$1(),
36024		_lastScrollTime = 0,
36025		_enabled = 0,
36026		_parseClamp = function _parseClamp(value, type, self) {
36027	  var clamp = _isString(value) && (value.substr(0, 6) === "clamp(" || value.indexOf("max") > -1);
36028	  self["_" + type + "Clamp"] = clamp;
36029	  return clamp ? value.substr(6, value.length - 7) : value;
36030	},
36031		_keepClamp = function _keepClamp(value, clamp) {
36032	  return clamp && (!_isString(value) || value.substr(0, 6) !== "clamp(") ? "clamp(" + value + ")" : value;
36033	},
36034		_rafBugFix = function _rafBugFix() {
36035	  return _enabled && requestAnimationFrame(_rafBugFix);
36036	},
36037		_pointerDownHandler = function _pointerDownHandler() {
36038	  return _pointerIsDown = 1;
36039	},
36040		_pointerUpHandler = function _pointerUpHandler() {
36041	  return _pointerIsDown = 0;
36042	},
36043		_passThrough = function _passThrough(v) {
36044	  return v;
36045	},
36046		_round = function _round(value) {
36047	  return Math.round(value * 100000) / 100000 || 0;
36048	},
36049		_windowExists = function _windowExists() {
36050	  return typeof window !== "undefined";
36051	},
36052		_getGSAP$1 = function _getGSAP() {
36053	  return gsap$1 || _windowExists() && (gsap$1 = window.gsap) && gsap$1.registerPlugin && gsap$1;
36054	},
36055		_isViewport$1 = function _isViewport(e) {
36056	  return !!~_root$1.indexOf(e);
36057	},
36058		_getViewportDimension = function _getViewportDimension(dimensionProperty) {
36059	  return (dimensionProperty === "Height" ? _100vh : _win$1["inner" + dimensionProperty]) || _docEl$1["client" + dimensionProperty] || _body$1["client" + dimensionProperty];
36060	},
36061		_getBoundsFunc = function _getBoundsFunc(element) {
36062	  return _getProxyProp(element, "getBoundingClientRect") || (_isViewport$1(element) ? function () {
36063		_winOffsets.width = _win$1.innerWidth;
36064		_winOffsets.height = _100vh;
36065		return _winOffsets;
36066	  } : function () {
36067		return _getBounds(element);
36068	  });
36069	},
36070		_getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref) {
36071	  var d = _ref.d,
36072		  d2 = _ref.d2,
36073		  a = _ref.a;
36074	  return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () {
36075		return a()[d];
36076	  } : function () {
36077		return (isViewport ? _getViewportDimension(d2) : scroller["client" + d2]) || 0;
36078	  };
36079	},
36080		_getOffsetsFunc = function _getOffsetsFunc(element, isViewport) {
36081	  return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () {
36082		return _winOffsets;
36083	  };
36084	},
36085		_maxScroll = function _maxScroll(element, _ref2) {
36086	  var s = _ref2.s,
36087		  d2 = _ref2.d2,
36088		  d = _ref2.d,
36089		  a = _ref2.a;
36090	  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]);
36091	},
36092		_iterateAutoRefresh = function _iterateAutoRefresh(func, events) {
36093	  for (var i = 0; i < _autoRefresh.length; i += 3) {
vendor: 4,900 bytes, lines 36094-36275
36094		(!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]);
36095	  }
36096	},
36097		_isString = function _isString(value) {
36098	  return typeof value === "string";
36099	},
36100		_isFunction = function _isFunction(value) {
36101	  return typeof value === "function";
36102	},
36103		_isNumber = function _isNumber(value) {
36104	  return typeof value === "number";
36105	},
36106		_isObject = function _isObject(value) {
36107	  return typeof value === "object";
36108	},
36109		_endAnimation = function _endAnimation(animation, reversed, pause) {
36110	  return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause();
36111	},
36112		_callback = function _callback(self, func) {
36113	  if (self.enabled) {
36114		var result = self._ctx ? self._ctx.add(function () {
36115		  return func(self);
36116		}) : func(self);
36117		result && result.totalTime && (self.callbackAnimation = result);
36118	  }
36119	},
36120		_abs = Math.abs,
36121		_left = "left",
36122		_top = "top",
36123		_right = "right",
36124		_bottom = "bottom",
36125		_width = "width",
36126		_height = "height",
36127		_Right = "Right",
36128		_Left = "Left",
36129		_Top = "Top",
36130		_Bottom = "Bottom",
36131		_padding = "padding",
36132		_margin = "margin",
36133		_Width = "Width",
36134		_Height = "Height",
36135		_px = "px",
36136		_getComputedStyle = function _getComputedStyle(element) {
36137	  return _win$1.getComputedStyle(element);
36138	},
36139		_makePositionable = function _makePositionable(element) {
36140	  var position = _getComputedStyle(element).position;
36141  
36142	  element.style.position = position === "absolute" || position === "fixed" ? position : "relative";
36143	},
36144		_setDefaults = function _setDefaults(obj, defaults) {
36145	  for (var p in defaults) {
36146		p in obj || (obj[p] = defaults[p]);
36147	  }
36148  
36149	  return obj;
36150	},
36151		_getBounds = function _getBounds(element, withoutTransforms) {
36152	  var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap$1.to(element, {
36153		x: 0,
36154		y: 0,
36155		xPercent: 0,
36156		yPercent: 0,
36157		rotation: 0,
36158		rotationX: 0,
36159		rotationY: 0,
36160		scale: 1,
36161		skewX: 0,
36162		skewY: 0
36163	  }).progress(1),
36164		  bounds = element.getBoundingClientRect();
36165	  tween && tween.progress(0).kill();
36166	  return bounds;
36167	},
36168		_getSize = function _getSize(element, _ref3) {
36169	  var d2 = _ref3.d2;
36170	  return element["offset" + d2] || element["client" + d2] || 0;
36171	},
36172		_getLabelRatioArray = function _getLabelRatioArray(timeline) {
36173	  var a = [],
36174		  labels = timeline.labels,
36175		  duration = timeline.duration(),
36176		  p;
36177  
36178	  for (p in labels) {
36179		a.push(labels[p] / duration);
36180	  }
36181  
36182	  return a;
36183	},
36184		_getClosestLabel = function _getClosestLabel(animation) {
36185	  return function (value) {
36186		return gsap$1.utils.snap(_getLabelRatioArray(animation), value);
36187	  };
36188	},
36189		_snapDirectional = function _snapDirectional(snapIncrementOrArray) {
36190	  var snap = gsap$1.utils.snap(snapIncrementOrArray),
36191		  a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) {
36192		return a - b;
36193	  });
36194	  return a ? function (value, direction, threshold) {
36195		if (threshold === void 0) {
36196		  threshold = 1e-3;
36197		}
36198  
36199		var i;
36200  
36201		if (!direction) {
36202		  return snap(value);
36203		}
36204  
36205		if (direction > 0) {
36206		  value -= threshold;
36207  
36208		  for (i = 0; i < a.length; i++) {
36209			if (a[i] >= value) {
36210			  return a[i];
36211			}
36212		  }
36213  
36214		  return a[i - 1];
36215		} else {
36216		  i = a.length;
36217		  value += threshold;
36218  
36219		  while (i--) {
36220			if (a[i] <= value) {
36221			  return a[i];
36222			}
36223		  }
36224		}
36225  
36226		return a[0];
36227	  } : function (value, direction, threshold) {
36228		if (threshold === void 0) {
36229		  threshold = 1e-3;
36230		}
36231  
36232		var snapped = snap(value);
36233		return !direction || Math.abs(snapped - value) < threshold || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray);
36234	  };
36235	},
36236		_getLabelAtDirection = function _getLabelAtDirection(timeline) {
36237	  return function (value, st) {
36238		return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction);
36239	  };
36240	},
36241		_multiListener = function _multiListener(func, element, types, callback) {
36242	  return types.split(",").forEach(function (type) {
36243		return func(element, type, callback);
36244	  });
36245	},
36246		_addListener$1 = function _addListener(element, type, func, nonPassive, capture) {
36247	  return element.addEventListener(type, func, {
36248		passive: !nonPassive,
36249		capture: !!capture
36250	  });
36251	},
36252		_removeListener$1 = function _removeListener(element, type, func, capture) {
36253	  return element.removeEventListener(type, func, !!capture);
36254	},
36255		_wheelListener = function _wheelListener(func, el, scrollFunc) {
36256	  scrollFunc = scrollFunc && scrollFunc.wheelHandler;
36257  
36258	  if (scrollFunc) {
36259		func(el, "wheel", scrollFunc);
36260		func(el, "touchmove", scrollFunc);
36261	  }
36262	},
36263		_markerDefaults = {
36264	  startColor: "green",
36265	  endColor: "red",
36266	  indent: 0,
36267	  fontSize: "16px",
36268	  fontWeight: "normal"
36269	},
36270		_defaults = {
36271	  toggleActions: "play",
36272	  anticipatePin: 0
36273	},
36274		_keywords = {
36275	  top: 0,
vendor: 14,119 bytes, lines 36276-36716
36276	  left: 0,
36277	  center: 0.5,
36278	  bottom: 1,
36279	  right: 1
36280	},
36281		_offsetToPx = function _offsetToPx(value, size) {
36282	  if (_isString(value)) {
36283		var eqIndex = value.indexOf("="),
36284			relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0;
36285  
36286		if (~eqIndex) {
36287		  value.indexOf("%") > eqIndex && (relative *= size / 100);
36288		  value = value.substr(0, eqIndex - 1);
36289		}
36290  
36291		value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0);
36292	  }
36293  
36294	  return value;
36295	},
36296		_createMarker = function _createMarker(type, name, container, direction, _ref4, offset, matchWidthEl, containerAnimation) {
36297	  var startColor = _ref4.startColor,
36298		  endColor = _ref4.endColor,
36299		  fontSize = _ref4.fontSize,
36300		  indent = _ref4.indent,
36301		  fontWeight = _ref4.fontWeight;
36302  
36303	  var e = _doc$1.createElement("div"),
36304		  useFixedPosition = _isViewport$1(container) || _getProxyProp(container, "pinType") === "fixed",
36305		  isScroller = type.indexOf("scroller") !== -1,
36306		  parent = useFixedPosition ? _body$1 : container,
36307		  isStart = type.indexOf("start") !== -1,
36308		  color = isStart ? startColor : endColor,
36309		  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;";
36310  
36311	  css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;");
36312	  (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;");
36313	  matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;");
36314	  e._isStart = isStart;
36315	  e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : ""));
36316	  e.style.cssText = css;
36317	  e.innerText = name || name === 0 ? type + "-" + name : type;
36318	  parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e);
36319	  e._offset = e["offset" + direction.op.d2];
36320  
36321	  _positionMarker(e, 0, direction, isStart);
36322  
36323	  return e;
36324	},
36325		_positionMarker = function _positionMarker(marker, start, direction, flipped) {
36326	  var vars = {
36327		display: "block"
36328	  },
36329		  side = direction[flipped ? "os2" : "p2"],
36330		  oppositeSide = direction[flipped ? "p2" : "os2"];
36331	  marker._isFlipped = flipped;
36332	  vars[direction.a + "Percent"] = flipped ? -100 : 0;
36333	  vars[direction.a] = flipped ? "1px" : 0;
36334	  vars["border" + side + _Width] = 1;
36335	  vars["border" + oppositeSide + _Width] = 0;
36336	  vars[direction.p] = start + "px";
36337	  gsap$1.set(marker, vars);
36338	},
36339		_triggers = [],
36340		_ids = {},
36341		_rafID,
36342		_sync = function _sync() {
36343	  return _getTime$1() - _lastScrollTime > 34 && (_rafID || (_rafID = requestAnimationFrame(_updateAll)));
36344	},
36345		_onScroll$1 = function _onScroll() {
36346	  if (!_normalizer$1 || !_normalizer$1.isPressed || _normalizer$1.startX > _body$1.clientWidth) {
36347		_scrollers.cache++;
36348  
36349		if (_normalizer$1) {
36350		  _rafID || (_rafID = requestAnimationFrame(_updateAll));
36351		} else {
36352		  _updateAll();
36353		}
36354  
36355		_lastScrollTime || _dispatch("scrollStart");
36356		_lastScrollTime = _getTime$1();
36357	  }
36358	},
36359		_setBaseDimensions = function _setBaseDimensions() {
36360	  _baseScreenWidth = _win$1.innerWidth;
36361	  _baseScreenHeight = _win$1.innerHeight;
36362	},
36363		_onResize = function _onResize() {
36364	  _scrollers.cache++;
36365	  !_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);
36366	},
36367		_listeners = {},
36368		_emptyArray = [],
36369		_softRefresh = function _softRefresh() {
36370	  return _removeListener$1(ScrollTrigger$1, "scrollEnd", _softRefresh) || _refreshAll(true);
36371	},
36372		_dispatch = function _dispatch(type) {
36373	  return _listeners[type] && _listeners[type].map(function (f) {
36374		return f();
36375	  }) || _emptyArray;
36376	},
36377		_savedStyles = [],
36378		_revertRecorded = function _revertRecorded(media) {
36379	  for (var i = 0; i < _savedStyles.length; i += 5) {
36380		if (!media || _savedStyles[i + 4] && _savedStyles[i + 4].query === media) {
36381		  _savedStyles[i].style.cssText = _savedStyles[i + 1];
36382		  _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || "");
36383		  _savedStyles[i + 3].uncache = 1;
36384		}
36385	  }
36386	},
36387		_revertAll = function _revertAll(kill, media) {
36388	  var trigger;
36389  
36390	  for (_i = 0; _i < _triggers.length; _i++) {
36391		trigger = _triggers[_i];
36392  
36393		if (trigger && (!media || trigger._ctx === media)) {
36394		  if (kill) {
36395			trigger.kill(1);
36396		  } else {
36397			trigger.revert(true, true);
36398		  }
36399		}
36400	  }
36401  
36402	  _isReverted = true;
36403	  media && _revertRecorded(media);
36404	  media || _dispatch("revert");
36405	},
36406		_clearScrollMemory = function _clearScrollMemory(scrollRestoration, force) {
36407	  _scrollers.cache++;
36408	  (force || !_refreshingAll) && _scrollers.forEach(function (obj) {
36409		return _isFunction(obj) && obj.cacheID++ && (obj.rec = 0);
36410	  });
36411	  _isString(scrollRestoration) && (_win$1.history.scrollRestoration = _scrollRestoration = scrollRestoration);
36412	},
36413		_refreshingAll,
36414		_refreshID = 0,
36415		_queueRefreshID,
36416		_queueRefreshAll = function _queueRefreshAll() {
36417	  if (_queueRefreshID !== _refreshID) {
36418		var id = _queueRefreshID = _refreshID;
36419		requestAnimationFrame(function () {
36420		  return id === _refreshID && _refreshAll(true);
36421		});
36422	  }
36423	},
36424		_refresh100vh = function _refresh100vh() {
36425	  _body$1.appendChild(_div100vh);
36426  
36427	  _100vh = !_normalizer$1 && _div100vh.offsetHeight || _win$1.innerHeight;
36428  
36429	  _body$1.removeChild(_div100vh);
36430	},
36431		_hideAllMarkers = function _hideAllMarkers(hide) {
36432	  return _toArray(".gsap-marker-start, .gsap-marker-end, .gsap-marker-scroller-start, .gsap-marker-scroller-end").forEach(function (el) {
36433		return el.style.display = hide ? "none" : "block";
36434	  });
36435	},
36436		_refreshAll = function _refreshAll(force, skipRevert) {
36437	  if (_lastScrollTime && !force && !_isReverted) {
36438		_addListener$1(ScrollTrigger$1, "scrollEnd", _softRefresh);
36439  
36440		return;
36441	  }
36442  
36443	  _refresh100vh();
36444  
36445	  _refreshingAll = ScrollTrigger$1.isRefreshing = true;
36446  
36447	  _scrollers.forEach(function (obj) {
36448		return _isFunction(obj) && ++obj.cacheID && (obj.rec = obj());
36449	  });
36450  
36451	  var refreshInits = _dispatch("refreshInit");
36452  
36453	  _sort && ScrollTrigger$1.sort();
36454	  skipRevert || _revertAll();
36455  
36456	  _scrollers.forEach(function (obj) {
36457		if (_isFunction(obj)) {
36458		  obj.smooth && (obj.target.style.scrollBehavior = "auto");
36459		  obj(0);
36460		}
36461	  });
36462  
36463	  _triggers.slice(0).forEach(function (t) {
36464		return t.refresh();
36465	  });
36466  
36467	  _isReverted = false;
36468  
36469	  _triggers.forEach(function (t) {
36470		if (t._subPinOffset && t.pin) {
36471		  var prop = t.vars.horizontal ? "offsetWidth" : "offsetHeight",
36472			  original = t.pin[prop];
36473		  t.revert(true, 1);
36474		  t.adjustPinSpacing(t.pin[prop] - original);
36475		  t.refresh();
36476		}
36477	  });
36478  
36479	  _clampingMax = 1;
36480  
36481	  _hideAllMarkers(true);
36482  
36483	  _triggers.forEach(function (t) {
36484		var max = _maxScroll(t.scroller, t._dir),
36485			endClamp = t.vars.end === "max" || t._endClamp && t.end > max,
36486			startClamp = t._startClamp && t.start >= max;
36487  
36488		(endClamp || startClamp) && t.setPositions(startClamp ? max - 1 : t.start, endClamp ? Math.max(startClamp ? max : t.start + 1, max) : t.end, true);
36489	  });
36490  
36491	  _hideAllMarkers(false);
36492  
36493	  _clampingMax = 0;
36494	  refreshInits.forEach(function (result) {
36495		return result && result.render && result.render(-1);
36496	  });
36497  
36498	  _scrollers.forEach(function (obj) {
36499		if (_isFunction(obj)) {
36500		  obj.smooth && requestAnimationFrame(function () {
36501			return obj.target.style.scrollBehavior = "smooth";
36502		  });
36503		  obj.rec && obj(obj.rec);
36504		}
36505	  });
36506  
36507	  _clearScrollMemory(_scrollRestoration, 1);
36508  
36509	  _resizeDelay.pause();
36510  
36511	  _refreshID++;
36512	  _refreshingAll = 2;
36513  
36514	  _updateAll(2);
36515  
36516	  _triggers.forEach(function (t) {
36517		return _isFunction(t.vars.onRefresh) && t.vars.onRefresh(t);
36518	  });
36519  
36520	  _refreshingAll = ScrollTrigger$1.isRefreshing = false;
36521  
36522	  _dispatch("refresh");
36523	},
36524		_lastScroll = 0,
36525		_direction = 1,
36526		_primary,
36527		_updateAll = function _updateAll(force) {
36528	  if (force === 2 || !_refreshingAll && !_isReverted) {
36529		ScrollTrigger$1.isUpdating = true;
36530		_primary && _primary.update(0);
36531  
36532		var l = _triggers.length,
36533			time = _getTime$1(),
36534			recordVelocity = time - _time1 >= 50,
36535			scroll = l && _triggers[0].scroll();
36536  
36537		_direction = _lastScroll > scroll ? -1 : 1;
36538		_refreshingAll || (_lastScroll = scroll);
36539  
36540		if (recordVelocity) {
36541		  if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) {
36542			_lastScrollTime = 0;
36543  
36544			_dispatch("scrollEnd");
36545		  }
36546  
36547		  _time2 = _time1;
36548		  _time1 = time;
36549		}
36550  
36551		if (_direction < 0) {
36552		  _i = l;
36553  
36554		  while (_i-- > 0) {
36555			_triggers[_i] && _triggers[_i].update(0, recordVelocity);
36556		  }
36557  
36558		  _direction = 1;
36559		} else {
36560		  for (_i = 0; _i < l; _i++) {
36561			_triggers[_i] && _triggers[_i].update(0, recordVelocity);
36562		  }
36563		}
36564  
36565		ScrollTrigger$1.isUpdating = false;
36566	  }
36567  
36568	  _rafID = 0;
36569	},
36570		_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"],
36571		_stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]),
36572		_swapPinOut = function _swapPinOut(pin, spacer, state) {
36573	  _setState(state);
36574  
36575	  var cache = pin._gsap;
36576  
36577	  if (cache.spacerIsNative) {
36578		_setState(cache.spacerState);
36579	  } else if (pin._gsap.swappedIn) {
36580		var parent = spacer.parentNode;
36581  
36582		if (parent) {
36583		  parent.insertBefore(pin, spacer);
36584		  parent.removeChild(spacer);
36585		}
36586	  }
36587  
36588	  pin._gsap.swappedIn = false;
36589	},
36590		_swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) {
36591	  if (!pin._gsap.swappedIn) {
36592		var i = _propNamesToCopy.length,
36593			spacerStyle = spacer.style,
36594			pinStyle = pin.style,
36595			p;
36596  
36597		while (i--) {
36598		  p = _propNamesToCopy[i];
36599		  spacerStyle[p] = cs[p];
36600		}
36601  
36602		spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative";
36603		cs.display === "inline" && (spacerStyle.display = "inline-block");
36604		pinStyle[_bottom] = pinStyle[_right] = "auto";
36605		spacerStyle.flexBasis = cs.flexBasis || "auto";
36606		spacerStyle.overflow = "visible";
36607		spacerStyle.boxSizing = "border-box";
36608		spacerStyle[_width] = _getSize(pin, _horizontal) + _px;
36609		spacerStyle[_height] = _getSize(pin, _vertical) + _px;
36610		spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0";
36611  
36612		_setState(spacerState);
36613  
36614		pinStyle[_width] = pinStyle["max" + _Width] = cs[_width];
36615		pinStyle[_height] = pinStyle["max" + _Height] = cs[_height];
36616		pinStyle[_padding] = cs[_padding];
36617  
36618		if (pin.parentNode !== spacer) {
36619		  pin.parentNode.insertBefore(spacer, pin);
36620		  spacer.appendChild(pin);
36621		}
36622  
36623		pin._gsap.swappedIn = true;
36624	  }
36625	},
36626		_capsExp = /([A-Z])/g,
36627		_setState = function _setState(state) {
36628	  if (state) {
36629		var style = state.t.style,
36630			l = state.length,
36631			i = 0,
36632			p,
36633			value;
36634		(state.t._gsap || gsap$1.core.getCache(state.t)).uncache = 1;
36635  
36636		for (; i < l; i += 2) {
36637		  value = state[i + 1];
36638		  p = state[i];
36639  
36640		  if (value) {
36641			style[p] = value;
36642		  } else if (style[p]) {
36643			style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());
36644		  }
36645		}
36646	  }
36647	},
36648		_getState = function _getState(element) {
36649	  var l = _stateProps.length,
36650		  style = element.style,
36651		  state = [],
36652		  i = 0;
36653  
36654	  for (; i < l; i++) {
36655		state.push(_stateProps[i], style[_stateProps[i]]);
36656	  }
36657  
36658	  state.t = element;
36659	  return state;
36660	},
36661		_copyState = function _copyState(state, override, omitOffsets) {
36662	  var result = [],
36663		  l = state.length,
36664		  i = omitOffsets ? 8 : 0,
36665		  p;
36666  
36667	  for (; i < l; i += 2) {
36668		p = state[i];
36669		result.push(p, p in override ? override[p] : state[i + 1]);
36670	  }
36671  
36672	  result.t = state.t;
36673	  return result;
36674	},
36675		_winOffsets = {
36676	  left: 0,
36677	  top: 0
36678	},
36679		_parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation, clampZeroProp) {
36680	  _isFunction(value) && (value = value(self));
36681  
36682	  if (_isString(value) && value.substr(0, 3) === "max") {
36683		value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0);
36684	  }
36685  
36686	  var time = containerAnimation ? containerAnimation.time() : 0,
36687		  p1,
36688		  p2,
36689		  element;
36690	  containerAnimation && containerAnimation.seek(0);
36691	  isNaN(value) || (value = +value);
36692  
36693	  if (!_isNumber(value)) {
36694		_isFunction(trigger) && (trigger = trigger(self));
36695		var offsets = (value || "0").split(" "),
36696			bounds,
36697			localOffset,
36698			globalOffset,
36699			display;
36700		element = _getTarget(trigger, self) || _body$1;
36701		bounds = _getBounds(element) || {};
36702  
36703		if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") {
36704		  display = element.style.display;
36705		  element.style.display = "block";
36706		  bounds = _getBounds(element);
36707		  display ? element.style.display = display : element.style.removeProperty("display");
36708		}
36709  
36710		localOffset = _offsetToPx(offsets[0], bounds[direction.d]);
36711		globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize);
36712		value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset;
36713		markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20);
36714		scrollerSize -= scrollerSize - globalOffset;
36715	  } else {
36716		containerAnimation && (value = gsap$1.utils.mapRange(containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, 0, scrollerMa
vendor: 4,541 bytes, lines 36716-36872
36716x, value));
36717		markerScroller && _positionMarker(markerScroller, scrollerSize, direction, true);
36718	  }
36719  
36720	  if (clampZeroProp) {
36721		self[clampZeroProp] = value || -0.001;
36722		value < 0 && (value = 0);
36723	  }
36724  
36725	  if (marker) {
36726		var position = value + scrollerSize,
36727			isStart = marker._isStart;
36728		p1 = "scroll" + direction.d2;
36729  
36730		_positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body$1[p1], _docEl$1[p1]) : marker.parentNode[p1]) <= position + 1);
36731  
36732		if (useFixedPosition) {
36733		  scrollerBounds = _getBounds(markerScroller);
36734		  useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px);
36735		}
36736	  }
36737  
36738	  if (containerAnimation && element) {
36739		p1 = _getBounds(element);
36740		containerAnimation.seek(scrollerMax);
36741		p2 = _getBounds(element);
36742		containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p];
36743		value = value / containerAnimation._caScrollDist * scrollerMax;
36744	  }
36745  
36746	  containerAnimation && containerAnimation.seek(time);
36747	  return containerAnimation ? value : Math.round(value);
36748	},
36749		_prefixExp = /(webkit|moz|length|cssText|inset)/i,
36750		_reparent = function _reparent(element, parent, top, left) {
36751	  if (element.parentNode !== parent) {
36752		var style = element.style,
36753			p,
36754			cs;
36755  
36756		if (parent === _body$1) {
36757		  element._stOrig = style.cssText;
36758		  cs = _getComputedStyle(element);
36759  
36760		  for (p in cs) {
36761			if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") {
36762			  style[p] = cs[p];
36763			}
36764		  }
36765  
36766		  style.top = top;
36767		  style.left = left;
36768		} else {
36769		  style.cssText = element._stOrig;
36770		}
36771  
36772		gsap$1.core.getCache(element).uncache = 1;
36773		parent.appendChild(element);
36774	  }
36775	},
36776		_interruptionTracker = function _interruptionTracker(getValueFunc, initialValue, onInterrupt) {
36777	  var last1 = initialValue,
36778		  last2 = last1;
36779	  return function (value) {
36780		var current = Math.round(getValueFunc());
36781  
36782		if (current !== last1 && current !== last2 && Math.abs(current - last1) > 3 && Math.abs(current - last2) > 3) {
36783		  value = current;
36784		  onInterrupt && onInterrupt();
36785		}
36786  
36787		last2 = last1;
36788		last1 = value;
36789		return value;
36790	  };
36791	},
36792		_shiftMarker = function _shiftMarker(marker, direction, value) {
36793	  var vars = {};
36794	  vars[direction.p] = "+=" + value;
36795	  gsap$1.set(marker, vars);
36796	},
36797		_getTweenCreator = function _getTweenCreator(scroller, direction) {
36798	  var getScroll = _getScrollFunc(scroller, direction),
36799		  prop = "_scroll" + direction.p2,
36800		  getTween = function getTween(scrollTo, vars, initialValue, change1, change2) {
36801		var tween = getTween.tween,
36802			onComplete = vars.onComplete,
36803			modifiers = {};
36804		initialValue = initialValue || getScroll();
36805  
36806		var checkForInterruption = _interruptionTracker(getScroll, initialValue, function () {
36807		  tween.kill();
36808		  getTween.tween = 0;
36809		});
36810  
36811		change2 = change1 && change2 || 0;
36812		change1 = change1 || scrollTo - initialValue;
36813		tween && tween.kill();
36814		vars[prop] = scrollTo;
36815		vars.inherit = false;
36816		vars.modifiers = modifiers;
36817  
36818		modifiers[prop] = function () {
36819		  return checkForInterruption(initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio);
36820		};
36821  
36822		vars.onUpdate = function () {
36823		  _scrollers.cache++;
36824		  getTween.tween && _updateAll();
36825		};
36826  
36827		vars.onComplete = function () {
36828		  getTween.tween = 0;
36829		  onComplete && onComplete.call(tween);
36830		};
36831  
36832		tween = getTween.tween = gsap$1.to(scroller, vars);
36833		return tween;
36834	  };
36835  
36836	  scroller[prop] = getScroll;
36837  
36838	  getScroll.wheelHandler = function () {
36839		return getTween.tween && getTween.tween.kill() && (getTween.tween = 0);
36840	  };
36841  
36842	  _addListener$1(scroller, "wheel", getScroll.wheelHandler);
36843  
36844	  ScrollTrigger$1.isTouch && _addListener$1(scroller, "touchmove", getScroll.wheelHandler);
36845	  return getTween;
36846	};
36847  
36848	var ScrollTrigger$1 = function () {
36849	  function ScrollTrigger(vars, animation) {
36850		_coreInitted$1 || ScrollTrigger.register(gsap$1) || console.warn("Please gsap.registerPlugin(ScrollTrigger)");
36851  
36852		_context$1(this);
36853  
36854		this.init(vars, animation);
36855	  }
36856  
36857	  var _proto = ScrollTrigger.prototype;
36858  
36859	  _proto.init = function init(vars, animation) {
36860		this.progress = this.start = 0;
36861		this.vars && this.kill(true, true);
36862  
36863		if (!_enabled) {
36864		  this.update = this.refresh = this.kill = _passThrough;
36865		  return;
36866		}
36867  
36868		vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? {
36869		  trigger: vars
36870		} : vars, _defaults);
36871  
36872		var _vars = vars,
vendor: 4,184 bytes, lines 36873-37013
36873			onUpdate = _vars.onUpdate,
36874			toggleClass = _vars.toggleClass,
36875			id = _vars.id,
36876			onToggle = _vars.onToggle,
36877			onRefresh = _vars.onRefresh,
36878			scrub = _vars.scrub,
36879			trigger = _vars.trigger,
36880			pin = _vars.pin,
36881			pinSpacing = _vars.pinSpacing,
36882			invalidateOnRefresh = _vars.invalidateOnRefresh,
36883			anticipatePin = _vars.anticipatePin,
36884			onScrubComplete = _vars.onScrubComplete,
36885			onSnapComplete = _vars.onSnapComplete,
36886			once = _vars.once,
36887			snap = _vars.snap,
36888			pinReparent = _vars.pinReparent,
36889			pinSpacer = _vars.pinSpacer,
36890			containerAnimation = _vars.containerAnimation,
36891			fastScrollEnd = _vars.fastScrollEnd,
36892			preventOverlaps = _vars.preventOverlaps,
36893			direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _horizontal : _vertical,
36894			isToggle = !scrub && scrub !== 0,
36895			scroller = _getTarget(vars.scroller || _win$1),
36896			scrollerCache = gsap$1.core.getCache(scroller),
36897			isViewport = _isViewport$1(scroller),
36898			useFixedPosition = ("pinType" in vars ? vars.pinType : _getProxyProp(scroller, "pinType") || isViewport && "fixed") === "fixed",
36899			callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack],
36900			toggleActions = isToggle && vars.toggleActions.split(" "),
36901			markers = "markers" in vars ? vars.markers : _defaults.markers,
36902			borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0,
36903			self = this,
36904			onRefreshInit = vars.onRefreshInit && function () {
36905		  return vars.onRefreshInit(self);
36906		},
36907			getScrollerSize = _getSizeFunc(scroller, isViewport, direction),
36908			getScrollerOffsets = _getOffsetsFunc(scroller, isViewport),
36909			lastSnap = 0,
36910			lastRefresh = 0,
36911			prevProgress = 0,
36912			scrollFunc = _getScrollFunc(scroller, direction),
36913			tweenTo,
36914			pinCache,
36915			snapFunc,
36916			scroll1,
36917			scroll2,
36918			start,
36919			end,
36920			markerStart,
36921			markerEnd,
36922			markerStartTrigger,
36923			markerEndTrigger,
36924			markerVars,
36925			executingOnRefresh,
36926			change,
36927			pinOriginalState,
36928			pinActiveState,
36929			pinState,
36930			spacer,
36931			offset,
36932			pinGetter,
36933			pinSetter,
36934			pinStart,
36935			pinChange,
36936			spacingStart,
36937			spacerState,
36938			markerStartSetter,
36939			pinMoves,
36940			markerEndSetter,
36941			cs,
36942			snap1,
36943			snap2,
36944			scrubTween,
36945			scrubSmooth,
36946			snapDurClamp,
36947			snapDelayedCall,
36948			prevScroll,
36949			prevAnimProgress,
36950			caMarkerSetter,
36951			customRevertReturn;
36952  
36953		self._startClamp = self._endClamp = false;
36954		self._dir = direction;
36955		anticipatePin *= 45;
36956		self.scroller = scroller;
36957		self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc;
36958		scroll1 = scrollFunc();
36959		self.vars = vars;
36960		animation = animation || vars.animation;
36961  
36962		if ("refreshPriority" in vars) {
36963		  _sort = 1;
36964		  vars.refreshPriority === -9999 && (_primary = self);
36965		}
36966  
36967		scrollerCache.tweenScroll = scrollerCache.tweenScroll || {
36968		  top: _getTweenCreator(scroller, _vertical),
36969		  left: _getTweenCreator(scroller, _horizontal)
36970		};
36971		self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p];
36972  
36973		self.scrubDuration = function (value) {
36974		  scrubSmooth = _isNumber(value) && value;
36975  
36976		  if (!scrubSmooth) {
36977			scrubTween && scrubTween.progress(1).kill();
36978			scrubTween = 0;
36979		  } else {
36980			scrubTween ? scrubTween.duration(value) : scrubTween = gsap$1.to(animation, {
36981			  ease: "expo",
36982			  totalProgress: "+=0",
36983			  inherit: false,
36984			  duration: scrubSmooth,
36985			  paused: true,
36986			  onComplete: function onComplete() {
36987				return onScrubComplete && onScrubComplete(self);
36988			  }
36989			});
36990		  }
36991		};
36992  
36993		if (animation) {
36994		  animation.vars.lazy = false;
36995		  animation._initted && !self.isReverted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.duration() && animation.render(0, true, true);
36996		  self.animation = animation.pause();
36997		  animation.scrollTrigger = self;
36998		  self.scrubDuration(scrub);
36999		  snap1 = 0;
37000		  id || (id = animation.vars.id);
37001		}
37002  
37003		if (snap) {
37004		  if (!_isObject(snap) || snap.push) {
37005			snap = {
37006			  snapTo: snap
37007			};
37008		  }
37009  
37010		  "scrollBehavior" in _body$1.style && gsap$1.set(isViewport ? [_body$1, _docEl$1] : scroller, {
37011			scrollBehavior: "auto"
37012		  });
37013  
vendor: 4,259 bytes, lines 37014-37109
37014		  _scrollers.forEach(function (o) {
37015			return _isFunction(o) && o.target === (isViewport ? _doc$1.scrollingElement || _docEl$1 : scroller) && (o.smooth = false);
37016		  });
37017  
37018		  snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) {
37019			return _snapDirectional(snap.snapTo)(value, _getTime$1() - lastRefresh < 500 ? 0 : st.direction);
37020		  } : gsap$1.utils.snap(snap.snapTo);
37021		  snapDurClamp = snap.duration || {
37022			min: 0.1,
37023			max: 2
37024		  };
37025		  snapDurClamp = _isObject(snapDurClamp) ? _clamp$1(snapDurClamp.min, snapDurClamp.max) : _clamp$1(snapDurClamp, snapDurClamp);
37026		  snapDelayedCall = gsap$1.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () {
37027			var scroll = scrollFunc(),
37028				refreshedRecently = _getTime$1() - lastRefresh < 500,
37029				tween = tweenTo.tween;
37030  
37031			if ((refreshedRecently || Math.abs(self.getVelocity()) < 10) && !tween && !_pointerIsDown && lastSnap !== scroll) {
37032			  var progress = (scroll - start) / change,
37033				  totalProgress = animation && !isToggle ? animation.totalProgress() : progress,
37034				  velocity = refreshedRecently ? 0 : (totalProgress - snap2) / (_getTime$1() - _time2) * 1000 || 0,
37035				  change1 = gsap$1.utils.clamp(-progress, 1 - progress, _abs(velocity / 2) * velocity / 0.185),
37036				  naturalEnd = progress + (snap.inertia === false ? 0 : change1),
37037				  endValue,
37038				  endScroll,
37039				  _snap = snap,
37040				  onStart = _snap.onStart,
37041				  _onInterrupt = _snap.onInterrupt,
37042				  _onComplete = _snap.onComplete;
37043			  endValue = snapFunc(naturalEnd, self);
37044			  _isNumber(endValue) || (endValue = naturalEnd);
37045			  endScroll = Math.round(start + endValue * change);
37046  
37047			  if (scroll <= end && scroll >= start && endScroll !== scroll) {
37048				if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) {
37049				  return;
37050				}
37051  
37052				if (snap.inertia === false) {
37053				  change1 = endValue - progress;
37054				}
37055  
37056				tweenTo(endScroll, {
37057				  duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)),
37058				  ease: snap.ease || "power3",
37059				  data: _abs(endScroll - scroll),
37060				  onInterrupt: function onInterrupt() {
37061					return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self);
37062				  },
37063				  onComplete: function onComplete() {
37064					self.update();
37065					lastSnap = scrollFunc();
37066  
37067					if (animation) {
37068					  scrubTween ? scrubTween.resetTo("totalProgress", endValue, animation._tTime / animation._tDur) : animation.progress(endValue);
37069					}
37070  
37071					snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress;
37072					onSnapComplete && onSnapComplete(self);
37073					_onComplete && _onComplete(self);
37074				  }
37075				}, scroll, change1 * change, endScroll - scroll - change1 * change);
37076				onStart && onStart(self, tweenTo.tween);
37077			  }
37078			} else if (self.isActive && lastSnap !== scroll) {
37079			  snapDelayedCall.restart(true);
37080			}
37081		  }).pause();
37082		}
37083  
37084		id && (_ids[id] = self);
37085		trigger = self.trigger = _getTarget(trigger || pin !== true && pin);
37086		customRevertReturn = trigger && trigger._gsap && trigger._gsap.stRevert;
37087		customRevertReturn && (customRevertReturn = customRevertReturn(self));
37088		pin = pin === true ? trigger : _getTarget(pin);
37089		_isString(toggleClass) && (toggleClass = {
37090		  targets: trigger,
37091		  className: toggleClass
37092		});
37093  
37094		if (pin) {
37095		  pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && pin.parentNode && pin.parentNode.style && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding);
37096		  self.pin = pin;
37097		  pinCache = gsap$1.core.getCache(pin);
37098  
37099		  if (!pinCache.spacer) {
37100			if (pinSpacer) {
37101			  pinSpacer = _getTarget(pinSpacer);
37102			  pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement);
37103			  pinCache.spacerIsNative = !!pinSpacer;
37104			  pinSpacer && (pinCache.spacerState = _getState(pinSpacer));
37105			}
37106  
37107			pinCache.spacer = spacer = pinSpacer || _doc$1.createElement("div");
37108			spacer.classList.add("pin-spacer");
37109			id && spacer.classList.add("pin-spacer-" + id);
vendor: 4,987 bytes, lines 37110-37264
37110			pinCache.pinState = pinOriginalState = _getState(pin);
37111		  } else {
37112			pinOriginalState = pinCache.pinState;
37113		  }
37114  
37115		  vars.force3D !== false && gsap$1.set(pin, {
37116			force3D: true
37117		  });
37118		  self.spacer = spacer = pinCache.spacer;
37119		  cs = _getComputedStyle(pin);
37120		  spacingStart = cs[pinSpacing + direction.os2];
37121		  pinGetter = gsap$1.getProperty(pin);
37122		  pinSetter = gsap$1.quickSetter(pin, direction.a, _px);
37123  
37124		  _swapPinIn(pin, spacer, cs);
37125  
37126		  pinState = _getState(pin);
37127		}
37128  
37129		if (markers) {
37130		  markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults;
37131		  markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0);
37132		  markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger);
37133		  offset = markerStartTrigger["offset" + direction.op.d2];
37134  
37135		  var content = _getTarget(_getProxyProp(scroller, "content") || scroller);
37136  
37137		  markerStart = this.markerStart = _createMarker("start", id, content, direction, markerVars, offset, 0, containerAnimation);
37138		  markerEnd = this.markerEnd = _createMarker("end", id, content, direction, markerVars, offset, 0, containerAnimation);
37139		  containerAnimation && (caMarkerSetter = gsap$1.quickSetter([markerStart, markerEnd], direction.a, _px));
37140  
37141		  if (!useFixedPosition && !(_proxies.length && _getProxyProp(scroller, "fixedMarkers") === true)) {
37142			_makePositionable(isViewport ? _body$1 : scroller);
37143  
37144			gsap$1.set([markerStartTrigger, markerEndTrigger], {
37145			  force3D: true
37146			});
37147			markerStartSetter = gsap$1.quickSetter(markerStartTrigger, direction.a, _px);
37148			markerEndSetter = gsap$1.quickSetter(markerEndTrigger, direction.a, _px);
37149		  }
37150		}
37151  
37152		if (containerAnimation) {
37153		  var oldOnUpdate = containerAnimation.vars.onUpdate,
37154			  oldParams = containerAnimation.vars.onUpdateParams;
37155		  containerAnimation.eventCallback("onUpdate", function () {
37156			self.update(0, 0, 1);
37157			oldOnUpdate && oldOnUpdate.apply(containerAnimation, oldParams || []);
37158		  });
37159		}
37160  
37161		self.previous = function () {
37162		  return _triggers[_triggers.indexOf(self) - 1];
37163		};
37164  
37165		self.next = function () {
37166		  return _triggers[_triggers.indexOf(self) + 1];
37167		};
37168  
37169		self.revert = function (revert, temp) {
37170		  if (!temp) {
37171			return self.kill(true);
37172		  }
37173  
37174		  var r = revert !== false || !self.enabled,
37175			  prevRefreshing = _refreshing;
37176  
37177		  if (r !== self.isReverted) {
37178			if (r) {
37179			  prevScroll = Math.max(scrollFunc(), self.scroll.rec || 0);
37180			  prevProgress = self.progress;
37181			  prevAnimProgress = animation && animation.progress();
37182			}
37183  
37184			markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {
37185			  return m.style.display = r ? "none" : "block";
37186			});
37187  
37188			if (r) {
37189			  _refreshing = self;
37190			  self.update(r);
37191			}
37192  
37193			if (pin && (!pinReparent || !self.isActive)) {
37194			  if (r) {
37195				_swapPinOut(pin, spacer, pinOriginalState);
37196			  } else {
37197				_swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState);
37198			  }
37199			}
37200  
37201			r || self.update(r);
37202			_refreshing = prevRefreshing;
37203			self.isReverted = r;
37204		  }
37205		};
37206  
37207		self.refresh = function (soft, force, position, pinOffset) {
37208		  if ((_refreshing || !self.enabled) && !force) {
37209			return;
37210		  }
37211  
37212		  if (pin && soft && _lastScrollTime) {
37213			_addListener$1(ScrollTrigger, "scrollEnd", _softRefresh);
37214  
37215			return;
37216		  }
37217  
37218		  !_refreshingAll && onRefreshInit && onRefreshInit(self);
37219		  _refreshing = self;
37220  
37221		  if (tweenTo.tween && !position) {
37222			tweenTo.tween.kill();
37223			tweenTo.tween = 0;
37224		  }
37225  
37226		  scrubTween && scrubTween.pause();
37227		  invalidateOnRefresh && animation && animation.revert({
37228			kill: false
37229		  }).invalidate();
37230		  self.isReverted || self.revert(true, true);
37231		  self._subPinOffset = false;
37232  
37233		  var size = getScrollerSize(),
37234			  scrollerBounds = getScrollerOffsets(),
37235			  max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction),
37236			  isFirstRefresh = change <= 0.01,
37237			  offset = 0,
37238			  otherPinOffset = pinOffset || 0,
37239			  parsedEnd = _isObject(position) ? position.end : vars.end,
37240			  parsedEndTrigger = vars.endTrigger || trigger,
37241			  parsedStart = _isObject(position) ? position.start : vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"),
37242			  pinnedContainer = self.pinnedContainer = vars.pinnedContainer && _getTarget(vars.pinnedContainer, self),
37243			  triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0,
37244			  i = triggerIndex,
37245			  cs,
37246			  bounds,
37247			  scroll,
37248			  isVertical,
37249			  override,
37250			  curTrigger,
37251			  curPin,
37252			  oppositeScroll,
37253			  initted,
37254			  revertedPins,
37255			  forcedOverflow,
37256			  markerStartOffset,
37257			  markerEndOffset;
37258  
37259		  if (markers && _isObject(position)) {
37260			markerStartOffset = gsap$1.getProperty(markerStartTrigger, direction.p);
37261			markerEndOffset = gsap$1.getProperty(markerEndTrigger, direction.p);
37262		  }
37263  
37264		  while (i--) {
vendor: 4,360 bytes, lines 37265-37376
37265			curTrigger = _triggers[i];
37266			curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = self);
37267			curPin = curTrigger.pin;
37268  
37269			if (curPin && (curPin === trigger || curPin === pin || curPin === pinnedContainer) && !curTrigger.isReverted) {
37270			  revertedPins || (revertedPins = []);
37271			  revertedPins.unshift(curTrigger);
37272			  curTrigger.revert(true, true);
37273			}
37274  
37275			if (curTrigger !== _triggers[i]) {
37276			  triggerIndex--;
37277			  i--;
37278			}
37279		  }
37280  
37281		  _isFunction(parsedStart) && (parsedStart = parsedStart(self));
37282		  parsedStart = _parseClamp(parsedStart, "start", self);
37283		  start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._startClamp && "_startClamp") || (pin ? -0.001 : 0);
37284		  _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self));
37285  
37286		  if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) {
37287			if (~parsedEnd.indexOf(" ")) {
37288			  parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd;
37289			} else {
37290			  offset = _offsetToPx(parsedEnd.substr(2), size);
37291			  parsedEnd = _isString(parsedStart) ? parsedStart : (containerAnimation ? gsap$1.utils.mapRange(0, containerAnimation.duration(), containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, start) : start) + offset;
37292			  parsedEndTrigger = trigger;
37293			}
37294		  }
37295  
37296		  parsedEnd = _parseClamp(parsedEnd, "end", self);
37297		  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;
37298		  offset = 0;
37299		  i = triggerIndex;
37300  
37301		  while (i--) {
37302			curTrigger = _triggers[i];
37303			curPin = curTrigger.pin;
37304  
37305			if (curPin && curTrigger.start - curTrigger._pinPush <= start && !containerAnimation && curTrigger.end > 0) {
37306			  cs = curTrigger.end - (self._startClamp ? Math.max(0, curTrigger.start) : curTrigger.start);
37307  
37308			  if ((curPin === trigger && curTrigger.start - curTrigger._pinPush < start || curPin === pinnedContainer) && isNaN(parsedStart)) {
37309				offset += cs * (1 - curTrigger.progress);
37310			  }
37311  
37312			  curPin === pin && (otherPinOffset += cs);
37313			}
37314		  }
37315  
37316		  start += offset;
37317		  end += offset;
37318		  self._startClamp && (self._startClamp += offset);
37319  
37320		  if (self._endClamp && !_refreshingAll) {
37321			self._endClamp = end || -0.001;
37322			end = Math.min(end, _maxScroll(scroller, direction));
37323		  }
37324  
37325		  change = end - start || (start -= 0.01) && 0.001;
37326  
37327		  if (isFirstRefresh) {
37328			prevProgress = gsap$1.utils.clamp(0, 1, gsap$1.utils.normalize(start, end, prevScroll));
37329		  }
37330  
37331		  self._pinPush = otherPinOffset;
37332  
37333		  if (markerStart && offset) {
37334			cs = {};
37335			cs[direction.a] = "+=" + offset;
37336			pinnedContainer && (cs[direction.p] = "-=" + scrollFunc());
37337			gsap$1.set([markerStart, markerEnd], cs);
37338		  }
37339  
37340		  if (pin && !(_clampingMax && self.end >= _maxScroll(scroller, direction))) {
37341			cs = _getComputedStyle(pin);
37342			isVertical = direction === _vertical;
37343			scroll = scrollFunc();
37344			pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset;
37345  
37346			if (!max && end > 1) {
37347			  forcedOverflow = (isViewport ? _doc$1.scrollingElement || _docEl$1 : scroller).style;
37348			  forcedOverflow = {
37349				style: forcedOverflow,
37350				value: forcedOverflow["overflow" + direction.a.toUpperCase()]
37351			  };
37352  
37353			  if (isViewport && _getComputedStyle(_body$1)["overflow" + direction.a.toUpperCase()] !== "scroll") {
37354				forcedOverflow.style["overflow" + direction.a.toUpperCase()] = "scroll";
37355			  }
37356			}
37357  
37358			_swapPinIn(pin, spacer, cs);
37359  
37360			pinState = _getState(pin);
37361			bounds = _getBounds(pin, true);
37362			oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)();
37363  
37364			if (pinSpacing) {
37365			  spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px];
37366			  spacerState.t = spacer;
37367			  i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0;
37368  
37369			  if (i) {
37370				spacerState.push(direction.d, i + _px);
37371				spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px);
37372			  }
37373  
37374			  _setState(spacerState);
37375  
37376			  if (pinnedContainer) {
vendor: 9,034 bytes, lines 37377-37619
37377				_triggers.forEach(function (t) {
37378				  if (t.pin === pinnedContainer && t.vars.pinSpacing !== false) {
37379					t._subPinOffset = true;
37380				  }
37381				});
37382			  }
37383  
37384			  useFixedPosition && scrollFunc(prevScroll);
37385			} else {
37386			  i = _getSize(pin, direction);
37387			  i && spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px);
37388			}
37389  
37390			if (useFixedPosition) {
37391			  override = {
37392				top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px,
37393				left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px,
37394				boxSizing: "border-box",
37395				position: "fixed"
37396			  };
37397			  override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px;
37398			  override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px;
37399			  override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0";
37400			  override[_padding] = cs[_padding];
37401			  override[_padding + _Top] = cs[_padding + _Top];
37402			  override[_padding + _Right] = cs[_padding + _Right];
37403			  override[_padding + _Bottom] = cs[_padding + _Bottom];
37404			  override[_padding + _Left] = cs[_padding + _Left];
37405			  pinActiveState = _copyState(pinOriginalState, override, pinReparent);
37406			  _refreshingAll && scrollFunc(0);
37407			}
37408  
37409			if (animation) {
37410			  initted = animation._initted;
37411  
37412			  _suppressOverwrites(1);
37413  
37414			  animation.render(animation.duration(), true, true);
37415			  pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset;
37416			  pinMoves = Math.abs(change - pinChange) > 1;
37417			  useFixedPosition && pinMoves && pinActiveState.splice(pinActiveState.length - 2, 2);
37418			  animation.render(0, true, true);
37419			  initted || animation.invalidate(true);
37420			  animation.parent || animation.totalTime(animation.totalTime());
37421  
37422			  _suppressOverwrites(0);
37423			} else {
37424			  pinChange = change;
37425			}
37426  
37427			forcedOverflow && (forcedOverflow.value ? forcedOverflow.style["overflow" + direction.a.toUpperCase()] = forcedOverflow.value : forcedOverflow.style.removeProperty("overflow-" + direction.a));
37428		  } else if (trigger && scrollFunc() && !containerAnimation) {
37429			bounds = trigger.parentNode;
37430  
37431			while (bounds && bounds !== _body$1) {
37432			  if (bounds._pinOffset) {
37433				start -= bounds._pinOffset;
37434				end -= bounds._pinOffset;
37435			  }
37436  
37437			  bounds = bounds.parentNode;
37438			}
37439		  }
37440  
37441		  revertedPins && revertedPins.forEach(function (t) {
37442			return t.revert(false, true);
37443		  });
37444		  self.start = start;
37445		  self.end = end;
37446		  scroll1 = scroll2 = _refreshingAll ? prevScroll : scrollFunc();
37447  
37448		  if (!containerAnimation && !_refreshingAll) {
37449			scroll1 < prevScroll && scrollFunc(prevScroll);
37450			self.scroll.rec = 0;
37451		  }
37452  
37453		  self.revert(false, true);
37454		  lastRefresh = _getTime$1();
37455  
37456		  if (snapDelayedCall) {
37457			lastSnap = -1;
37458			snapDelayedCall.restart(true);
37459		  }
37460  
37461		  _refreshing = 0;
37462		  animation && isToggle && (animation._initted || prevAnimProgress) && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress || 0, true).render(animation.time(), true, true);
37463  
37464		  if (isFirstRefresh || prevProgress !== self.progress || containerAnimation || invalidateOnRefresh) {
37465			animation && !isToggle && animation.totalProgress(containerAnimation && start < -0.001 && !prevProgress ? gsap$1.utils.normalize(start, end, 0) : prevProgress, true);
37466			self.progress = isFirstRefresh || (scroll1 - start) / change === prevProgress ? 0 : prevProgress;
37467		  }
37468  
37469		  pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange));
37470		  scrubTween && scrubTween.invalidate();
37471  
37472		  if (!isNaN(markerStartOffset)) {
37473			markerStartOffset -= gsap$1.getProperty(markerStartTrigger, direction.p);
37474			markerEndOffset -= gsap$1.getProperty(markerEndTrigger, direction.p);
37475  
37476			_shiftMarker(markerStartTrigger, direction, markerStartOffset);
37477  
37478			_shiftMarker(markerStart, direction, markerStartOffset - (pinOffset || 0));
37479  
37480			_shiftMarker(markerEndTrigger, direction, markerEndOffset);
37481  
37482			_shiftMarker(markerEnd, direction, markerEndOffset - (pinOffset || 0));
37483		  }
37484  
37485		  isFirstRefresh && !_refreshingAll && self.update();
37486  
37487		  if (onRefresh && !_refreshingAll && !executingOnRefresh) {
37488			executingOnRefresh = true;
37489			onRefresh(self);
37490			executingOnRefresh = false;
37491		  }
37492		};
37493  
37494		self.getVelocity = function () {
37495		  return (scrollFunc() - scroll2) / (_getTime$1() - _time2) * 1000 || 0;
37496		};
37497  
37498		self.endAnimation = function () {
37499		  _endAnimation(self.callbackAnimation);
37500  
37501		  if (animation) {
37502			scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1);
37503		  }
37504		};
37505  
37506		self.labelToScroll = function (label) {
37507		  return animation && animation.labels && (start || self.refresh() || start) + animation.labels[label] / animation.duration() * change || 0;
37508		};
37509  
37510		self.getTrailing = function (name) {
37511		  var i = _triggers.indexOf(self),
37512			  a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1);
37513  
37514		  return (_isString(name) ? a.filter(function (t) {
37515			return t.vars.preventOverlaps === name;
37516		  }) : a).filter(function (t) {
37517			return self.direction > 0 ? t.end <= start : t.start >= end;
37518		  });
37519		};
37520  
37521		self.update = function (reset, recordVelocity, forceFake) {
37522		  if (containerAnimation && !forceFake && !reset) {
37523			return;
37524		  }
37525  
37526		  var scroll = _refreshingAll === true ? prevScroll : self.scroll(),
37527			  p = reset ? 0 : (scroll - start) / change,
37528			  clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0,
37529			  prevProgress = self.progress,
37530			  isActive,
37531			  wasActive,
37532			  toggleState,
37533			  action,
37534			  stateChanged,
37535			  toggled,
37536			  isAtMax,
37537			  isTakingAction;
37538  
37539		  if (recordVelocity) {
37540			scroll2 = scroll1;
37541			scroll1 = containerAnimation ? scrollFunc() : scroll;
37542  
37543			if (snap) {
37544			  snap2 = snap1;
37545			  snap1 = animation && !isToggle ? animation.totalProgress() : clipped;
37546			}
37547		  }
37548  
37549		  if (anticipatePin && pin && !_refreshing && !_startup$1 && _lastScrollTime) {
37550			if (!clipped && start < scroll + (scroll - scroll2) / (_getTime$1() - _time2) * anticipatePin) {
37551			  clipped = 0.0001;
37552			} else if (clipped === 1 && end > scroll + (scroll - scroll2) / (_getTime$1() - _time2) * anticipatePin) {
37553			  clipped = 0.9999;
37554			}
37555		  }
37556  
37557		  if (clipped !== prevProgress && self.enabled) {
37558			isActive = self.isActive = !!clipped && clipped < 1;
37559			wasActive = !!prevProgress && prevProgress < 1;
37560			toggled = isActive !== wasActive;
37561			stateChanged = toggled || !!clipped !== !!prevProgress;
37562			self.direction = clipped > prevProgress ? 1 : -1;
37563			self.progress = clipped;
37564  
37565			if (stateChanged && !_refreshing) {
37566			  toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3;
37567  
37568			  if (isToggle) {
37569				action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState];
37570				isTakingAction = animation && (action === "complete" || action === "reset" || action in animation);
37571			  }
37572			}
37573  
37574			preventOverlaps && (toggled || isTakingAction) && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) {
37575			  return t.endAnimation();
37576			}));
37577  
37578			if (!isToggle) {
37579			  if (scrubTween && !_refreshing && !_startup$1) {
37580				scrubTween._dp._time - scrubTween._start !== scrubTween._time && scrubTween.render(scrubTween._dp._time - scrubTween._start);
37581  
37582				if (scrubTween.resetTo) {
37583				  scrubTween.resetTo("totalProgress", clipped, animation._tTime / animation._tDur);
37584				} else {
37585				  scrubTween.vars.totalProgress = clipped;
37586				  scrubTween.invalidate().restart();
37587				}
37588			  } else if (animation) {
37589				animation.totalProgress(clipped, !!(_refreshing && (lastRefresh || reset)));
37590			  }
37591			}
37592  
37593			if (pin) {
37594			  reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart);
37595  
37596			  if (!useFixedPosition) {
37597				pinSetter(_round(pinStart + pinChange * clipped));
37598			  } else if (stateChanged) {
37599				isAtMax = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction);
37600  
37601				if (pinReparent) {
37602				  if (!reset && (isActive || isAtMax)) {
37603					var bounds = _getBounds(pin, true),
37604						_offset = scroll - start;
37605  
37606					_reparent(pin, _body$1, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px);
37607				  } else {
37608					_reparent(pin, spacer);
37609				  }
37610				}
37611  
37612				_setState(isActive || isAtMax ? pinActiveState : pinState);
37613  
37614				pinMoves && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0));
37615			  }
37616			}
37617  
37618			snap && !tweenTo.tween && !_refreshing && !_startup$1 && snapDelayedCall.restart(true);
37619			toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEac
vendor: 4,284 bytes, lines 37619-37760
37619h(function (el) {
37620			  return el.classList[isActive || once ? "add" : "remove"](toggleClass.className);
37621			});
37622			onUpdate && !isToggle && !reset && onUpdate(self);
37623  
37624			if (stateChanged && !_refreshing) {
37625			  if (isToggle) {
37626				if (isTakingAction) {
37627				  if (action === "complete") {
37628					animation.pause().totalProgress(1);
37629				  } else if (action === "reset") {
37630					animation.restart(true).pause();
37631				  } else if (action === "restart") {
37632					animation.restart(true);
37633				  } else {
37634					animation[action]();
37635				  }
37636				}
37637  
37638				onUpdate && onUpdate(self);
37639			  }
37640  
37641			  if (toggled || !_limitCallbacks) {
37642				onToggle && toggled && _callback(self, onToggle);
37643				callbacks[toggleState] && _callback(self, callbacks[toggleState]);
37644				once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0);
37645  
37646				if (!toggled) {
37647				  toggleState = clipped === 1 ? 1 : 3;
37648				  callbacks[toggleState] && _callback(self, callbacks[toggleState]);
37649				}
37650			  }
37651  
37652			  if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) {
37653				_endAnimation(self.callbackAnimation);
37654  
37655				scrubTween ? scrubTween.progress(1) : _endAnimation(animation, action === "reverse" ? 1 : !clipped, 1);
37656			  }
37657			} else if (isToggle && onUpdate && !_refreshing) {
37658			  onUpdate(self);
37659			}
37660		  }
37661  
37662		  if (markerEndSetter) {
37663			var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll;
37664			markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0));
37665			markerEndSetter(n);
37666		  }
37667  
37668		  caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0));
37669		};
37670  
37671		self.enable = function (reset, refresh) {
37672		  if (!self.enabled) {
37673			self.enabled = true;
37674  
37675			_addListener$1(scroller, "resize", _onResize);
37676  
37677			isViewport || _addListener$1(scroller, "scroll", _onScroll$1);
37678			onRefreshInit && _addListener$1(ScrollTrigger, "refreshInit", onRefreshInit);
37679  
37680			if (reset !== false) {
37681			  self.progress = prevProgress = 0;
37682			  scroll1 = scroll2 = lastSnap = scrollFunc();
37683			}
37684  
37685			refresh !== false && self.refresh();
37686		  }
37687		};
37688  
37689		self.getTween = function (snap) {
37690		  return snap && tweenTo ? tweenTo.tween : scrubTween;
37691		};
37692  
37693		self.setPositions = function (newStart, newEnd, keepClamp, pinOffset) {
37694		  if (containerAnimation) {
37695			var st = containerAnimation.scrollTrigger,
37696				duration = containerAnimation.duration(),
37697				_change = st.end - st.start;
37698  
37699			newStart = st.start + _change * newStart / duration;
37700			newEnd = st.start + _change * newEnd / duration;
37701		  }
37702  
37703		  self.refresh(false, false, {
37704			start: _keepClamp(newStart, keepClamp && !!self._startClamp),
37705			end: _keepClamp(newEnd, keepClamp && !!self._endClamp)
37706		  }, pinOffset);
37707		  self.update();
37708		};
37709  
37710		self.adjustPinSpacing = function (amount) {
37711		  if (spacerState && amount) {
37712			var i = spacerState.indexOf(direction.d) + 1;
37713			spacerState[i] = parseFloat(spacerState[i]) + amount + _px;
37714			spacerState[1] = parseFloat(spacerState[1]) + amount + _px;
37715  
37716			_setState(spacerState);
37717		  }
37718		};
37719  
37720		self.disable = function (reset, allowAnimation) {
37721		  if (self.enabled) {
37722			reset !== false && self.revert(true, true);
37723			self.enabled = self.isActive = false;
37724			allowAnimation || scrubTween && scrubTween.pause();
37725			prevScroll = 0;
37726			pinCache && (pinCache.uncache = 1);
37727			onRefreshInit && _removeListener$1(ScrollTrigger, "refreshInit", onRefreshInit);
37728  
37729			if (snapDelayedCall) {
37730			  snapDelayedCall.pause();
37731			  tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0);
37732			}
37733  
37734			if (!isViewport) {
37735			  var i = _triggers.length;
37736  
37737			  while (i--) {
37738				if (_triggers[i].scroller === scroller && _triggers[i] !== self) {
37739				  return;
37740				}
37741			  }
37742  
37743			  _removeListener$1(scroller, "resize", _onResize);
37744  
37745			  isViewport || _removeListener$1(scroller, "scroll", _onScroll$1);
37746			}
37747		  }
37748		};
37749  
37750		self.kill = function (revert, allowAnimation) {
37751		  self.disable(revert, allowAnimation);
37752		  scrubTween && !allowAnimation && scrubTween.kill();
37753		  id && delete _ids[id];
37754  
37755		  var i = _triggers.indexOf(self);
37756  
37757		  i >= 0 && _triggers.splice(i, 1);
37758		  i === _i && _direction > 0 && _i--;
37759		  i = 0;
37760  
vendor: 15,520 bytes, lines 37761-38267
37761		  _triggers.forEach(function (t) {
37762			return t.scroller === self.scroller && (i = 1);
37763		  });
37764  
37765		  i || _refreshingAll || (self.scroll.rec = 0);
37766  
37767		  if (animation) {
37768			animation.scrollTrigger = null;
37769			revert && animation.revert({
37770			  kill: false
37771			});
37772			allowAnimation || animation.kill();
37773		  }
37774  
37775		  markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {
37776			return m.parentNode && m.parentNode.removeChild(m);
37777		  });
37778		  _primary === self && (_primary = 0);
37779  
37780		  if (pin) {
37781			pinCache && (pinCache.uncache = 1);
37782			i = 0;
37783  
37784			_triggers.forEach(function (t) {
37785			  return t.pin === pin && i++;
37786			});
37787  
37788			i || (pinCache.spacer = 0);
37789		  }
37790  
37791		  vars.onKill && vars.onKill(self);
37792		};
37793  
37794		_triggers.push(self);
37795  
37796		self.enable(false, false);
37797		customRevertReturn && customRevertReturn(self);
37798  
37799		if (animation && animation.add && !change) {
37800		  var updateFunc = self.update;
37801  
37802		  self.update = function () {
37803			self.update = updateFunc;
37804			start || end || self.refresh();
37805		  };
37806  
37807		  gsap$1.delayedCall(0.01, self.update);
37808		  change = 0.01;
37809		  start = end = 0;
37810		} else {
37811		  self.refresh();
37812		}
37813  
37814		pin && _queueRefreshAll();
37815	  };
37816  
37817	  ScrollTrigger.register = function register(core) {
37818		if (!_coreInitted$1) {
37819		  gsap$1 = core || _getGSAP$1();
37820		  _windowExists() && window.document && ScrollTrigger.enable();
37821		  _coreInitted$1 = _enabled;
37822		}
37823  
37824		return _coreInitted$1;
37825	  };
37826  
37827	  ScrollTrigger.defaults = function defaults(config) {
37828		if (config) {
37829		  for (var p in config) {
37830			_defaults[p] = config[p];
37831		  }
37832		}
37833  
37834		return _defaults;
37835	  };
37836  
37837	  ScrollTrigger.disable = function disable(reset, kill) {
37838		_enabled = 0;
37839  
37840		_triggers.forEach(function (trigger) {
37841		  return trigger[kill ? "kill" : "disable"](reset);
37842		});
37843  
37844		_removeListener$1(_win$1, "wheel", _onScroll$1);
37845  
37846		_removeListener$1(_doc$1, "scroll", _onScroll$1);
37847  
37848		clearInterval(_syncInterval);
37849  
37850		_removeListener$1(_doc$1, "touchcancel", _passThrough);
37851  
37852		_removeListener$1(_body$1, "touchstart", _passThrough);
37853  
37854		_multiListener(_removeListener$1, _doc$1, "pointerdown,touchstart,mousedown", _pointerDownHandler);
37855  
37856		_multiListener(_removeListener$1, _doc$1, "pointerup,touchend,mouseup", _pointerUpHandler);
37857  
37858		_resizeDelay.kill();
37859  
37860		_iterateAutoRefresh(_removeListener$1);
37861  
37862		for (var i = 0; i < _scrollers.length; i += 3) {
37863		  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 1]);
37864  
37865		  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 2]);
37866		}
37867	  };
37868  
37869	  ScrollTrigger.enable = function enable() {
37870		_win$1 = window;
37871		_doc$1 = document;
37872		_docEl$1 = _doc$1.documentElement;
37873		_body$1 = _doc$1.body;
37874  
37875		if (gsap$1) {
37876		  _toArray = gsap$1.utils.toArray;
37877		  _clamp$1 = gsap$1.utils.clamp;
37878		  _context$1 = gsap$1.core.context || _passThrough;
37879		  _suppressOverwrites = gsap$1.core.suppressOverwrites || _passThrough;
37880		  _scrollRestoration = _win$1.history.scrollRestoration || "auto";
37881		  _lastScroll = _win$1.pageYOffset;
37882		  gsap$1.core.globals("ScrollTrigger", ScrollTrigger);
37883  
37884		  if (_body$1) {
37885			_enabled = 1;
37886			_div100vh = document.createElement("div");
37887			_div100vh.style.height = "100vh";
37888			_div100vh.style.position = "absolute";
37889  
37890			_refresh100vh();
37891  
37892			_rafBugFix();
37893  
37894			Observer.register(gsap$1);
37895			ScrollTrigger.isTouch = Observer.isTouch;
37896			_fixIOSBug = Observer.isTouch && /(iPad|iPhone|iPod|Mac)/g.test(navigator.userAgent);
37897			_ignoreMobileResize = Observer.isTouch === 1;
37898  
37899			_addListener$1(_win$1, "wheel", _onScroll$1);
37900  
37901			_root$1 = [_win$1, _doc$1, _docEl$1, _body$1];
37902  
37903			if (gsap$1.matchMedia) {
37904			  ScrollTrigger.matchMedia = function (vars) {
37905				var mm = gsap$1.matchMedia(),
37906					p;
37907  
37908				for (p in vars) {
37909				  mm.add(p, vars[p]);
37910				}
37911  
37912				return mm;
37913			  };
37914  
37915			  gsap$1.addEventListener("matchMediaInit", function () {
37916				return _revertAll();
37917			  });
37918			  gsap$1.addEventListener("matchMediaRevert", function () {
37919				return _revertRecorded();
37920			  });
37921			  gsap$1.addEventListener("matchMedia", function () {
37922				_refreshAll(0, 1);
37923  
37924				_dispatch("matchMedia");
37925			  });
37926			  gsap$1.matchMedia("(orientation: portrait)", function () {
37927				_setBaseDimensions();
37928  
37929				return _setBaseDimensions;
37930			  });
37931			} else {
37932			  console.warn("Requires GSAP 3.11.0 or later");
37933			}
37934  
37935			_setBaseDimensions();
37936  
37937			_addListener$1(_doc$1, "scroll", _onScroll$1);
37938  
37939			var bodyStyle = _body$1.style,
37940				border = bodyStyle.borderTopStyle,
37941				AnimationProto = gsap$1.core.Animation.prototype,
37942				bounds,
37943				i;
37944			AnimationProto.revert || Object.defineProperty(AnimationProto, "revert", {
37945			  value: function value() {
37946				return this.time(-0.01, true);
37947			  }
37948			});
37949			bodyStyle.borderTopStyle = "solid";
37950			bounds = _getBounds(_body$1);
37951			_vertical.m = Math.round(bounds.top + _vertical.sc()) || 0;
37952			_horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0;
37953			border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style");
37954			_syncInterval = setInterval(_sync, 250);
37955			gsap$1.delayedCall(0.5, function () {
37956			  return _startup$1 = 0;
37957			});
37958  
37959			_addListener$1(_doc$1, "touchcancel", _passThrough);
37960  
37961			_addListener$1(_body$1, "touchstart", _passThrough);
37962  
37963			_multiListener(_addListener$1, _doc$1, "pointerdown,touchstart,mousedown", _pointerDownHandler);
37964  
37965			_multiListener(_addListener$1, _doc$1, "pointerup,touchend,mouseup", _pointerUpHandler);
37966  
37967			_transformProp = gsap$1.utils.checkPrefix("transform");
37968  
37969			_stateProps.push(_transformProp);
37970  
37971			_coreInitted$1 = _getTime$1();
37972			_resizeDelay = gsap$1.delayedCall(0.2, _refreshAll).pause();
37973			_autoRefresh = [_doc$1, "visibilitychange", function () {
37974			  var w = _win$1.innerWidth,
37975				  h = _win$1.innerHeight;
37976  
37977			  if (_doc$1.hidden) {
37978				_prevWidth = w;
37979				_prevHeight = h;
37980			  } else if (_prevWidth !== w || _prevHeight !== h) {
37981				_onResize();
37982			  }
37983			}, _doc$1, "DOMContentLoaded", _refreshAll, _win$1, "load", _refreshAll, _win$1, "resize", _onResize];
37984  
37985			_iterateAutoRefresh(_addListener$1);
37986  
37987			_triggers.forEach(function (trigger) {
37988			  return trigger.enable(0, 1);
37989			});
37990  
37991			for (i = 0; i < _scrollers.length; i += 3) {
37992			  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 1]);
37993  
37994			  _wheelListener(_removeListener$1, _scrollers[i], _scrollers[i + 2]);
37995			}
37996		  }
37997		}
37998	  };
37999  
38000	  ScrollTrigger.config = function config(vars) {
38001		"limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks);
38002		var ms = vars.syncInterval;
38003		ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms);
38004		"ignoreMobileResize" in vars && (_ignoreMobileResize = ScrollTrigger.isTouch === 1 && vars.ignoreMobileResize);
38005  
38006		if ("autoRefreshEvents" in vars) {
38007		  _iterateAutoRefresh(_removeListener$1) || _iterateAutoRefresh(_addListener$1, vars.autoRefreshEvents || "none");
38008		  _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1;
38009		}
38010	  };
38011  
38012	  ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) {
38013		var t = _getTarget(target),
38014			i = _scrollers.indexOf(t),
38015			isViewport = _isViewport$1(t);
38016  
38017		if (~i) {
38018		  _scrollers.splice(i, isViewport ? 6 : 2);
38019		}
38020  
38021		if (vars) {
38022		  isViewport ? _proxies.unshift(_win$1, vars, _body$1, vars, _docEl$1, vars) : _proxies.unshift(t, vars);
38023		}
38024	  };
38025  
38026	  ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) {
38027		_triggers.forEach(function (t) {
38028		  return t._ctx && t._ctx.query === query && t._ctx.kill(true, true);
38029		});
38030	  };
38031  
38032	  ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) {
38033		var bounds = (_isString(element) ? _getTarget(element) : element).getBoundingClientRect(),
38034			offset = bounds[horizontal ? _width : _height] * ratio || 0;
38035		return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win$1.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win$1.innerHeight;
38036	  };
38037  
38038	  ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) {
38039		_isString(element) && (element = _getTarget(element));
38040		var bounds = element.getBoundingClientRect(),
38041			size = bounds[horizontal ? _width : _height],
38042			offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0;
38043		return horizontal ? (bounds.left + offset) / _win$1.innerWidth : (bounds.top + offset) / _win$1.innerHeight;
38044	  };
38045  
38046	  ScrollTrigger.killAll = function killAll(allowListeners) {
38047		_triggers.slice(0).forEach(function (t) {
38048		  return t.vars.id !== "ScrollSmoother" && t.kill();
38049		});
38050  
38051		if (allowListeners !== true) {
38052		  var listeners = _listeners.killAll || [];
38053		  _listeners = {};
38054		  listeners.forEach(function (f) {
38055			return f();
38056		  });
38057		}
38058	  };
38059  
38060	  return ScrollTrigger;
38061	}();
38062	ScrollTrigger$1.version = "3.12.5";
38063  
38064	ScrollTrigger$1.saveStyles = function (targets) {
38065	  return targets ? _toArray(targets).forEach(function (target) {
38066		if (target && target.style) {
38067		  var i = _savedStyles.indexOf(target);
38068  
38069		  i >= 0 && _savedStyles.splice(i, 5);
38070  
38071		  _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap$1.core.getCache(target), _context$1());
38072		}
38073	  }) : _savedStyles;
38074	};
38075  
38076	ScrollTrigger$1.revert = function (soft, media) {
38077	  return _revertAll(!soft, media);
38078	};
38079  
38080	ScrollTrigger$1.create = function (vars, animation) {
38081	  return new ScrollTrigger$1(vars, animation);
38082	};
38083  
38084	ScrollTrigger$1.refresh = function (safe) {
38085	  return safe ? _onResize() : (_coreInitted$1 || ScrollTrigger$1.register()) && _refreshAll(true);
38086	};
38087  
38088	ScrollTrigger$1.update = function (force) {
38089	  return ++_scrollers.cache && _updateAll(force === true ? 2 : 0);
38090	};
38091  
38092	ScrollTrigger$1.clearScrollMemory = _clearScrollMemory;
38093  
38094	ScrollTrigger$1.maxScroll = function (element, horizontal) {
38095	  return _maxScroll(element, horizontal ? _horizontal : _vertical);
38096	};
38097  
38098	ScrollTrigger$1.getScrollFunc = function (element, horizontal) {
38099	  return _getScrollFunc(_getTarget(element), horizontal ? _horizontal : _vertical);
38100	};
38101  
38102	ScrollTrigger$1.getById = function (id) {
38103	  return _ids[id];
38104	};
38105  
38106	ScrollTrigger$1.getAll = function () {
38107	  return _triggers.filter(function (t) {
38108		return t.vars.id !== "ScrollSmoother";
38109	  });
38110	};
38111  
38112	ScrollTrigger$1.isScrolling = function () {
38113	  return !!_lastScrollTime;
38114	};
38115  
38116	ScrollTrigger$1.snapDirectional = _snapDirectional;
38117  
38118	ScrollTrigger$1.addEventListener = function (type, callback) {
38119	  var a = _listeners[type] || (_listeners[type] = []);
38120	  ~a.indexOf(callback) || a.push(callback);
38121	};
38122  
38123	ScrollTrigger$1.removeEventListener = function (type, callback) {
38124	  var a = _listeners[type],
38125		  i = a && a.indexOf(callback);
38126	  i >= 0 && a.splice(i, 1);
38127	};
38128  
38129	ScrollTrigger$1.batch = function (targets, vars) {
38130	  var result = [],
38131		  varsCopy = {},
38132		  interval = vars.interval || 0.016,
38133		  batchMax = vars.batchMax || 1e9,
38134		  proxyCallback = function proxyCallback(type, callback) {
38135		var elements = [],
38136			triggers = [],
38137			delay = gsap$1.delayedCall(interval, function () {
38138		  callback(elements, triggers);
38139		  elements = [];
38140		  triggers = [];
38141		}).pause();
38142		return function (self) {
38143		  elements.length || delay.restart(true);
38144		  elements.push(self.trigger);
38145		  triggers.push(self);
38146		  batchMax <= elements.length && delay.progress(1);
38147		};
38148	  },
38149		  p;
38150  
38151	  for (p in vars) {
38152		varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p];
38153	  }
38154  
38155	  if (_isFunction(batchMax)) {
38156		batchMax = batchMax();
38157  
38158		_addListener$1(ScrollTrigger$1, "refresh", function () {
38159		  return batchMax = vars.batchMax();
38160		});
38161	  }
38162  
38163	  _toArray(targets).forEach(function (target) {
38164		var config = {};
38165  
38166		for (p in varsCopy) {
38167		  config[p] = varsCopy[p];
38168		}
38169  
38170		config.trigger = target;
38171		result.push(ScrollTrigger$1.create(config));
38172	  });
38173  
38174	  return result;
38175	};
38176  
38177	var _clampScrollAndGetDurationMultiplier = function _clampScrollAndGetDurationMultiplier(scrollFunc, current, end, max) {
38178	  current > max ? scrollFunc(max) : current < 0 && scrollFunc(0);
38179	  return end > max ? (max - current) / (end - current) : end < 0 ? current / (current - end) : 1;
38180	},
38181		_allowNativePanning = function _allowNativePanning(target, direction) {
38182	  if (direction === true) {
38183		target.style.removeProperty("touch-action");
38184	  } else {
38185		target.style.touchAction = direction === true ? "auto" : direction ? "pan-" + direction + (Observer.isTouch ? " pinch-zoom" : "") : "none";
38186	  }
38187  
38188	  target === _docEl$1 && _allowNativePanning(_body$1, direction);
38189	},
38190		_overflow = {
38191	  auto: 1,
38192	  scroll: 1
38193	},
38194		_nestedScroll = function _nestedScroll(_ref5) {
38195	  var event = _ref5.event,
38196		  target = _ref5.target,
38197		  axis = _ref5.axis;
38198  
38199	  var node = (event.changedTouches ? event.changedTouches[0] : event).target,
38200		  cache = node._gsap || gsap$1.core.getCache(node),
38201		  time = _getTime$1(),
38202		  cs;
38203  
38204	  if (!cache._isScrollT || time - cache._isScrollT > 2000) {
38205		while (node && node !== _body$1 && (node.scrollHeight <= node.clientHeight && node.scrollWidth <= node.clientWidth || !(_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]))) {
38206		  node = node.parentNode;
38207		}
38208  
38209		cache._isScroll = node && node !== target && !_isViewport$1(node) && (_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]);
38210		cache._isScrollT = time;
38211	  }
38212  
38213	  if (cache._isScroll || axis === "x") {
38214		event.stopPropagation();
38215		event._gsapAllow = true;
38216	  }
38217	},
38218		_inputObserver = function _inputObserver(target, type, inputs, nested) {
38219	  return Observer.create({
38220		target: target,
38221		capture: true,
38222		debounce: false,
38223		lockAxis: true,
38224		type: type,
38225		onWheel: nested = nested && _nestedScroll,
38226		onPress: nested,
38227		onDrag: nested,
38228		onScroll: nested,
38229		onEnable: function onEnable() {
38230		  return inputs && _addListener$1(_doc$1, Observer.eventTypes[0], _captureInputs, false, true);
38231		},
38232		onDisable: function onDisable() {
38233		  return _removeListener$1(_doc$1, Observer.eventTypes[0], _captureInputs, true);
38234		}
38235	  });
38236	},
38237		_inputExp = /(input|label|select|textarea)/i,
38238		_inputIsFocused,
38239		_captureInputs = function _captureInputs(e) {
38240	  var isInput = _inputExp.test(e.target.tagName);
38241  
38242	  if (isInput || _inputIsFocused) {
38243		e._gsapAllow = true;
38244		_inputIsFocused = isInput;
38245	  }
38246	},
38247		_getScrollNormalizer = function _getScrollNormalizer(vars) {
38248	  _isObject(vars) || (vars = {});
38249	  vars.preventDefault = vars.isNormalizer = vars.allowClicks = true;
38250	  vars.type || (vars.type = "wheel,touch");
38251	  vars.debounce = !!vars.debounce;
38252	  vars.id = vars.id || "normalizer";
38253  
38254	  var _vars2 = vars,
38255		  normalizeScrollX = _vars2.normalizeScrollX,
38256		  momentum = _vars2.momentum,
38257		  allowNestedScroll = _vars2.allowNestedScroll,
38258		  onRelease = _vars2.onRelease,
38259		  self,
38260		  maxY,
38261		  target = _getTarget(vars.target) || _docEl$1,
38262		  smoother = gsap$1.core.globals().ScrollSmoother,
38263		  smootherInstance = smoother && smoother.get(),
38264		  content = _fixIOSBug && (vars.content && _getTarget(vars.content) || smootherInstance && vars.content !== false && !smootherInstance.smooth() && smootherInstance.content()),
38265		  scrollFuncY = _getScrollFunc(target, _vertical),
38266		  scrollFuncX = _getScrollFunc(target, _horizontal),
38267		  scale = 1,
vendor: 4,132 bytes, lines 38268-38389
38268		  initialScale = (Observer.isTouch && _win$1.visualViewport ? _win$1.visualViewport.scale * _win$1.visualViewport.width : _win$1.outerWidth) / _win$1.innerWidth,
38269		  wheelRefresh = 0,
38270		  resolveMomentumDuration = _isFunction(momentum) ? function () {
38271		return momentum(self);
38272	  } : function () {
38273		return momentum || 2.8;
38274	  },
38275		  lastRefreshID,
38276		  skipTouchMove,
38277		  inputObserver = _inputObserver(target, vars.type, true, allowNestedScroll),
38278		  resumeTouchMove = function resumeTouchMove() {
38279		return skipTouchMove = false;
38280	  },
38281		  scrollClampX = _passThrough,
38282		  scrollClampY = _passThrough,
38283		  updateClamps = function updateClamps() {
38284		maxY = _maxScroll(target, _vertical);
38285		scrollClampY = _clamp$1(_fixIOSBug ? 1 : 0, maxY);
38286		normalizeScrollX && (scrollClampX = _clamp$1(0, _maxScroll(target, _horizontal)));
38287		lastRefreshID = _refreshID;
38288	  },
38289		  removeContentOffset = function removeContentOffset() {
38290		content._gsap.y = _round(parseFloat(content._gsap.y) + scrollFuncY.offset) + "px";
38291		content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + parseFloat(content._gsap.y) + ", 0, 1)";
38292		scrollFuncY.offset = scrollFuncY.cacheID = 0;
38293	  },
38294		  ignoreDrag = function ignoreDrag() {
38295		if (skipTouchMove) {
38296		  requestAnimationFrame(resumeTouchMove);
38297  
38298		  var offset = _round(self.deltaY / 2),
38299			  scroll = scrollClampY(scrollFuncY.v - offset);
38300  
38301		  if (content && scroll !== scrollFuncY.v + scrollFuncY.offset) {
38302			scrollFuncY.offset = scroll - scrollFuncY.v;
38303  
38304			var y = _round((parseFloat(content && content._gsap.y) || 0) - scrollFuncY.offset);
38305  
38306			content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + y + ", 0, 1)";
38307			content._gsap.y = y + "px";
38308			scrollFuncY.cacheID = _scrollers.cache;
38309  
38310			_updateAll();
38311		  }
38312  
38313		  return true;
38314		}
38315  
38316		scrollFuncY.offset && removeContentOffset();
38317		skipTouchMove = true;
38318	  },
38319		  tween,
38320		  startScrollX,
38321		  startScrollY,
38322		  onStopDelayedCall,
38323		  onResize = function onResize() {
38324		updateClamps();
38325  
38326		if (tween.isActive() && tween.vars.scrollY > maxY) {
38327		  scrollFuncY() > maxY ? tween.progress(1) && scrollFuncY(maxY) : tween.resetTo("scrollY", maxY);
38328		}
38329	  };
38330  
38331	  content && gsap$1.set(content, {
38332		y: "+=0"
38333	  });
38334  
38335	  vars.ignoreCheck = function (e) {
38336		return _fixIOSBug && e.type === "touchmove" && ignoreDrag() || scale > 1.05 && e.type !== "touchstart" || self.isGesturing || e.touches && e.touches.length > 1;
38337	  };
38338  
38339	  vars.onPress = function () {
38340		skipTouchMove = false;
38341		var prevScale = scale;
38342		scale = _round((_win$1.visualViewport && _win$1.visualViewport.scale || 1) / initialScale);
38343		tween.pause();
38344		prevScale !== scale && _allowNativePanning(target, scale > 1.01 ? true : normalizeScrollX ? false : "x");
38345		startScrollX = scrollFuncX();
38346		startScrollY = scrollFuncY();
38347		updateClamps();
38348		lastRefreshID = _refreshID;
38349	  };
38350  
38351	  vars.onRelease = vars.onGestureStart = function (self, wasDragging) {
38352		scrollFuncY.offset && removeContentOffset();
38353  
38354		if (!wasDragging) {
38355		  onStopDelayedCall.restart(true);
38356		} else {
38357		  _scrollers.cache++;
38358		  var dur = resolveMomentumDuration(),
38359			  currentScroll,
38360			  endScroll;
38361  
38362		  if (normalizeScrollX) {
38363			currentScroll = scrollFuncX();
38364			endScroll = currentScroll + dur * 0.05 * -self.velocityX / 0.227;
38365			dur *= _clampScrollAndGetDurationMultiplier(scrollFuncX, currentScroll, endScroll, _maxScroll(target, _horizontal));
38366			tween.vars.scrollX = scrollClampX(endScroll);
38367		  }
38368  
38369		  currentScroll = scrollFuncY();
38370		  endScroll = currentScroll + dur * 0.05 * -self.velocityY / 0.227;
38371		  dur *= _clampScrollAndGetDurationMultiplier(scrollFuncY, currentScroll, endScroll, _maxScroll(target, _vertical));
38372		  tween.vars.scrollY = scrollClampY(endScroll);
38373		  tween.invalidate().duration(dur).play(0.01);
38374  
38375		  if (_fixIOSBug && tween.vars.scrollY >= maxY || currentScroll >= maxY - 1) {
38376			gsap$1.to({}, {
38377			  onUpdate: onResize,
38378			  duration: dur
38379			});
38380		  }
38381		}
38382  
38383		onRelease && onRelease(self);
38384	  };
38385  
38386	  vars.onWheel = function () {
38387		tween._ts && tween.pause();
38388  
38389		if (_getTime$1() - wheelRefresh > 1000) {
vendor: 28,617 bytes, lines 38390-39444
38390		  lastRefreshID = 0;
38391		  wheelRefresh = _getTime$1();
38392		}
38393	  };
38394  
38395	  vars.onChange = function (self, dx, dy, xArray, yArray) {
38396		_refreshID !== lastRefreshID && updateClamps();
38397		dx && normalizeScrollX && scrollFuncX(scrollClampX(xArray[2] === dx ? startScrollX + (self.startX - self.x) : scrollFuncX() + dx - xArray[1]));
38398  
38399		if (dy) {
38400		  scrollFuncY.offset && removeContentOffset();
38401		  var isTouch = yArray[2] === dy,
38402			  y = isTouch ? startScrollY + self.startY - self.y : scrollFuncY() + dy - yArray[1],
38403			  yClamped = scrollClampY(y);
38404		  isTouch && y !== yClamped && (startScrollY += yClamped - y);
38405		  scrollFuncY(yClamped);
38406		}
38407  
38408		(dy || dx) && _updateAll();
38409	  };
38410  
38411	  vars.onEnable = function () {
38412		_allowNativePanning(target, normalizeScrollX ? false : "x");
38413  
38414		ScrollTrigger$1.addEventListener("refresh", onResize);
38415  
38416		_addListener$1(_win$1, "resize", onResize);
38417  
38418		if (scrollFuncY.smooth) {
38419		  scrollFuncY.target.style.scrollBehavior = "auto";
38420		  scrollFuncY.smooth = scrollFuncX.smooth = false;
38421		}
38422  
38423		inputObserver.enable();
38424	  };
38425  
38426	  vars.onDisable = function () {
38427		_allowNativePanning(target, true);
38428  
38429		_removeListener$1(_win$1, "resize", onResize);
38430  
38431		ScrollTrigger$1.removeEventListener("refresh", onResize);
38432		inputObserver.kill();
38433	  };
38434  
38435	  vars.lockAxis = vars.lockAxis !== false;
38436	  self = new Observer(vars);
38437	  self.iOS = _fixIOSBug;
38438	  _fixIOSBug && !scrollFuncY() && scrollFuncY(1);
38439	  _fixIOSBug && gsap$1.ticker.add(_passThrough);
38440	  onStopDelayedCall = self._dc;
38441	  tween = gsap$1.to(self, {
38442		ease: "power4",
38443		paused: true,
38444		inherit: false,
38445		scrollX: normalizeScrollX ? "+=0.1" : "+=0",
38446		scrollY: "+=0.1",
38447		modifiers: {
38448		  scrollY: _interruptionTracker(scrollFuncY, scrollFuncY(), function () {
38449			return tween.pause();
38450		  })
38451		},
38452		onUpdate: _updateAll,
38453		onComplete: onStopDelayedCall.vars.onComplete
38454	  });
38455	  return self;
38456	};
38457  
38458	ScrollTrigger$1.sort = function (func) {
38459	  return _triggers.sort(func || function (a, b) {
38460		return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6);
38461	  });
38462	};
38463  
38464	ScrollTrigger$1.observe = function (vars) {
38465	  return new Observer(vars);
38466	};
38467  
38468	ScrollTrigger$1.normalizeScroll = function (vars) {
38469	  if (typeof vars === "undefined") {
38470		return _normalizer$1;
38471	  }
38472  
38473	  if (vars === true && _normalizer$1) {
38474		return _normalizer$1.enable();
38475	  }
38476  
38477	  if (vars === false) {
38478		_normalizer$1 && _normalizer$1.kill();
38479		_normalizer$1 = vars;
38480		return;
38481	  }
38482  
38483	  var normalizer = vars instanceof Observer ? vars : _getScrollNormalizer(vars);
38484	  _normalizer$1 && _normalizer$1.target === normalizer.target && _normalizer$1.kill();
38485	  _isViewport$1(normalizer.target) && (_normalizer$1 = normalizer);
38486	  return normalizer;
38487	};
38488  
38489	ScrollTrigger$1.core = {
38490	  _getVelocityProp: _getVelocityProp,
38491	  _inputObserver: _inputObserver,
38492	  _scrollers: _scrollers,
38493	  _proxies: _proxies,
38494	  bridge: {
38495		ss: function ss() {
38496		  _lastScrollTime || _dispatch("scrollStart");
38497		  _lastScrollTime = _getTime$1();
38498		},
38499		ref: function ref() {
38500		  return _refreshing;
38501		}
38502	  }
38503	};
38504	_getGSAP$1() && gsap$1.registerPlugin(ScrollTrigger$1);
38505  
38506	exports.ScrollTrigger = ScrollTrigger$1;
38507	exports.default = ScrollTrigger$1;
38508  
38509	if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;}
38510  
38511  })));
38512
38513/*!
38514 * CustomEase 3.12.7
38515 * https://gsap.com
38516 * 
38517 * @license Copyright 2025, GreenSock. All rights reserved.
38518 * Subject to the terms at https://gsap.com/standard-license or for Club GSAP members, the agreement issued with that membership.
38519 * @author: Jack Doyle, [email protected]
38520 */
38521
38522  (function (global, factory) {
38523	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
38524	typeof define === 'function' && define.amd ? define(['exports'], factory) :
38525	(global = global || self, factory(global.window = global.window || {}));
38526}(this, (function (exports) { 'use strict';
38527
38528	var _svgPathExp = /[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig,
38529	    _scientific = /[\+\-]?\d*\.?\d+e[\+\-]?\d+/ig,
38530	    _DEG2RAD = Math.PI / 180,
38531	    _sin = Math.sin,
38532	    _cos = Math.cos,
38533	    _abs = Math.abs,
38534	    _sqrt = Math.sqrt,
38535	    _isNumber = function _isNumber(value) {
38536	  return typeof value === "number";
38537	},
38538	    _roundingNum = 1e5,
38539	    _round = function _round(value) {
38540	  return Math.round(value * _roundingNum) / _roundingNum || 0;
38541	};
38542	function transformRawPath(rawPath, a, b, c, d, tx, ty) {
38543	  var j = rawPath.length,
38544	      segment,
38545	      l,
38546	      i,
38547	      x,
38548	      y;
38549
38550	  while (--j > -1) {
38551	    segment = rawPath[j];
38552	    l = segment.length;
38553
38554	    for (i = 0; i < l; i += 2) {
38555	      x = segment[i];
38556	      y = segment[i + 1];
38557	      segment[i] = x * a + y * c + tx;
38558	      segment[i + 1] = x * b + y * d + ty;
38559	    }
38560	  }
38561
38562	  rawPath._dirty = 1;
38563	  return rawPath;
38564	}
38565
38566	function arcToSegment(lastX, lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y) {
38567	  if (lastX === x && lastY === y) {
38568	    return;
38569	  }
38570
38571	  rx = _abs(rx);
38572	  ry = _abs(ry);
38573
38574	  var angleRad = angle % 360 * _DEG2RAD,
38575	      cosAngle = _cos(angleRad),
38576	      sinAngle = _sin(angleRad),
38577	      PI = Math.PI,
38578	      TWOPI = PI * 2,
38579	      dx2 = (lastX - x) / 2,
38580	      dy2 = (lastY - y) / 2,
38581	      x1 = cosAngle * dx2 + sinAngle * dy2,
38582	      y1 = -sinAngle * dx2 + cosAngle * dy2,
38583	      x1_sq = x1 * x1,
38584	      y1_sq = y1 * y1,
38585	      radiiCheck = x1_sq / (rx * rx) + y1_sq / (ry * ry);
38586
38587	  if (radiiCheck > 1) {
38588	    rx = _sqrt(radiiCheck) * rx;
38589	    ry = _sqrt(radiiCheck) * ry;
38590	  }
38591
38592	  var rx_sq = rx * rx,
38593	      ry_sq = ry * ry,
38594	      sq = (rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq) / (rx_sq * y1_sq + ry_sq * x1_sq);
38595
38596	  if (sq < 0) {
38597	    sq = 0;
38598	  }
38599
38600	  var coef = (largeArcFlag === sweepFlag ? -1 : 1) * _sqrt(sq),
38601	      cx1 = coef * (rx * y1 / ry),
38602	      cy1 = coef * -(ry * x1 / rx),
38603	      sx2 = (lastX + x) / 2,
38604	      sy2 = (lastY + y) / 2,
38605	      cx = sx2 + (cosAngle * cx1 - sinAngle * cy1),
38606	      cy = sy2 + (sinAngle * cx1 + cosAngle * cy1),
38607	      ux = (x1 - cx1) / rx,
38608	      uy = (y1 - cy1) / ry,
38609	      vx = (-x1 - cx1) / rx,
38610	      vy = (-y1 - cy1) / ry,
38611	      temp = ux * ux + uy * uy,
38612	      angleStart = (uy < 0 ? -1 : 1) * Math.acos(ux / _sqrt(temp)),
38613	      angleExtent = (ux * vy - uy * vx < 0 ? -1 : 1) * Math.acos((ux * vx + uy * vy) / _sqrt(temp * (vx * vx + vy * vy)));
38614
38615	  isNaN(angleExtent) && (angleExtent = PI);
38616
38617	  if (!sweepFlag && angleExtent > 0) {
38618	    angleExtent -= TWOPI;
38619	  } else if (sweepFlag && angleExtent < 0) {
38620	    angleExtent += TWOPI;
38621	  }
38622
38623	  angleStart %= TWOPI;
38624	  angleExtent %= TWOPI;
38625
38626	  var segments = Math.ceil(_abs(angleExtent) / (TWOPI / 4)),
38627	      rawPath = [],
38628	      angleIncrement = angleExtent / segments,
38629	      controlLength = 4 / 3 * _sin(angleIncrement / 2) / (1 + _cos(angleIncrement / 2)),
38630	      ma = cosAngle * rx,
38631	      mb = sinAngle * rx,
38632	      mc = sinAngle * -ry,
38633	      md = cosAngle * ry,
38634	      i;
38635
38636	  for (i = 0; i < segments; i++) {
38637	    angle = angleStart + i * angleIncrement;
38638	    x1 = _cos(angle);
38639	    y1 = _sin(angle);
38640	    ux = _cos(angle += angleIncrement);
38641	    uy = _sin(angle);
38642	    rawPath.push(x1 - controlLength * y1, y1 + controlLength * x1, ux + controlLength * uy, uy - controlLength * ux, ux, uy);
38643	  }
38644
38645	  for (i = 0; i < rawPath.length; i += 2) {
38646	    x1 = rawPath[i];
38647	    y1 = rawPath[i + 1];
38648	    rawPath[i] = x1 * ma + y1 * mc + cx;
38649	    rawPath[i + 1] = x1 * mb + y1 * md + cy;
38650	  }
38651
38652	  rawPath[i - 2] = x;
38653	  rawPath[i - 1] = y;
38654	  return rawPath;
38655	}
38656
38657	function stringToRawPath(d) {
38658	  var a = (d + "").replace(_scientific, function (m) {
38659	    var n = +m;
38660	    return n < 0.0001 && n > -0.0001 ? 0 : n;
38661	  }).match(_svgPathExp) || [],
38662	      path = [],
38663	      relativeX = 0,
38664	      relativeY = 0,
38665	      twoThirds = 2 / 3,
38666	      elements = a.length,
38667	      points = 0,
38668	      errorMessage = "ERROR: malformed path: " + d,
38669	      i,
38670	      j,
38671	      x,
38672	      y,
38673	      command,
38674	      isRelative,
38675	      segment,
38676	      startX,
38677	      startY,
38678	      difX,
38679	      difY,
38680	      beziers,
38681	      prevCommand,
38682	      flag1,
38683	      flag2,
38684	      line = function line(sx, sy, ex, ey) {
38685	    difX = (ex - sx) / 3;
38686	    difY = (ey - sy) / 3;
38687	    segment.push(sx + difX, sy + difY, ex - difX, ey - difY, ex, ey);
38688	  };
38689
38690	  if (!d || !isNaN(a[0]) || isNaN(a[1])) {
38691	    console.log(errorMessage);
38692	    return path;
38693	  }
38694
38695	  for (i = 0; i < elements; i++) {
38696	    prevCommand = command;
38697
38698	    if (isNaN(a[i])) {
38699	      command = a[i].toUpperCase();
38700	      isRelative = command !== a[i];
38701	    } else {
38702	      i--;
38703	    }
38704
38705	    x = +a[i + 1];
38706	    y = +a[i + 2];
38707
38708	    if (isRelative) {
38709	      x += relativeX;
38710	      y += relativeY;
38711	    }
38712
38713	    if (!i) {
38714	      startX = x;
38715	      startY = y;
38716	    }
38717
38718	    if (command === "M") {
38719	      if (segment) {
38720	        if (segment.length < 8) {
38721	          path.length -= 1;
38722	        } else {
38723	          points += segment.length;
38724	        }
38725	      }
38726
38727	      relativeX = startX = x;
38728	      relativeY = startY = y;
38729	      segment = [x, y];
38730	      path.push(segment);
38731	      i += 2;
38732	      command = "L";
38733	    } else if (command === "C") {
38734	      if (!segment) {
38735	        segment = [0, 0];
38736	      }
38737
38738	      if (!isRelative) {
38739	        relativeX = relativeY = 0;
38740	      }
38741
38742	      segment.push(x, y, relativeX + a[i + 3] * 1, relativeY + a[i + 4] * 1, relativeX += a[i + 5] * 1, relativeY += a[i + 6] * 1);
38743	      i += 6;
38744	    } else if (command === "S") {
38745	      difX = relativeX;
38746	      difY = relativeY;
38747
38748	      if (prevCommand === "C" || prevCommand === "S") {
38749	        difX += relativeX - segment[segment.length - 4];
38750	        difY += relativeY - segment[segment.length - 3];
38751	      }
38752
38753	      if (!isRelative) {
38754	        relativeX = relativeY = 0;
38755	      }
38756
38757	      segment.push(difX, difY, x, y, relativeX += a[i + 3] * 1, relativeY += a[i + 4] * 1);
38758	      i += 4;
38759	    } else if (command === "Q") {
38760	      difX = relativeX + (x - relativeX) * twoThirds;
38761	      difY = relativeY + (y - relativeY) * twoThirds;
38762
38763	      if (!isRelative) {
38764	        relativeX = relativeY = 0;
38765	      }
38766
38767	      relativeX += a[i + 3] * 1;
38768	      relativeY += a[i + 4] * 1;
38769	      segment.push(difX, difY, relativeX + (x - relativeX) * twoThirds, relativeY + (y - relativeY) * twoThirds, relativeX, relativeY);
38770	      i += 4;
38771	    } else if (command === "T") {
38772	      difX = relativeX - segment[segment.length - 4];
38773	      difY = relativeY - segment[segment.length - 3];
38774	      segment.push(relativeX + difX, relativeY + difY, x + (relativeX + difX * 1.5 - x) * twoThirds, y + (relativeY + difY * 1.5 - y) * twoThirds, relativeX = x, relativeY = y);
38775	      i += 2;
38776	    } else if (command === "H") {
38777	      line(relativeX, relativeY, relativeX = x, relativeY);
38778	      i += 1;
38779	    } else if (command === "V") {
38780	      line(relativeX, relativeY, relativeX, relativeY = x + (isRelative ? relativeY - relativeX : 0));
38781	      i += 1;
38782	    } else if (command === "L" || command === "Z") {
38783	      if (command === "Z") {
38784	        x = startX;
38785	        y = startY;
38786	        segment.closed = true;
38787	      }
38788
38789	      if (command === "L" || _abs(relativeX - x) > 0.5 || _abs(relativeY - y) > 0.5) {
38790	        line(relativeX, relativeY, x, y);
38791
38792	        if (command === "L") {
38793	          i += 2;
38794	        }
38795	      }
38796
38797	      relativeX = x;
38798	      relativeY = y;
38799	    } else if (command === "A") {
38800	      flag1 = a[i + 4];
38801	      flag2 = a[i + 5];
38802	      difX = a[i + 6];
38803	      difY = a[i + 7];
38804	      j = 7;
38805
38806	      if (flag1.length > 1) {
38807	        if (flag1.length < 3) {
38808	          difY = difX;
38809	          difX = flag2;
38810	          j--;
38811	        } else {
38812	          difY = flag2;
38813	          difX = flag1.substr(2);
38814	          j -= 2;
38815	        }
38816
38817	        flag2 = flag1.charAt(1);
38818	        flag1 = flag1.charAt(0);
38819	      }
38820
38821	      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);
38822	      i += j;
38823
38824	      if (beziers) {
38825	        for (j = 0; j < beziers.length; j++) {
38826	          segment.push(beziers[j]);
38827	        }
38828	      }
38829
38830	      relativeX = segment[segment.length - 2];
38831	      relativeY = segment[segment.length - 1];
38832	    } else {
38833	      console.log(errorMessage);
38834	    }
38835	  }
38836
38837	  i = segment.length;
38838
38839	  if (i < 6) {
38840	    path.pop();
38841	    i = 0;
38842	  } else if (segment[0] === segment[i - 2] && segment[1] === segment[i - 1]) {
38843	    segment.closed = true;
38844	  }
38845
38846	  path.totalPoints = points + i;
38847	  return path;
38848	}
38849	function rawPathToString(rawPath) {
38850	  if (_isNumber(rawPath[0])) {
38851	    rawPath = [rawPath];
38852	  }
38853
38854	  var result = "",
38855	      l = rawPath.length,
38856	      sl,
38857	      s,
38858	      i,
38859	      segment;
38860
38861	  for (s = 0; s < l; s++) {
38862	    segment = rawPath[s];
38863	    result += "M" + _round(segment[0]) + "," + _round(segment[1]) + " C";
38864	    sl = segment.length;
38865
38866	    for (i = 2; i < sl; i++) {
38867	      result += _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i]) + " ";
38868	    }
38869
38870	    if (segment.closed) {
38871	      result += "z";
38872	    }
38873	  }
38874
38875	  return result;
38876	}
38877
38878	/*!
38879	 * CustomEase 3.12.7
38880	 * https://gsap.com
38881	 *
38882	 * @license Copyright 2008-2025, GreenSock. All rights reserved.
38883	 * Subject to the terms at https://gsap.com/standard-license or for
38884	 * Club GSAP members, the agreement issued with that membership.
38885	 * @author: Jack Doyle, [email protected]
38886	*/
38887
38888	var gsap,
38889	    _coreInitted,
38890	    _getGSAP = function _getGSAP() {
38891	  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;
38892	},
38893	    _initCore = function _initCore() {
38894	  gsap = _getGSAP();
38895
38896	  if (gsap) {
38897	    gsap.registerEase("_CE", CustomEase.create);
38898	    _coreInitted = 1;
38899	  } else {
38900	    console.warn("Please gsap.registerPlugin(CustomEase)");
38901	  }
38902	},
38903	    _bigNum = 1e20,
38904	    _round$1 = function _round(value) {
38905	  return ~~(value * 1000 + (value < 0 ? -.5 : .5)) / 1000;
38906	},
38907	    _numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/gi,
38908	    _needsParsingExp = /[cLlsSaAhHvVtTqQ]/g,
38909	    _findMinimum = function _findMinimum(values) {
38910	  var l = values.length,
38911	      min = _bigNum,
38912	      i;
38913
38914	  for (i = 1; i < l; i += 6) {
38915	    +values[i] < min && (min = +values[i]);
38916	  }
38917
38918	  return min;
38919	},
38920	    _normalize = function _normalize(values, height, originY) {
38921	  if (!originY && originY !== 0) {
38922	    originY = Math.max(+values[values.length - 1], +values[1]);
38923	  }
38924
38925	  var tx = +values[0] * -1,
38926	      ty = -originY,
38927	      l = values.length,
38928	      sx = 1 / (+values[l - 2] + tx),
38929	      sy = -height || (Math.abs(+values[l - 1] - +values[1]) < 0.01 * (+values[l - 2] - +values[0]) ? _findMinimum(values) + ty : +values[l - 1] + ty),
38930	      i;
38931
38932	  if (sy) {
38933	    sy = 1 / sy;
38934	  } else {
38935	    sy = -sx;
38936	  }
38937
38938	  for (i = 0; i < l; i += 2) {
38939	    values[i] = (+values[i] + tx) * sx;
38940	    values[i + 1] = (+values[i + 1] + ty) * sy;
38941	  }
38942	},
38943	    _bezierToPoints = function _bezierToPoints(x1, y1, x2, y2, x3, y3, x4, y4, threshold, points, index) {
38944	  var x12 = (x1 + x2) / 2,
38945	      y12 = (y1 + y2) / 2,
38946	      x23 = (x2 + x3) / 2,
38947	      y23 = (y2 + y3) / 2,
38948	      x34 = (x3 + x4) / 2,
38949	      y34 = (y3 + y4) / 2,
38950	      x123 = (x12 + x23) / 2,
38951	      y123 = (y12 + y23) / 2,
38952	      x234 = (x23 + x34) / 2,
38953	      y234 = (y23 + y34) / 2,
38954	      x1234 = (x123 + x234) / 2,
38955	      y1234 = (y123 + y234) / 2,
38956	      dx = x4 - x1,
38957	      dy = y4 - y1,
38958	      d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx),
38959	      d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx),
38960	      length;
38961
38962	  if (!points) {
38963	    points = [{
38964	      x: x1,
38965	      y: y1
38966	    }, {
38967	      x: x4,
38968	      y: y4
38969	    }];
38970	    index = 1;
38971	  }
38972
38973	  points.splice(index || points.length - 1, 0, {
38974	    x: x1234,
38975	    y: y1234
38976	  });
38977
38978	  if ((d2 + d3) * (d2 + d3) > threshold * (dx * dx + dy * dy)) {
38979	    length = points.length;
38980
38981	    _bezierToPoints(x1, y1, x12, y12, x123, y123, x1234, y1234, threshold, points, index);
38982
38983	    _bezierToPoints(x1234, y1234, x234, y234, x34, y34, x4, y4, threshold, points, index + 1 + (points.length - length));
38984	  }
38985
38986	  return points;
38987	};
38988
38989	var CustomEase = function () {
38990	  function CustomEase(id, data, config) {
38991	    _coreInitted || _initCore();
38992	    this.id = id;
38993	     this.setData(data, config);
38994	  }
38995
38996	  var _proto = CustomEase.prototype;
38997
38998	  _proto.setData = function setData(data, config) {
38999	    config = config || {};
39000	    data = data || "0,0,1,1";
39001	    var values = data.match(_numExp),
39002	        closest = 1,
39003	        points = [],
39004	        lookup = [],
39005	        precision = config.precision || 1,
39006	        fast = precision <= 1,
39007	        l,
39008	        a1,
39009	        a2,
39010	        i,
39011	        inc,
39012	        j,
39013	        point,
39014	        prevPoint,
39015	        p;
39016	    this.data = data;
39017
39018	    if (_needsParsingExp.test(data) || ~data.indexOf("M") && data.indexOf("C") < 0) {
39019	      values = stringToRawPath(data)[0];
39020	    }
39021
39022	    l = values.length;
39023
39024	    if (l === 4) {
39025	      values.unshift(0, 0);
39026	      values.push(1, 1);
39027	      l = 8;
39028	    } else if ((l - 2) % 6) {
39029	      throw "Invalid CustomEase";
39030	    }
39031
39032	    if (+values[0] !== 0 || +values[l - 2] !== 1) {
39033	      _normalize(values, config.height, config.originY);
39034	    }
39035
39036	    this.segment = values;
39037
39038	    for (i = 2; i < l; i += 6) {
39039	      a1 = {
39040	        x: +values[i - 2],
39041	        y: +values[i - 1]
39042	      };
39043	      a2 = {
39044	        x: +values[i + 4],
39045	        y: +values[i + 5]
39046	      };
39047	      points.push(a1, a2);
39048
39049	      _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);
39050	    }
39051
39052	    l = points.length;
39053
39054	    for (i = 0; i < l; i++) {
39055	      point = points[i];
39056	      prevPoint = points[i - 1] || point;
39057
39058	      if ((point.x > prevPoint.x || prevPoint.y !== point.y && prevPoint.x === point.x || point === prevPoint) && point.x <= 1) {
39059	        prevPoint.cx = point.x - prevPoint.x;
39060	        prevPoint.cy = point.y - prevPoint.y;
39061	        prevPoint.n = point;
39062	        prevPoint.nx = point.x;
39063
39064	        if (fast && i > 1 && Math.abs(prevPoint.cy / prevPoint.cx - points[i - 2].cy / points[i - 2].cx) > 2) {
39065	          fast = 0;
39066	        }
39067
39068	        if (prevPoint.cx < closest) {
39069	          if (!prevPoint.cx) {
39070	            prevPoint.cx = 0.001;
39071
39072	            if (i === l - 1) {
39073	              prevPoint.x -= 0.001;
39074	              closest = Math.min(closest, 0.001);
39075	              fast = 0;
39076	            }
39077	          } else {
39078	            closest = prevPoint.cx;
39079	          }
39080	        }
39081	      } else {
39082	        points.splice(i--, 1);
39083	        l--;
39084	      }
39085	    }
39086
39087	    l = 1 / closest + 1 | 0;
39088	    inc = 1 / l;
39089	    j = 0;
39090	    point = points[0];
39091
39092	    if (fast) {
39093	      for (i = 0; i < l; i++) {
39094	        p = i * inc;
39095
39096	        if (point.nx < p) {
39097	          point = points[++j];
39098	        }
39099
39100	        a1 = point.y + (p - point.x) / point.cx * point.cy;
39101	        lookup[i] = {
39102	          x: p,
39103	          cx: inc,
39104	          y: a1,
39105	          cy: 0,
39106	          nx: 9
39107	        };
39108
39109	        if (i) {
39110	          lookup[i - 1].cy = a1 - lookup[i - 1].y;
39111	        }
39112	      }
39113
39114	      j = points[points.length - 1];
39115	      lookup[l - 1].cy = j.y - a1;
39116	      lookup[l - 1].cx = j.x - lookup[lookup.length - 1].x;
39117	    } else {
39118	      for (i = 0; i < l; i++) {
39119	        if (point.nx < i * inc) {
39120	          point = points[++j];
39121	        }
39122
39123	        lookup[i] = point;
39124	      }
39125
39126	      if (j < points.length - 1) {
39127	        lookup[i - 1] = points[points.length - 2];
39128	      }
39129	    }
39130
39131	    this.ease = function (p) {
39132	      var point = lookup[p * l | 0] || lookup[l - 1];
39133
39134	      if (point.nx < p) {
39135	        point = point.n;
39136	      }
39137
39138	      return point.y + (p - point.x) / point.cx * point.cy;
39139	    };
39140
39141	    this.ease.custom = this;
39142	    this.id && gsap && gsap.registerEase(this.id, this.ease);
39143	    return this;
39144	  };
39145
39146	  _proto.getSVGData = function getSVGData(config) {
39147	    return CustomEase.getSVGData(this, config);
39148	  };
39149
39150	  CustomEase.create = function create(id, data, config) {
39151	    return new CustomEase(id, data, config).ease;
39152	  };
39153
39154	  CustomEase.register = function register(core) {
39155	    gsap = core;
39156
39157	    _initCore();
39158	  };
39159
39160	  CustomEase.get = function get(id) {
39161	    return gsap.parseEase(id);
39162	  };
39163
39164	  CustomEase.getSVGData = function getSVGData(ease, config) {
39165	    config = config || {};
39166	    var width = config.width || 100,
39167	        height = config.height || 100,
39168	        x = config.x || 0,
39169	        y = (config.y || 0) + height,
39170	        e = gsap.utils.toArray(config.path)[0],
39171	        a,
39172	        slope,
39173	        i,
39174	        inc,
39175	        tx,
39176	        ty,
39177	        precision,
39178	        threshold,
39179	        prevX,
39180	        prevY;
39181
39182	    if (config.invert) {
39183	      height = -height;
39184	      y = 0;
39185	    }
39186
39187	    if (typeof ease === "string") {
39188	      ease = gsap.parseEase(ease);
39189	    }
39190
39191	    if (ease.custom) {
39192	      ease = ease.custom;
39193	    }
39194
39195	    if (ease instanceof CustomEase) {
39196	      a = rawPathToString(transformRawPath([ease.segment], width, 0, 0, -height, x, y));
39197	    } else {
39198	      a = [x, y];
39199	      precision = Math.max(5, (config.precision || 1) * 200);
39200	      inc = 1 / precision;
39201	      precision += 2;
39202	      threshold = 5 / precision;
39203	      prevX = _round$1(x + inc * width);
39204	      prevY = _round$1(y + ease(inc) * -height);
39205	      slope = (prevY - y) / (prevX - x);
39206
39207	      for (i = 2; i < precision; i++) {
39208	        tx = _round$1(x + i * inc * width);
39209	        ty = _round$1(y + ease(i * inc) * -height);
39210
39211	        if (Math.abs((ty - prevY) / (tx - prevX) - slope) > threshold || i === precision - 1) {
39212	          a.push(prevX, prevY);
39213	          slope = (ty - prevY) / (tx - prevX);
39214	        }
39215
39216	        prevX = tx;
39217	        prevY = ty;
39218	      }
39219
39220	      a = "M" + a.join(",");
39221	    }
39222
39223	    e && e.setAttribute("d", a);
39224	    return a;
39225	  };
39226
39227	  return CustomEase;
39228	}();
39229	CustomEase.version = "3.12.7";
39230	CustomEase.headless = true;
39231	_getGSAP() && gsap.registerPlugin(CustomEase);
39232
39233	exports.CustomEase = CustomEase;
39234	exports.default = CustomEase;
39235
39236	Object.defineProperty(exports, '__esModule', { value: true });
39237
39238})));
39239(function (global, factory) {
39240  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
39241  typeof define === 'function' && define.amd ? define(['exports'], factory) :
39242  (global = global || self, factory(global.window = global.window || {}));
39243}(this, (function (exports) { 'use strict';
39244
39245  function _inheritsLoose(subClass, superClass) {
39246    subClass.prototype = Object.create(superClass.prototype);
39247    subClass.prototype.constructor = subClass;
39248    subClass.__proto__ = superClass;
39249  }
39250
39251  function _assertThisInitialized(self) {
39252    if (self === void 0) {
39253      throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
39254    }
39255
39256    return self;
39257  }
39258
39259  var _doc,
39260      _win,
39261      _docElement,
39262      _body,
39263      _divContainer,
39264      _svgContainer,
39265      _identityMatrix,
39266      _gEl,
39267      _transformProp = "transform",
39268      _transformOriginProp = _transformProp + "Origin",
39269      _hasOffsetBug,
39270      _setDoc = function _setDoc(element) {
39271    var doc = element.ownerDocument || element;
39272
39273    if (!(_transformProp in element.style) && "msTransform" in element.style) {
39274      _transformProp = "msTransform";
39275      _transformOriginProp = _transformProp + "Origin";
39276    }
39277
39278    while (doc.parentNode && (doc = doc.parentNode)) {}
39279
39280    _win = window;
39281    _identityMatrix = new Matrix2D();
39282
39283    if (doc) {
39284      _doc = doc;
39285      _docElement = doc.documentElement;
39286      _body = doc.body;
39287      _gEl = _doc.createElementNS("http://www.w3.org/2000/svg", "g");
39288      _gEl.style.transform = "none";
39289      var d1 = doc.createElement("div"),
39290          d2 = doc.createElement("div"),
39291          root = doc && (doc.body || doc.firstElementChild);
39292
39293      if (root && root.appendChild) {
39294        root.appendChild(d1);
39295        d1.appendChild(d2);
39296        d1.setAttribute("style", "position:static;transform:translate3d(0,0,1px)");
39297        _hasOffsetBug = d2.offsetParent !== d1;
39298        root.removeChild(d1);
39299      }
39300    }
39301
39302    return doc;
39303  },
39304      _forceNonZeroScale = function _forceNonZeroScale(e) {
39305    var a, cache;
39306
39307    while (e && e !== _body) {
39308      cache = e._gsap;
39309      cache && cache.uncache && cache.get(e, "x");
39310
39311      if (cache && !cache.scaleX && !cache.scaleY && cache.renderTransform) {
39312        cache.scaleX = cache.scaleY = 1e-4;
39313        cache.renderTransform(1, cache);
39314        a ? a.push(cache) : a = [cache];
39315      }
39316
39317      e = e.parentNode;
39318    }
39319
39320    return a;
39321  },
39322      _svgTemps = [],
39323      _divTemps = [],
39324      _getDocScrollTop = function _getDocScrollTop() {
39325    return _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0;
39326  },
39327      _getDocScrollLeft = function _getDocScrollLeft() {
39328    return _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0;
39329  },
39330      _svgOwner = function _svgOwner(element) {
39331    return element.ownerSVGElement || ((element.tagName + "").toLowerCase() === "svg" ? element : null);
39332  },
39333      _isFixed = function _isFixed(element) {
39334    if (_win.getComputedStyle(element).position === "fixed") {
39335      return true;
39336    }
39337
39338    element = element.parentNode;
39339
39340    if (element && element.nodeType === 1) {
39341      return _isFixed(element);
39342    }
39343  },
39344      _createSibling = function _createSibling(element, i) {
39345    if (element.parentNode && (_doc || _setDoc(element))) {
39346      var svg = _svgOwner(element),
39347          ns = svg ? svg.getAttribute("xmlns") || "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml",
39348          type = svg ? i ? "rect" : "g" : "div",
39349          x = i !== 2 ? 0 : 100,
39350          y = i === 3 ? 100 : 0,
39351          css = "position:absolute;display:block;pointer-events:none;margin:0;padding:0;",
39352          e = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, "http"), type) : _doc.createElement(type);
39353
39354      if (i) {
39355        if (!svg) {
39356          if (!_divContainer) {
39357            _divContainer = _createSibling(element);
39358            _divContainer.style.cssText = css;
39359          }
39360
39361          e.style.cssText = css + "width:0.1px;height:0.1px;top:" + y + "px;left:" + x + "px";
39362
39363          _divContainer.appendChild(e);
39364        } else {
39365          _svgContainer || (_svgContainer = _createSibling(element));
39366          e.setAttribute("width", 0.01);
39367          e.setAttribute("height", 0.01);
39368          e.setAttribute("transform", "translate(" + x + "," + y + ")");
39369
39370          _svgContainer.appendChild(e);
39371        }
39372      }
39373
39374      return e;
39375    }
39376
39377    throw "Need document and parent.";
39378  },
39379      _consolidate = function _consolidate(m) {
39380    var c = new Matrix2D(),
39381        i = 0;
39382
39383    for (; i < m.numberOfItems; i++) {
39384      c.multiply(m.getItem(i).matrix);
39385    }
39386
39387    return c;
39388  },
39389      _getCTM = function _getCTM(svg) {
39390    var m = svg.getCTM(),
39391        transform;
39392
39393    if (!m) {
39394      transform = svg.style[_transformProp];
39395      svg.style[_transformProp] = "none";
39396      svg.appendChild(_gEl);
39397      m = _gEl.getCTM();
39398      svg.removeChild(_gEl);
39399      transform ? svg.style[_transformProp] = transform : svg.style.removeProperty(_transformProp.replace(/([A-Z])/g, "-$1").toLowerCase());
39400    }
39401
39402    return m || _identityMatrix.clone();
39403  },
39404      _placeSiblings = function _placeSiblings(element, adjustGOffset) {
39405    var svg = _svgOwner(element),
39406        isRootSVG = element === svg,
39407        siblings = svg ? _svgTemps : _divTemps,
39408        parent = element.parentNode,
39409        container,
39410        m,
39411        b,
39412        x,
39413        y,
39414        cs;
39415
39416    if (element === _win) {
39417      return element;
39418    }
39419
39420    siblings.length || siblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3));
39421    container = svg ? _svgContainer : _divContainer;
39422
39423    if (svg) {
39424      if (isRootSVG) {
39425        b = _getCTM(element);
39426        x = -b.e / b.a;
39427        y = -b.f / b.d;
39428        m = _identityMatrix;
39429      } else if (element.getBBox) {
39430        b = element.getBBox();
39431        m = element.transform ? element.transform.baseVal : {};
39432        m = !m.numberOfItems ? _identityMatrix : m.numberOfItems > 1 ? _consolidate(m) : m.getItem(0).matrix;
39433        x = m.a * b.x + m.c * b.y;
39434        y = m.b * b.x + m.d * b.y;
39435      } else {
39436        m = new Matrix2D();
39437        x = y = 0;
39438      }
39439
39440      if (adjustGOffset && element.tagName.toLowerCase() === "g") {
39441        x = y = 0;
39442      }
39443
39444      (isRootSVG ? svg : parent).appendChild(container);
vendor: 1,139 bytes, lines 39445-39480
39445      container.setAttribute("transform", "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + (m.e + x) + "," + (m.f + y) + ")");
39446    } else {
39447      x = y = 0;
39448
39449      if (_hasOffsetBug) {
39450        m = element.offsetParent;
39451        b = element;
39452
39453        while (b && (b = b.parentNode) && b !== m && b.parentNode) {
39454          if ((_win.getComputedStyle(b)[_transformProp] + "").length > 4) {
39455            x = b.offsetLeft;
39456            y = b.offsetTop;
39457            b = 0;
39458          }
39459        }
39460      }
39461
39462      cs = _win.getComputedStyle(element);
39463
39464      if (cs.position !== "absolute" && cs.position !== "fixed") {
39465        m = element.offsetParent;
39466
39467        while (parent && parent !== m) {
39468          x += parent.scrollLeft || 0;
39469          y += parent.scrollTop || 0;
39470          parent = parent.parentNode;
39471        }
39472      }
39473
39474      b = container.style;
39475      b.top = element.offsetTop - y + "px";
39476      b.left = element.offsetLeft - x + "px";
39477      b[_transformProp] = cs[_transformProp];
39478      b[_transformOriginProp] = cs[_transformOriginProp];
39479      b.position = cs.position === "fixed" ? "fixed" : "absolute";
39480      element.parentNode
vendor: 37,456 bytes, lines 39480-40735
39480.appendChild(container);
39481    }
39482
39483    return container;
39484  },
39485      _setMatrix = function _setMatrix(m, a, b, c, d, e, f) {
39486    m.a = a;
39487    m.b = b;
39488    m.c = c;
39489    m.d = d;
39490    m.e = e;
39491    m.f = f;
39492    return m;
39493  };
39494
39495  var Matrix2D = function () {
39496    function Matrix2D(a, b, c, d, e, f) {
39497      if (a === void 0) {
39498        a = 1;
39499      }
39500
39501      if (b === void 0) {
39502        b = 0;
39503      }
39504
39505      if (c === void 0) {
39506        c = 0;
39507      }
39508
39509      if (d === void 0) {
39510        d = 1;
39511      }
39512
39513      if (e === void 0) {
39514        e = 0;
39515      }
39516
39517      if (f === void 0) {
39518        f = 0;
39519      }
39520
39521      _setMatrix(this, a, b, c, d, e, f);
39522    }
39523
39524    var _proto = Matrix2D.prototype;
39525
39526    _proto.inverse = function inverse() {
39527      var a = this.a,
39528          b = this.b,
39529          c = this.c,
39530          d = this.d,
39531          e = this.e,
39532          f = this.f,
39533          determinant = a * d - b * c || 1e-10;
39534      return _setMatrix(this, d / determinant, -b / determinant, -c / determinant, a / determinant, (c * f - d * e) / determinant, -(a * f - b * e) / determinant);
39535    };
39536
39537    _proto.multiply = function multiply(matrix) {
39538      var a = this.a,
39539          b = this.b,
39540          c = this.c,
39541          d = this.d,
39542          e = this.e,
39543          f = this.f,
39544          a2 = matrix.a,
39545          b2 = matrix.c,
39546          c2 = matrix.b,
39547          d2 = matrix.d,
39548          e2 = matrix.e,
39549          f2 = matrix.f;
39550      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);
39551    };
39552
39553    _proto.clone = function clone() {
39554      return new Matrix2D(this.a, this.b, this.c, this.d, this.e, this.f);
39555    };
39556
39557    _proto.equals = function equals(matrix) {
39558      var a = this.a,
39559          b = this.b,
39560          c = this.c,
39561          d = this.d,
39562          e = this.e,
39563          f = this.f;
39564      return a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f;
39565    };
39566
39567    _proto.apply = function apply(point, decoratee) {
39568      if (decoratee === void 0) {
39569        decoratee = {};
39570      }
39571
39572      var x = point.x,
39573          y = point.y,
39574          a = this.a,
39575          b = this.b,
39576          c = this.c,
39577          d = this.d,
39578          e = this.e,
39579          f = this.f;
39580      decoratee.x = x * a + y * c + e || 0;
39581      decoratee.y = x * b + y * d + f || 0;
39582      return decoratee;
39583    };
39584
39585    return Matrix2D;
39586  }();
39587  function getGlobalMatrix(element, inverse, adjustGOffset, includeScrollInFixed) {
39588    if (!element || !element.parentNode || (_doc || _setDoc(element)).documentElement === element) {
39589      return new Matrix2D();
39590    }
39591
39592    var zeroScales = _forceNonZeroScale(element),
39593        svg = _svgOwner(element),
39594        temps = svg ? _svgTemps : _divTemps,
39595        container = _placeSiblings(element, adjustGOffset),
39596        b1 = temps[0].getBoundingClientRect(),
39597        b2 = temps[1].getBoundingClientRect(),
39598        b3 = temps[2].getBoundingClientRect(),
39599        parent = container.parentNode,
39600        isFixed = !includeScrollInFixed && _isFixed(element),
39601        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()));
39602
39603    parent.removeChild(container);
39604
39605    if (zeroScales) {
39606      b1 = zeroScales.length;
39607
39608      while (b1--) {
39609        b2 = zeroScales[b1];
39610        b2.scaleX = b2.scaleY = 0;
39611        b2.renderTransform(1, b2);
39612      }
39613    }
39614
39615    return inverse ? m.inverse() : m;
39616  }
39617
39618  var gsap,
39619      _win$1,
39620      _doc$1,
39621      _docElement$1,
39622      _body$1,
39623      _tempDiv,
39624      _placeholderDiv,
39625      _coreInitted,
39626      _checkPrefix,
39627      _toArray,
39628      _supportsPassive,
39629      _isTouchDevice,
39630      _touchEventLookup,
39631      _isMultiTouching,
39632      _isAndroid,
39633      InertiaPlugin,
39634      _defaultCursor,
39635      _supportsPointer,
39636      _context,
39637      _getStyleSaver,
39638      _dragCount = 0,
39639      _windowExists = function _windowExists() {
39640    return typeof window !== "undefined";
39641  },
39642      _getGSAP = function _getGSAP() {
39643    return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap;
39644  },
39645      _isFunction = function _isFunction(value) {
39646    return typeof value === "function";
39647  },
39648      _isObject = function _isObject(value) {
39649    return typeof value === "object";
39650  },
39651      _isUndefined = function _isUndefined(value) {
39652    return typeof value === "undefined";
39653  },
39654      _emptyFunc = function _emptyFunc() {
39655    return false;
39656  },
39657      _transformProp$1 = "transform",
39658      _transformOriginProp$1 = "transformOrigin",
39659      _round = function _round(value) {
39660    return Math.round(value * 10000) / 10000;
39661  },
39662      _isArray = Array.isArray,
39663      _createElement = function _createElement(type, ns) {
39664    var e = _doc$1.createElementNS ? _doc$1.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc$1.createElement(type);
39665    return e.style ? e : _doc$1.createElement(type);
39666  },
39667      _RAD2DEG = 180 / Math.PI,
39668      _bigNum = 1e20,
39669      _identityMatrix$1 = new Matrix2D(),
39670      _getTime = Date.now || function () {
39671    return new Date().getTime();
39672  },
39673      _renderQueue = [],
39674      _lookup = {},
39675      _lookupCount = 0,
39676      _clickableTagExp = /^(?:a|input|textarea|button|select)$/i,
39677      _lastDragTime = 0,
39678      _temp1 = {},
39679      _windowProxy = {},
39680      _copy = function _copy(obj, factor) {
39681    var copy = {},
39682        p;
39683
39684    for (p in obj) {
39685      copy[p] = factor ? obj[p] * factor : obj[p];
39686    }
39687
39688    return copy;
39689  },
39690      _extend = function _extend(obj, defaults) {
39691    for (var p in defaults) {
39692      if (!(p in obj)) {
39693        obj[p] = defaults[p];
39694      }
39695    }
39696
39697    return obj;
39698  },
39699      _setTouchActionForAllDescendants = function _setTouchActionForAllDescendants(elements, value) {
39700    var i = elements.length,
39701        children;
39702
39703    while (i--) {
39704      value ? elements[i].style.touchAction = value : elements[i].style.removeProperty("touch-action");
39705      children = elements[i].children;
39706      children && children.length && _setTouchActionForAllDescendants(children, value);
39707    }
39708  },
39709      _renderQueueTick = function _renderQueueTick() {
39710    return _renderQueue.forEach(function (func) {
39711      return func();
39712    });
39713  },
39714      _addToRenderQueue = function _addToRenderQueue(func) {
39715    _renderQueue.push(func);
39716
39717    if (_renderQueue.length === 1) {
39718      gsap.ticker.add(_renderQueueTick);
39719    }
39720  },
39721      _renderQueueTimeout = function _renderQueueTimeout() {
39722    return !_renderQueue.length && gsap.ticker.remove(_renderQueueTick);
39723  },
39724      _removeFromRenderQueue = function _removeFromRenderQueue(func) {
39725    var i = _renderQueue.length;
39726
39727    while (i--) {
39728      if (_renderQueue[i] === func) {
39729        _renderQueue.splice(i, 1);
39730      }
39731    }
39732
39733    gsap.to(_renderQueueTimeout, {
39734      overwrite: true,
39735      delay: 15,
39736      duration: 0,
39737      onComplete: _renderQueueTimeout,
39738      data: "_draggable"
39739    });
39740  },
39741      _setDefaults = function _setDefaults(obj, defaults) {
39742    for (var p in defaults) {
39743      if (!(p in obj)) {
39744        obj[p] = defaults[p];
39745      }
39746    }
39747
39748    return obj;
39749  },
39750      _addListener = function _addListener(element, type, func, capture) {
39751    if (element.addEventListener) {
39752      var touchType = _touchEventLookup[type];
39753      capture = capture || (_supportsPassive ? {
39754        passive: false
39755      } : null);
39756      element.addEventListener(touchType || type, func, capture);
39757      touchType && type !== touchType && element.addEventListener(type, func, capture);
39758    }
39759  },
39760      _removeListener = function _removeListener(element, type, func, capture) {
39761    if (element.removeEventListener) {
39762      var touchType = _touchEventLookup[type];
39763      element.removeEventListener(touchType || type, func, capture);
39764      touchType && type !== touchType && element.removeEventListener(type, func, capture);
39765    }
39766  },
39767      _preventDefault = function _preventDefault(event) {
39768    event.preventDefault && event.preventDefault();
39769    event.preventManipulation && event.preventManipulation();
39770  },
39771      _hasTouchID = function _hasTouchID(list, ID) {
39772    var i = list.length;
39773
39774    while (i--) {
39775      if (list[i].identifier === ID) {
39776        return true;
39777      }
39778    }
39779  },
39780      _onMultiTouchDocumentEnd = function _onMultiTouchDocumentEnd(event) {
39781    _isMultiTouching = event.touches && _dragCount < event.touches.length;
39782
39783    _removeListener(event.target, "touchend", _onMultiTouchDocumentEnd);
39784  },
39785      _onMultiTouchDocument = function _onMultiTouchDocument(event) {
39786    _isMultiTouching = event.touches && _dragCount < event.touches.length;
39787
39788    _addListener(event.target, "touchend", _onMultiTouchDocumentEnd);
39789  },
39790      _getDocScrollTop$1 = function _getDocScrollTop(doc) {
39791    return _win$1.pageYOffset || doc.scrollTop || doc.documentElement.scrollTop || doc.body.scrollTop || 0;
39792  },
39793      _getDocScrollLeft$1 = function _getDocScrollLeft(doc) {
39794    return _win$1.pageXOffset || doc.scrollLeft || doc.documentElement.scrollLeft || doc.body.scrollLeft || 0;
39795  },
39796      _addScrollListener = function _addScrollListener(e, callback) {
39797    _addListener(e, "scroll", callback);
39798
39799    if (!_isRoot(e.parentNode)) {
39800      _addScrollListener(e.parentNode, callback);
39801    }
39802  },
39803      _removeScrollListener = function _removeScrollListener(e, callback) {
39804    _removeListener(e, "scroll", callback);
39805
39806    if (!_isRoot(e.parentNode)) {
39807      _removeScrollListener(e.parentNode, callback);
39808    }
39809  },
39810      _isRoot = function _isRoot(e) {
39811    return !!(!e || e === _docElement$1 || e.nodeType === 9 || e === _doc$1.body || e === _win$1 || !e.nodeType || !e.parentNode);
39812  },
39813      _getMaxScroll = function _getMaxScroll(element, axis) {
39814    var dim = axis === "x" ? "Width" : "Height",
39815        scroll = "scroll" + dim,
39816        client = "client" + dim;
39817    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]);
39818  },
39819      _recordMaxScrolls = function _recordMaxScrolls(e, skipCurrent) {
39820    var x = _getMaxScroll(e, "x"),
39821        y = _getMaxScroll(e, "y");
39822
39823    if (_isRoot(e)) {
39824      e = _windowProxy;
39825    } else {
39826      _recordMaxScrolls(e.parentNode, skipCurrent);
39827    }
39828
39829    e._gsMaxScrollX = x;
39830    e._gsMaxScrollY = y;
39831
39832    if (!skipCurrent) {
39833      e._gsScrollX = e.scrollLeft || 0;
39834      e._gsScrollY = e.scrollTop || 0;
39835    }
39836  },
39837      _setStyle = function _setStyle(element, property, value) {
39838    var style = element.style;
39839
39840    if (!style) {
39841      return;
39842    }
39843
39844    if (_isUndefined(style[property])) {
39845      property = _checkPrefix(property, element) || property;
39846    }
39847
39848    if (value == null) {
39849      style.removeProperty && style.removeProperty(property.replace(/([A-Z])/g, "-$1").toLowerCase());
39850    } else {
39851      style[property] = value;
39852    }
39853  },
39854      _getComputedStyle = function _getComputedStyle(element) {
39855    return _win$1.getComputedStyle(element instanceof Element ? element : element.host || (element.parentNode || {}).host || element);
39856  },
39857      _tempRect = {},
39858      _parseRect = function _parseRect(e) {
39859    if (e === _win$1) {
39860      _tempRect.left = _tempRect.top = 0;
39861      _tempRect.width = _tempRect.right = _docElement$1.clientWidth || e.innerWidth || _body$1.clientWidth || 0;
39862      _tempRect.height = _tempRect.bottom = (e.innerHeight || 0) - 20 < _docElement$1.clientHeight ? _docElement$1.clientHeight : e.innerHeight || _body$1.clientHeight || 0;
39863      return _tempRect;
39864    }
39865
39866    var doc = e.ownerDocument || _doc$1,
39867        r = !_isUndefined(e.pageX) ? {
39868      left: e.pageX - _getDocScrollLeft$1(doc),
39869      top: e.pageY - _getDocScrollTop$1(doc),
39870      right: e.pageX - _getDocScrollLeft$1(doc) + 1,
39871      bottom: e.pageY - _getDocScrollTop$1(doc) + 1
39872    } : !e.nodeType && !_isUndefined(e.left) && !_isUndefined(e.top) ? e : _toArray(e)[0].getBoundingClientRect();
39873
39874    if (_isUndefined(r.right) && !_isUndefined(r.width)) {
39875      r.right = r.left + r.width;
39876      r.bottom = r.top + r.height;
39877    } else if (_isUndefined(r.width)) {
39878      r = {
39879        width: r.right - r.left,
39880        height: r.bottom - r.top,
39881        right: r.right,
39882        left: r.left,
39883        bottom: r.bottom,
39884        top: r.top
39885      };
39886    }
39887
39888    return r;
39889  },
39890      _dispatchEvent = function _dispatchEvent(target, type, callbackName) {
39891    var vars = target.vars,
39892        callback = vars[callbackName],
39893        listeners = target._listeners[type],
39894        result;
39895
39896    if (_isFunction(callback)) {
39897      result = callback.apply(vars.callbackScope || target, vars[callbackName + "Params"] || [target.pointerEvent]);
39898    }
39899
39900    if (listeners && target.dispatchEvent(type) === false) {
39901      result = false;
39902    }
39903
39904    return result;
39905  },
39906      _getBounds = function _getBounds(target, context) {
39907    var e = _toArray(target)[0],
39908        top,
39909        left,
39910        offset;
39911
39912    if (!e.nodeType && e !== _win$1) {
39913      if (!_isUndefined(target.left)) {
39914        offset = {
39915          x: 0,
39916          y: 0
39917        };
39918        return {
39919          left: target.left - offset.x,
39920          top: target.top - offset.y,
39921          width: target.width,
39922          height: target.height
39923        };
39924      }
39925
39926      left = target.min || target.minX || target.minRotation || 0;
39927      top = target.min || target.minY || 0;
39928      return {
39929        left: left,
39930        top: top,
39931        width: (target.max || target.maxX || target.maxRotation || 0) - left,
39932        height: (target.max || target.maxY || 0) - top
39933      };
39934    }
39935
39936    return _getElementBounds(e, context);
39937  },
39938      _point1 = {},
39939      _getElementBounds = function _getElementBounds(element, context) {
39940    context = _toArray(context)[0];
39941    var isSVG = element.getBBox && element.ownerSVGElement,
39942        doc = element.ownerDocument || _doc$1,
39943        left,
39944        right,
39945        top,
39946        bottom,
39947        matrix,
39948        p1,
39949        p2,
39950        p3,
39951        p4,
39952        bbox,
39953        width,
39954        height,
39955        cs;
39956
39957    if (element === _win$1) {
39958      top = _getDocScrollTop$1(doc);
39959      left = _getDocScrollLeft$1(doc);
39960      right = left + (doc.documentElement.clientWidth || element.innerWidth || doc.body.clientWidth || 0);
39961      bottom = top + ((element.innerHeight || 0) - 20 < doc.documentElement.clientHeight ? doc.documentElement.clientHeight : element.innerHeight || doc.body.clientHeight || 0);
39962    } else if (context === _win$1 || _isUndefined(context)) {
39963      return element.getBoundingClientRect();
39964    } else {
39965      left = top = 0;
39966
39967      if (isSVG) {
39968        bbox = element.getBBox();
39969        width = bbox.width;
39970        height = bbox.height;
39971      } else {
39972        if (element.viewBox && (bbox = element.viewBox.baseVal)) {
39973          left = bbox.x || 0;
39974          top = bbox.y || 0;
39975          width = bbox.width;
39976          height = bbox.height;
39977        }
39978
39979        if (!width) {
39980          cs = _getComputedStyle(element);
39981          bbox = cs.boxSizing === "border-box";
39982          width = (parseFloat(cs.width) || element.clientWidth || 0) + (bbox ? 0 : parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth));
39983          height = (parseFloat(cs.height) || element.clientHeight || 0) + (bbox ? 0 : parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth));
39984        }
39985      }
39986
39987      right = width;
39988      bottom = height;
39989    }
39990
39991    if (element === context) {
39992      return {
39993        left: left,
39994        top: top,
39995        width: right - left,
39996        height: bottom - top
39997      };
39998    }
39999
40000    matrix = getGlobalMatrix(context, true).multiply(getGlobalMatrix(element));
40001    p1 = matrix.apply({
40002      x: left,
40003      y: top
40004    });
40005    p2 = matrix.apply({
40006      x: right,
40007      y: top
40008    });
40009    p3 = matrix.apply({
40010      x: right,
40011      y: bottom
40012    });
40013    p4 = matrix.apply({
40014      x: left,
40015      y: bottom
40016    });
40017    left = Math.min(p1.x, p2.x, p3.x, p4.x);
40018    top = Math.min(p1.y, p2.y, p3.y, p4.y);
40019    return {
40020      left: left,
40021      top: top,
40022      width: Math.max(p1.x, p2.x, p3.x, p4.x) - left,
40023      height: Math.max(p1.y, p2.y, p3.y, p4.y) - top
40024    };
40025  },
40026      _parseInertia = function _parseInertia(draggable, snap, max, min, factor, forceZeroVelocity) {
40027    var vars = {},
40028        a,
40029        i,
40030        l;
40031
40032    if (snap) {
40033      if (factor !== 1 && snap instanceof Array) {
40034        vars.end = a = [];
40035        l = snap.length;
40036
40037        if (_isObject(snap[0])) {
40038          for (i = 0; i < l; i++) {
40039            a[i] = _copy(snap[i], factor);
40040          }
40041        } else {
40042          for (i = 0; i < l; i++) {
40043            a[i] = snap[i] * factor;
40044          }
40045        }
40046
40047        max += 1.1;
40048        min -= 1.1;
40049      } else if (_isFunction(snap)) {
40050        vars.end = function (value) {
40051          var result = snap.call(draggable, value),
40052              copy,
40053              p;
40054
40055          if (factor !== 1) {
40056            if (_isObject(result)) {
40057              copy = {};
40058
40059              for (p in result) {
40060                copy[p] = result[p] * factor;
40061              }
40062
40063              result = copy;
40064            } else {
40065              result *= factor;
40066            }
40067          }
40068
40069          return result;
40070        };
40071      } else {
40072        vars.end = snap;
40073      }
40074    }
40075
40076    if (max || max === 0) {
40077      vars.max = max;
40078    }
40079
40080    if (min || min === 0) {
40081      vars.min = min;
40082    }
40083
40084    if (forceZeroVelocity) {
40085      vars.velocity = 0;
40086    }
40087
40088    return vars;
40089  },
40090      _isClickable = function _isClickable(element) {
40091    var data;
40092    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);
40093  },
40094      _setSelectable = function _setSelectable(elements, selectable) {
40095    var i = elements.length,
40096        e;
40097
40098    while (i--) {
40099      e = elements[i];
40100      e.ondragstart = e.onselectstart = selectable ? null : _emptyFunc;
40101      gsap.set(e, {
40102        lazy: true,
40103        userSelect: selectable ? "text" : "none"
40104      });
40105    }
40106  },
40107      _isFixed$1 = function _isFixed(element) {
40108    if (_getComputedStyle(element).position === "fixed") {
40109      return true;
40110    }
40111
40112    element = element.parentNode;
40113
40114    if (element && element.nodeType === 1) {
40115      return _isFixed(element);
40116    }
40117  },
40118      _supports3D,
40119      _addPaddingBR,
40120      ScrollProxy = function ScrollProxy(element, vars) {
40121    element = gsap.utils.toArray(element)[0];
40122    vars = vars || {};
40123    var content = document.createElement("div"),
40124        style = content.style,
40125        node = element.firstChild,
40126        offsetTop = 0,
40127        offsetLeft = 0,
40128        prevTop = element.scrollTop,
40129        prevLeft = element.scrollLeft,
40130        scrollWidth = element.scrollWidth,
40131        scrollHeight = element.scrollHeight,
40132        extraPadRight = 0,
40133        maxLeft = 0,
40134        maxTop = 0,
40135        elementWidth,
40136        elementHeight,
40137        contentHeight,
40138        nextNode,
40139        transformStart,
40140        transformEnd;
40141
40142    if (_supports3D && vars.force3D !== false) {
40143      transformStart = "translate3d(";
40144      transformEnd = "px,0px)";
40145    } else if (_transformProp$1) {
40146      transformStart = "translate(";
40147      transformEnd = "px)";
40148    }
40149
40150    this.scrollTop = function (value, force) {
40151      if (!arguments.length) {
40152        return -this.top();
40153      }
40154
40155      this.top(-value, force);
40156    };
40157
40158    this.scrollLeft = function (value, force) {
40159      if (!arguments.length) {
40160        return -this.left();
40161      }
40162
40163      this.left(-value, force);
40164    };
40165
40166    this.left = function (value, force) {
40167      if (!arguments.length) {
40168        return -(element.scrollLeft + offsetLeft);
40169      }
40170
40171      var dif = element.scrollLeft - prevLeft,
40172          oldOffset = offsetLeft;
40173
40174      if ((dif > 2 || dif < -2) && !force) {
40175        prevLeft = element.scrollLeft;
40176        gsap.killTweensOf(this, {
40177          left: 1,
40178          scrollLeft: 1
40179        });
40180        this.left(-prevLeft);
40181
40182        if (vars.onKill) {
40183          vars.onKill();
40184        }
40185
40186        return;
40187      }
40188
40189      value = -value;
40190
40191      if (value < 0) {
40192        offsetLeft = value - 0.5 | 0;
40193        value = 0;
40194      } else if (value > maxLeft) {
40195        offsetLeft = value - maxLeft | 0;
40196        value = maxLeft;
40197      } else {
40198        offsetLeft = 0;
40199      }
40200
40201      if (offsetLeft || oldOffset) {
40202        if (!this._skip) {
40203          style[_transformProp$1] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd;
40204        }
40205
40206        if (offsetLeft + extraPadRight >= 0) {
40207          style.paddingRight = offsetLeft + extraPadRight + "px";
40208        }
40209      }
40210
40211      element.scrollLeft = value | 0;
40212      prevLeft = element.scrollLeft;
40213    };
40214
40215    this.top = function (value, force) {
40216      if (!arguments.length) {
40217        return -(element.scrollTop + offsetTop);
40218      }
40219
40220      var dif = element.scrollTop - prevTop,
40221          oldOffset = offsetTop;
40222
40223      if ((dif > 2 || dif < -2) && !force) {
40224        prevTop = element.scrollTop;
40225        gsap.killTweensOf(this, {
40226          top: 1,
40227          scrollTop: 1
40228        });
40229        this.top(-prevTop);
40230
40231        if (vars.onKill) {
40232          vars.onKill();
40233        }
40234
40235        return;
40236      }
40237
40238      value = -value;
40239
40240      if (value < 0) {
40241        offsetTop = value - 0.5 | 0;
40242        value = 0;
40243      } else if (value > maxTop) {
40244        offsetTop = value - maxTop | 0;
40245        value = maxTop;
40246      } else {
40247        offsetTop = 0;
40248      }
40249
40250      if (offsetTop || oldOffset) {
40251        if (!this._skip) {
40252          style[_transformProp$1] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd;
40253        }
40254      }
40255
40256      element.scrollTop = value | 0;
40257      prevTop = element.scrollTop;
40258    };
40259
40260    this.maxScrollTop = function () {
40261      return maxTop;
40262    };
40263
40264    this.maxScrollLeft = function () {
40265      return maxLeft;
40266    };
40267
40268    this.disable = function () {
40269      node = content.firstChild;
40270
40271      while (node) {
40272        nextNode = node.nextSibling;
40273        element.appendChild(node);
40274        node = nextNode;
40275      }
40276
40277      if (element === content.parentNode) {
40278        element.removeChild(content);
40279      }
40280    };
40281
40282    this.enable = function () {
40283      node = element.firstChild;
40284
40285      if (node === content) {
40286        return;
40287      }
40288
40289      while (node) {
40290        nextNode = node.nextSibling;
40291        content.appendChild(node);
40292        node = nextNode;
40293      }
40294
40295      element.appendChild(content);
40296      this.calibrate();
40297    };
40298
40299    this.calibrate = function (force) {
40300      var widthMatches = element.clientWidth === elementWidth,
40301          cs,
40302          x,
40303          y;
40304      prevTop = element.scrollTop;
40305      prevLeft = element.scrollLeft;
40306
40307      if (widthMatches && element.clientHeight === elementHeight && content.offsetHeight === contentHeight && scrollWidth === element.scrollWidth && scrollHeight === element.scrollHeight && !force) {
40308        return;
40309      }
40310
40311      if (offsetTop || offsetLeft) {
40312        x = this.left();
40313        y = this.top();
40314        this.left(-element.scrollLeft);
40315        this.top(-element.scrollTop);
40316      }
40317
40318      cs = _getComputedStyle(element);
40319
40320      if (!widthMatches || force) {
40321        style.display = "block";
40322        style.width = "auto";
40323        style.paddingRight = "0px";
40324        extraPadRight = Math.max(0, element.scrollWidth - element.clientWidth);
40325
40326        if (extraPadRight) {
40327          extraPadRight += parseFloat(cs.paddingLeft) + (_addPaddingBR ? parseFloat(cs.paddingRight) : 0);
40328        }
40329      }
40330
40331      style.display = "inline-block";
40332      style.position = "relative";
40333      style.overflow = "visible";
40334      style.verticalAlign = "top";
40335      style.boxSizing = "content-box";
40336      style.width = "100%";
40337      style.paddingRight = extraPadRight + "px";
40338
40339      if (_addPaddingBR) {
40340        style.paddingBottom = cs.paddingBottom;
40341      }
40342
40343      elementWidth = element.clientWidth;
40344      elementHeight = element.clientHeight;
40345      scrollWidth = element.scrollWidth;
40346      scrollHeight = element.scrollHeight;
40347      maxLeft = element.scrollWidth - elementWidth;
40348      maxTop = element.scrollHeight - elementHeight;
40349      contentHeight = content.offsetHeight;
40350      style.display = "block";
40351
40352      if (x || y) {
40353        this.left(x);
40354        this.top(y);
40355      }
40356    };
40357
40358    this.content = content;
40359    this.element = element;
40360    this._skip = false;
40361    this.enable();
40362  },
40363      _initCore = function _initCore(required) {
40364    if (_windowExists() && document.body) {
40365      var nav = window && window.navigator;
40366      _win$1 = window;
40367      _doc$1 = document;
40368      _docElement$1 = _doc$1.documentElement;
40369      _body$1 = _doc$1.body;
40370      _tempDiv = _createElement("div");
40371      _supportsPointer = !!window.PointerEvent;
40372      _placeholderDiv = _createElement("div");
40373      _placeholderDiv.style.cssText = "visibility:hidden;height:1px;top:-1px;pointer-events:none;position:relative;clear:both;cursor:grab";
40374      _defaultCursor = _placeholderDiv.style.cursor === "grab" ? "grab" : "move";
40375      _isAndroid = nav && nav.userAgent.toLowerCase().indexOf("android") !== -1;
40376      _isTouchDevice = "ontouchstart" in _docElement$1 && "orientation" in _win$1 || nav && (nav.MaxTouchPoints > 0 || nav.msMaxTouchPoints > 0);
40377
40378      _addPaddingBR = function () {
40379        var div = _createElement("div"),
40380            child = _createElement("div"),
40381            childStyle = child.style,
40382            parent = _body$1,
40383            val;
40384
40385        childStyle.display = "inline-block";
40386        childStyle.position = "relative";
40387        div.style.cssText = "width:90px;height:40px;padding:10px;overflow:auto;visibility:hidden";
40388        div.appendChild(child);
40389        parent.appendChild(div);
40390        val = child.offsetHeight + 18 > div.scrollHeight;
40391        parent.removeChild(div);
40392        return val;
40393      }();
40394
40395      _touchEventLookup = function (types) {
40396        var standard = types.split(","),
40397            converted = ("onpointerdown" in _tempDiv ? "pointerdown,pointermove,pointerup,pointercancel" : "onmspointerdown" in _tempDiv ? "MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancel" : types).split(","),
40398            obj = {},
40399            i = 4;
40400
40401        while (--i > -1) {
40402          obj[standard[i]] = converted[i];
40403          obj[converted[i]] = standard[i];
40404        }
40405
40406        try {
40407          _docElement$1.addEventListener("test", null, Object.defineProperty({}, "passive", {
40408            get: function get() {
40409              _supportsPassive = 1;
40410            }
40411          }));
40412        } catch (e) {}
40413
40414        return obj;
40415      }("touchstart,touchmove,touchend,touchcancel");
40416
40417      _addListener(_doc$1, "touchcancel", _emptyFunc);
40418
40419      _addListener(_win$1, "touchmove", _emptyFunc);
40420
40421      _body$1 && _body$1.addEventListener("touchstart", _emptyFunc);
40422
40423      _addListener(_doc$1, "contextmenu", function () {
40424        for (var p in _lookup) {
40425          if (_lookup[p].isPressed) {
40426            _lookup[p].endDrag();
40427          }
40428        }
40429      });
40430
40431      gsap = _coreInitted = _getGSAP();
40432    }
40433
40434    if (gsap) {
40435      InertiaPlugin = gsap.plugins.inertia;
40436
40437      _context = gsap.core.context || function () {};
40438
40439      _checkPrefix = gsap.utils.checkPrefix;
40440      _transformProp$1 = _checkPrefix(_transformProp$1);
40441      _transformOriginProp$1 = _checkPrefix(_transformOriginProp$1);
40442      _toArray = gsap.utils.toArray;
40443      _getStyleSaver = gsap.core.getStyleSaver;
40444      _supports3D = !!_checkPrefix("perspective");
40445    } else if (required) {
40446      console.warn("Please gsap.registerPlugin(Draggable)");
40447    }
40448  };
40449
40450  var EventDispatcher = function () {
40451    function EventDispatcher(target) {
40452      this._listeners = {};
40453      this.target = target || this;
40454    }
40455
40456    var _proto = EventDispatcher.prototype;
40457
40458    _proto.addEventListener = function addEventListener(type, callback) {
40459      var list = this._listeners[type] || (this._listeners[type] = []);
40460
40461      if (!~list.indexOf(callback)) {
40462        list.push(callback);
40463      }
40464    };
40465
40466    _proto.removeEventListener = function removeEventListener(type, callback) {
40467      var list = this._listeners[type],
40468          i = list && list.indexOf(callback);
40469      i >= 0 && list.splice(i, 1);
40470    };
40471
40472    _proto.dispatchEvent = function dispatchEvent(type) {
40473      var _this = this;
40474
40475      var result;
40476      (this._listeners[type] || []).forEach(function (callback) {
40477        return callback.call(_this, {
40478          type: type,
40479          target: _this.target
40480        }) === false && (result = false);
40481      });
40482      return result;
40483    };
40484
40485    return EventDispatcher;
40486  }();
40487
40488  var Draggable = function (_EventDispatcher) {
40489    _inheritsLoose(Draggable, _EventDispatcher);
40490
40491    function Draggable(target, vars) {
40492      var _this2;
40493
40494      _this2 = _EventDispatcher.call(this) || this;
40495      _coreInitted || _initCore(1);
40496      target = _toArray(target)[0];
40497      _this2.styles = _getStyleSaver && _getStyleSaver(target, "transform,left,top");
40498
40499      if (!InertiaPlugin) {
40500        InertiaPlugin = gsap.plugins.inertia;
40501      }
40502
40503      _this2.vars = vars = _copy(vars || {});
40504      _this2.target = target;
40505      _this2.x = _this2.y = _this2.rotation = 0;
40506      _this2.dragResistance = parseFloat(vars.dragResistance) || 0;
40507      _this2.edgeResistance = isNaN(vars.edgeResistance) ? 1 : parseFloat(vars.edgeResistance) || 0;
40508      _this2.lockAxis = vars.lockAxis;
40509      _this2.autoScroll = vars.autoScroll || 0;
40510      _this2.lockedAxis = null;
40511      _this2.allowEventDefault = !!vars.allowEventDefault;
40512      gsap.getProperty(target, "x");
40513
40514      var type = (vars.type || "x,y").toLowerCase(),
40515          xyMode = ~type.indexOf("x") || ~type.indexOf("y"),
40516          rotationMode = type.indexOf("rotation") !== -1,
40517          xProp = rotationMode ? "rotation" : xyMode ? "x" : "left",
40518          yProp = xyMode ? "y" : "top",
40519          allowX = !!(~type.indexOf("x") || ~type.indexOf("left") || type === "scroll"),
40520          allowY = !!(~type.indexOf("y") || ~type.indexOf("top") || type === "scroll"),
40521          minimumMovement = vars.minimumMovement || 2,
40522          self = _assertThisInitialized(_this2),
40523          triggers = _toArray(vars.trigger || vars.handle || target),
40524          killProps = {},
40525          dragEndTime = 0,
40526          checkAutoScrollBounds = false,
40527          autoScrollMarginTop = vars.autoScrollMarginTop || 40,
40528          autoScrollMarginRight = vars.autoScrollMarginRight || 40,
40529          autoScrollMarginBottom = vars.autoScrollMarginBottom || 40,
40530          autoScrollMarginLeft = vars.autoScrollMarginLeft || 40,
40531          isClickable = vars.clickableTest || _isClickable,
40532          clickTime = 0,
40533          gsCache = target._gsap || gsap.core.getCache(target),
40534          isFixed = _isFixed$1(target),
40535          getPropAsNum = function getPropAsNum(property, unit) {
40536        return parseFloat(gsCache.get(target, property, unit));
40537      },
40538          ownerDoc = target.ownerDocument || _doc$1,
40539          enabled,
40540          scrollProxy,
40541          startPointerX,
40542          startPointerY,
40543          startElementX,
40544          startElementY,
40545          hasBounds,
40546          hasDragCallback,
40547          hasMoveCallback,
40548          maxX,
40549          minX,
40550          maxY,
40551          minY,
40552          touch,
40553          touchID,
40554          rotationOrigin,
40555          dirty,
40556          old,
40557          snapX,
40558          snapY,
40559          snapXY,
40560          isClicking,
40561          touchEventTarget,
40562          matrix,
40563          interrupted,
40564          allowNativeTouchScrolling,
40565          touchDragAxis,
40566          isDispatching,
40567          clickDispatch,
40568          trustedClickDispatch,
40569          isPreventingDefault,
40570          innerMatrix,
40571          dragged,
40572          onContextMenu = function onContextMenu(e) {
40573        _preventDefault(e);
40574
40575        e.stopImmediatePropagation && e.stopImmediatePropagation();
40576        return false;
40577      },
40578          render = function render(suppressEvents) {
40579        if (self.autoScroll && self.isDragging && (checkAutoScrollBounds || dirty)) {
40580          var e = target,
40581              autoScrollFactor = self.autoScroll * 15,
40582              parent,
40583              isRoot,
40584              rect,
40585              pointerX,
40586              pointerY,
40587              changeX,
40588              changeY,
40589              gap;
40590          checkAutoScrollBounds = false;
40591          _windowProxy.scrollTop = _win$1.pageYOffset != null ? _win$1.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop;
40592          _windowProxy.scrollLeft = _win$1.pageXOffset != null ? _win$1.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft;
40593          pointerX = self.pointerX - _windowProxy.scrollLeft;
40594          pointerY = self.pointerY - _windowProxy.scrollTop;
40595
40596          while (e && !isRoot) {
40597            isRoot = _isRoot(e.parentNode);
40598            parent = isRoot ? _windowProxy : e.parentNode;
40599            rect = isRoot ? {
40600              bottom: Math.max(_docElement$1.clientHeight, _win$1.innerHeight || 0),
40601              right: Math.max(_docElement$1.clientWidth, _win$1.innerWidth || 0),
40602              left: 0,
40603              top: 0
40604            } : parent.getBoundingClientRect();
40605            changeX = changeY = 0;
40606
40607            if (allowY) {
40608              gap = parent._gsMaxScrollY - parent.scrollTop;
40609
40610              if (gap < 0) {
40611                changeY = gap;
40612              } else if (pointerY > rect.bottom - autoScrollMarginBottom && gap) {
40613                checkAutoScrollBounds = true;
40614                changeY = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.bottom - pointerY) / autoScrollMarginBottom) | 0);
40615              } else if (pointerY < rect.top + autoScrollMarginTop && parent.scrollTop) {
40616                checkAutoScrollBounds = true;
40617                changeY = -Math.min(parent.scrollTop, autoScrollFactor * (1 - Math.max(0, pointerY - rect.top) / autoScrollMarginTop) | 0);
40618              }
40619
40620              if (changeY) {
40621                parent.scrollTop += changeY;
40622              }
40623            }
40624
40625            if (allowX) {
40626              gap = parent._gsMaxScrollX - parent.scrollLeft;
40627
40628              if (gap < 0) {
40629                changeX = gap;
40630              } else if (pointerX > rect.right - autoScrollMarginRight && gap) {
40631                checkAutoScrollBounds = true;
40632                changeX = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.right - pointerX) / autoScrollMarginRight) | 0);
40633              } else if (pointerX < rect.left + autoScrollMarginLeft && parent.scrollLeft) {
40634                checkAutoScrollBounds = true;
40635                changeX = -Math.min(parent.scrollLeft, autoScrollFactor * (1 - Math.max(0, pointerX - rect.left) / autoScrollMarginLeft) | 0);
40636              }
40637
40638              if (changeX) {
40639                parent.scrollLeft += changeX;
40640              }
40641            }
40642
40643            if (isRoot && (changeX || changeY)) {
40644              _win$1.scrollTo(parent.scrollLeft, parent.scrollTop);
40645
40646              setPointerPosition(self.pointerX + changeX, self.pointerY + changeY);
40647            }
40648
40649            e = parent;
40650          }
40651        }
40652
40653        if (dirty) {
40654          var x = self.x,
40655              y = self.y;
40656
40657          if (rotationMode) {
40658            self.deltaX = x - parseFloat(gsCache.rotation);
40659            self.rotation = x;
40660            gsCache.rotation = x + "deg";
40661            gsCache.renderTransform(1, gsCache);
40662          } else {
40663            if (scrollProxy) {
40664              if (allowY) {
40665                self.deltaY = y - scrollProxy.top();
40666                scrollProxy.top(y);
40667              }
40668
40669              if (allowX) {
40670                self.deltaX = x - scrollProxy.left();
40671                scrollProxy.left(x);
40672              }
40673            } else if (xyMode) {
40674              if (allowY) {
40675                self.deltaY = y - parseFloat(gsCache.y);
40676                gsCache.y = y + "px";
40677              }
40678
40679              if (allowX) {
40680                self.deltaX = x - parseFloat(gsCache.x);
40681                gsCache.x = x + "px";
40682              }
40683
40684              gsCache.renderTransform(1, gsCache);
40685            } else {
40686              if (allowY) {
40687                self.deltaY = y - parseFloat(target.style.top || 0);
40688                target.style.top = y + "px";
40689              }
40690
40691              if (allowX) {
40692                self.deltaX = x - parseFloat(target.style.left || 0);
40693                target.style.left = x + "px";
40694              }
40695            }
40696          }
40697
40698          if (hasDragCallback && !suppressEvents && !isDispatching) {
40699            isDispatching = true;
40700
40701            if (_dispatchEvent(self, "drag", "onDrag") === false) {
40702              if (allowX) {
40703                self.x -= self.deltaX;
40704              }
40705
40706              if (allowY) {
40707                self.y -= self.deltaY;
40708              }
40709
40710              render(true);
40711            }
40712
40713            isDispatching = false;
40714          }
40715        }
40716
40717        dirty = false;
40718      },
40719          syncXY = function syncXY(skipOnUpdate, skipSnap) {
40720        var x = self.x,
40721            y = self.y,
40722            snappedValue,
40723            cs;
40724
40725        if (!target._gsap) {
40726          gsCache = gsap.core.getCache(target);
40727        }
40728
40729        gsCache.uncache && gsap.getProperty(target, "x");
40730
40731        if (xyMode) {
40732          self.x = parseFloat(gsCache.x);
40733          self.y = parseFloat(gsCache.y);
40734        } else if (rotationMode) {
40735          self.x = self.rotation = 
40735parseFloat(gsCache.rotation
vendor: 18,327 bytes, lines 40735-41285
40735);
40736        } else if (scrollProxy) {
40737          self.y = scrollProxy.top();
40738          self.x = scrollProxy.left();
40739        } else {
40740          self.y = parseFloat(target.style.top || (cs = _getComputedStyle(target)) && cs.top) || 0;
40741          self.x = parseFloat(target.style.left || (cs || {}).left) || 0;
40742        }
40743
40744        if ((snapX || snapY || snapXY) && !skipSnap && (self.isDragging || self.isThrowing)) {
40745          if (snapXY) {
40746            _temp1.x = self.x;
40747            _temp1.y = self.y;
40748            snappedValue = snapXY(_temp1);
40749
40750            if (snappedValue.x !== self.x) {
40751              self.x = snappedValue.x;
40752              dirty = true;
40753            }
40754
40755            if (snappedValue.y !== self.y) {
40756              self.y = snappedValue.y;
40757              dirty = true;
40758            }
40759          }
40760
40761          if (snapX) {
40762            snappedValue = snapX(self.x);
40763
40764            if (snappedValue !== self.x) {
40765              self.x = snappedValue;
40766
40767              if (rotationMode) {
40768                self.rotation = snappedValue;
40769              }
40770
40771              dirty = true;
40772            }
40773          }
40774
40775          if (snapY) {
40776            snappedValue = snapY(self.y);
40777
40778            if (snappedValue !== self.y) {
40779              self.y = snappedValue;
40780            }
40781
40782            dirty = true;
40783          }
40784        }
40785
40786        dirty && render(true);
40787
40788        if (!skipOnUpdate) {
40789          self.deltaX = self.x - x;
40790          self.deltaY = self.y - y;
40791
40792          _dispatchEvent(self, "throwupdate", "onThrowUpdate");
40793        }
40794      },
40795          buildSnapFunc = function buildSnapFunc(snap, min, max, factor) {
40796        if (min == null) {
40797          min = -_bigNum;
40798        }
40799
40800        if (max == null) {
40801          max = _bigNum;
40802        }
40803
40804        if (_isFunction(snap)) {
40805          return function (n) {
40806            var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance;
40807            return snap.call(self, (n > max ? max + (n - max) * edgeTolerance : n < min ? min + (n - min) * edgeTolerance : n) * factor) * factor;
40808          };
40809        }
40810
40811        if (_isArray(snap)) {
40812          return function (n) {
40813            var i = snap.length,
40814                closest = 0,
40815                absDif = _bigNum,
40816                val,
40817                dif;
40818
40819            while (--i > -1) {
40820              val = snap[i];
40821              dif = val - n;
40822
40823              if (dif < 0) {
40824                dif = -dif;
40825              }
40826
40827              if (dif < absDif && val >= min && val <= max) {
40828                closest = i;
40829                absDif = dif;
40830              }
40831            }
40832
40833            return snap[closest];
40834          };
40835        }
40836
40837        return isNaN(snap) ? function (n) {
40838          return n;
40839        } : function () {
40840          return snap * factor;
40841        };
40842      },
40843          buildPointSnapFunc = function buildPointSnapFunc(snap, minX, maxX, minY, maxY, radius, factor) {
40844        radius = radius && radius < _bigNum ? radius * radius : _bigNum;
40845
40846        if (_isFunction(snap)) {
40847          return function (point) {
40848            var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance,
40849                x = point.x,
40850                y = point.y,
40851                result,
40852                dx,
40853                dy;
40854            point.x = x = x > maxX ? maxX + (x - maxX) * edgeTolerance : x < minX ? minX + (x - minX) * edgeTolerance : x;
40855            point.y = y = y > maxY ? maxY + (y - maxY) * edgeTolerance : y < minY ? minY + (y - minY) * edgeTolerance : y;
40856            result = snap.call(self, point);
40857
40858            if (result !== point) {
40859              point.x = result.x;
40860              point.y = result.y;
40861            }
40862
40863            if (factor !== 1) {
40864              point.x *= factor;
40865              point.y *= factor;
40866            }
40867
40868            if (radius < _bigNum) {
40869              dx = point.x - x;
40870              dy = point.y - y;
40871
40872              if (dx * dx + dy * dy > radius) {
40873                point.x = x;
40874                point.y = y;
40875              }
40876            }
40877
40878            return point;
40879          };
40880        }
40881
40882        if (_isArray(snap)) {
40883          return function (p) {
40884            var i = snap.length,
40885                closest = 0,
40886                minDist = _bigNum,
40887                x,
40888                y,
40889                point,
40890                dist;
40891
40892            while (--i > -1) {
40893              point = snap[i];
40894              x = point.x - p.x;
40895              y = point.y - p.y;
40896              dist = x * x + y * y;
40897
40898              if (dist < minDist) {
40899                closest = i;
40900                minDist = dist;
40901              }
40902            }
40903
40904            return minDist <= radius ? snap[closest] : p;
40905          };
40906        }
40907
40908        return function (n) {
40909          return n;
40910        };
40911      },
40912          calculateBounds = function calculateBounds() {
40913        var bounds, targetBounds, snap, snapIsRaw;
40914        hasBounds = false;
40915
40916        if (scrollProxy) {
40917          scrollProxy.calibrate();
40918          self.minX = minX = -scrollProxy.maxScrollLeft();
40919          self.minY = minY = -scrollProxy.maxScrollTop();
40920          self.maxX = maxX = self.maxY = maxY = 0;
40921          hasBounds = true;
40922        } else if (!!vars.bounds) {
40923          bounds = _getBounds(vars.bounds, target.parentNode);
40924
40925          if (rotationMode) {
40926            self.minX = minX = bounds.left;
40927            self.maxX = maxX = bounds.left + bounds.width;
40928            self.minY = minY = self.maxY = maxY = 0;
40929          } else if (!_isUndefined(vars.bounds.maxX) || !_isUndefined(vars.bounds.maxY)) {
40930            bounds = vars.bounds;
40931            self.minX = minX = bounds.minX;
40932            self.minY = minY = bounds.minY;
40933            self.maxX = maxX = bounds.maxX;
40934            self.maxY = maxY = bounds.maxY;
40935          } else {
40936            targetBounds = _getBounds(target, target.parentNode);
40937            self.minX = minX = Math.round(getPropAsNum(xProp, "px") + bounds.left - targetBounds.left);
40938            self.minY = minY = Math.round(getPropAsNum(yProp, "px") + bounds.top - targetBounds.top);
40939            self.maxX = maxX = Math.round(minX + (bounds.width - targetBounds.width));
40940            self.maxY = maxY = Math.round(minY + (bounds.height - targetBounds.height));
40941          }
40942
40943          if (minX > maxX) {
40944            self.minX = maxX;
40945            self.maxX = maxX = minX;
40946            minX = self.minX;
40947          }
40948
40949          if (minY > maxY) {
40950            self.minY = maxY;
40951            self.maxY = maxY = minY;
40952            minY = self.minY;
40953          }
40954
40955          if (rotationMode) {
40956            self.minRotation = minX;
40957            self.maxRotation = maxX;
40958          }
40959
40960          hasBounds = true;
40961        }
40962
40963        if (vars.liveSnap) {
40964          snap = vars.liveSnap === true ? vars.snap || {} : vars.liveSnap;
40965          snapIsRaw = _isArray(snap) || _isFunction(snap);
40966
40967          if (rotationMode) {
40968            snapX = buildSnapFunc(snapIsRaw ? snap : snap.rotation, minX, maxX, 1);
40969            snapY = null;
40970          } else {
40971            if (snap.points) {
40972              snapXY = buildPointSnapFunc(snapIsRaw ? snap : snap.points, minX, maxX, minY, maxY, snap.radius, scrollProxy ? -1 : 1);
40973            } else {
40974              if (allowX) {
40975                snapX = buildSnapFunc(snapIsRaw ? snap : snap.x || snap.left || snap.scrollLeft, minX, maxX, scrollProxy ? -1 : 1);
40976              }
40977
40978              if (allowY) {
40979                snapY = buildSnapFunc(snapIsRaw ? snap : snap.y || snap.top || snap.scrollTop, minY, maxY, scrollProxy ? -1 : 1);
40980              }
40981            }
40982          }
40983        }
40984      },
40985          onThrowComplete = function onThrowComplete() {
40986        self.isThrowing = false;
40987
40988        _dispatchEvent(self, "throwcomplete", "onThrowComplete");
40989      },
40990          onThrowInterrupt = function onThrowInterrupt() {
40991        self.isThrowing = false;
40992      },
40993          animate = function animate(inertia, forceZeroVelocity) {
40994        var snap, snapIsRaw, tween, overshootTolerance;
40995
40996        if (inertia && InertiaPlugin) {
40997          if (inertia === true) {
40998            snap = vars.snap || vars.liveSnap || {};
40999            snapIsRaw = _isArray(snap) || _isFunction(snap);
41000            inertia = {
41001              resistance: (vars.throwResistance || vars.resistance || 1000) / (rotationMode ? 10 : 1)
41002            };
41003
41004            if (rotationMode) {
41005              inertia.rotation = _parseInertia(self, snapIsRaw ? snap : snap.rotation, maxX, minX, 1, forceZeroVelocity);
41006            } else {
41007              if (allowX) {
41008                inertia[xProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.x || snap.left, maxX, minX, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "x");
41009              }
41010
41011              if (allowY) {
41012                inertia[yProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.y || snap.top, maxY, minY, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "y");
41013              }
41014
41015              if (snap.points || _isArray(snap) && _isObject(snap[0])) {
41016                inertia.linkedProps = xProp + "," + yProp;
41017                inertia.radius = snap.radius;
41018              }
41019            }
41020          }
41021
41022          self.isThrowing = true;
41023          overshootTolerance = !isNaN(vars.overshootTolerance) ? vars.overshootTolerance : vars.edgeResistance === 1 ? 0 : 1 - self.edgeResistance + 0.2;
41024
41025          if (!inertia.duration) {
41026            inertia.duration = {
41027              max: Math.max(vars.minDuration || 0, "maxDuration" in vars ? vars.maxDuration : 2),
41028              min: !isNaN(vars.minDuration) ? vars.minDuration : overshootTolerance === 0 || _isObject(inertia) && inertia.resistance > 1000 ? 0 : 0.5,
41029              overshoot: overshootTolerance
41030            };
41031          }
41032
41033          self.tween = tween = gsap.to(scrollProxy || target, {
41034            inertia: inertia,
41035            data: "_draggable",
41036            inherit: false,
41037            onComplete: onThrowComplete,
41038            onInterrupt: onThrowInterrupt,
41039            onUpdate: vars.fastMode ? _dispatchEvent : syncXY,
41040            onUpdateParams: vars.fastMode ? [self, "onthrowupdate", "onThrowUpdate"] : snap && snap.radius ? [false, true] : []
41041          });
41042
41043          if (!vars.fastMode) {
41044            if (scrollProxy) {
41045              scrollProxy._skip = true;
41046            }
41047
41048            tween.render(1e9, true, true);
41049            syncXY(true, true);
41050            self.endX = self.x;
41051            self.endY = self.y;
41052
41053            if (rotationMode) {
41054              self.endRotation = self.x;
41055            }
41056
41057            tween.play(0);
41058            syncXY(true, true);
41059
41060            if (scrollProxy) {
41061              scrollProxy._skip = false;
41062            }
41063          }
41064        } else if (hasBounds) {
41065          self.applyBounds();
41066        }
41067      },
41068          updateMatrix = function updateMatrix(shiftStart) {
41069        var start = matrix,
41070            p;
41071        matrix = getGlobalMatrix(target.parentNode, true);
41072
41073        if (shiftStart && self.isPressed && !matrix.equals(start || new Matrix2D())) {
41074          p = start.inverse().apply({
41075            x: startPointerX,
41076            y: startPointerY
41077          });
41078          matrix.apply(p, p);
41079          startPointerX = p.x;
41080          startPointerY = p.y;
41081        }
41082
41083        if (matrix.equals(_identityMatrix$1)) {
41084          matrix = null;
41085        }
41086      },
41087          recordStartPositions = function recordStartPositions() {
41088        var edgeTolerance = 1 - self.edgeResistance,
41089            offsetX = isFixed ? _getDocScrollLeft$1(ownerDoc) : 0,
41090            offsetY = isFixed ? _getDocScrollTop$1(ownerDoc) : 0,
41091            parsedOrigin,
41092            x,
41093            y;
41094
41095        if (xyMode) {
41096          gsCache.x = getPropAsNum(xProp, "px") + "px";
41097          gsCache.y = getPropAsNum(yProp, "px") + "px";
41098          gsCache.renderTransform();
41099        }
41100
41101        updateMatrix(false);
41102        _point1.x = self.pointerX - offsetX;
41103        _point1.y = self.pointerY - offsetY;
41104        matrix && matrix.apply(_point1, _point1);
41105        startPointerX = _point1.x;
41106        startPointerY = _point1.y;
41107
41108        if (dirty) {
41109          setPointerPosition(self.pointerX, self.pointerY);
41110          render(true);
41111        }
41112
41113        innerMatrix = getGlobalMatrix(target);
41114
41115        if (scrollProxy) {
41116          calculateBounds();
41117          startElementY = scrollProxy.top();
41118          startElementX = scrollProxy.left();
41119        } else {
41120          if (isTweening()) {
41121            syncXY(true, true);
41122            calculateBounds();
41123          } else {
41124            self.applyBounds();
41125          }
41126
41127          if (rotationMode) {
41128            parsedOrigin = target.ownerSVGElement ? [gsCache.xOrigin - target.getBBox().x, gsCache.yOrigin - target.getBBox().y] : (_getComputedStyle(target)[_transformOriginProp$1] || "0 0").split(" ");
41129            rotationOrigin = self.rotationOrigin = getGlobalMatrix(target).apply({
41130              x: parseFloat(parsedOrigin[0]) || 0,
41131              y: parseFloat(parsedOrigin[1]) || 0
41132            });
41133            syncXY(true, true);
41134            x = self.pointerX - rotationOrigin.x - offsetX;
41135            y = rotationOrigin.y - self.pointerY + offsetY;
41136            startElementX = self.x;
41137            startElementY = self.y = Math.atan2(y, x) * _RAD2DEG;
41138          } else {
41139            startElementY = getPropAsNum(yProp, "px");
41140            startElementX = getPropAsNum(xProp, "px");
41141          }
41142        }
41143
41144        if (hasBounds && edgeTolerance) {
41145          if (startElementX > maxX) {
41146            startElementX = maxX + (startElementX - maxX) / edgeTolerance;
41147          } else if (startElementX < minX) {
41148            startElementX = minX - (minX - startElementX) / edgeTolerance;
41149          }
41150
41151          if (!rotationMode) {
41152            if (startElementY > maxY) {
41153              startElementY = maxY + (startElementY - maxY) / edgeTolerance;
41154            } else if (startElementY < minY) {
41155              startElementY = minY - (minY - startElementY) / edgeTolerance;
41156            }
41157          }
41158        }
41159
41160        self.startX = startElementX = _round(startElementX);
41161        self.startY = startElementY = _round(startElementY);
41162      },
41163          isTweening = function isTweening() {
41164        return self.tween && self.tween.isActive();
41165      },
41166          removePlaceholder = function removePlaceholder() {
41167        if (_placeholderDiv.parentNode && !isTweening() && !self.isDragging) {
41168          _placeholderDiv.parentNode.removeChild(_placeholderDiv);
41169        }
41170      },
41171          onPress = function onPress(e, force) {
41172        var i;
41173
41174        if (!enabled || self.isPressed || !e || (e.type === "mousedown" || e.type === "pointerdown") && !force && _getTime() - clickTime < 30 && _touchEventLookup[self.pointerEvent.type]) {
41175          isPreventingDefault && e && enabled && _preventDefault(e);
41176          return;
41177        }
41178
41179        interrupted = isTweening();
41180        dragged = false;
41181        self.pointerEvent = e;
41182
41183        if (_touchEventLookup[e.type]) {
41184          touchEventTarget = ~e.type.indexOf("touch") ? e.currentTarget || e.target : ownerDoc;
41185
41186          _addListener(touchEventTarget, "touchend", onRelease);
41187
41188          _addListener(touchEventTarget, "touchmove", onMove);
41189
41190          _addListener(touchEventTarget, "touchcancel", onRelease);
41191
41192          _addListener(ownerDoc, "touchstart", _onMultiTouchDocument);
41193        } else {
41194          touchEventTarget = null;
41195
41196          _addListener(ownerDoc, "mousemove", onMove);
41197        }
41198
41199        touchDragAxis = null;
41200
41201        if (!_supportsPointer || !touchEventTarget) {
41202          _addListener(ownerDoc, "mouseup", onRelease);
41203
41204          e && e.target && _addListener(e.target, "mouseup", onRelease);
41205        }
41206
41207        isClicking = isClickable.call(self, e.target) && vars.dragClickables === false && !force;
41208
41209        if (isClicking) {
41210          _addListener(e.target, "change", onRelease);
41211
41212          _dispatchEvent(self, "pressInit", "onPressInit");
41213
41214          _dispatchEvent(self, "press", "onPress");
41215
41216          _setSelectable(triggers, true);
41217
41218          isPreventingDefault = false;
41219          return;
41220        }
41221
41222        allowNativeTouchScrolling = !touchEventTarget || allowX === allowY || self.vars.allowNativeTouchScrolling === false || self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2) ? false : allowX ? "y" : "x";
41223        isPreventingDefault = !allowNativeTouchScrolling && !self.allowEventDefault;
41224
41225        if (isPreventingDefault) {
41226          _preventDefault(e);
41227
41228          _addListener(_win$1, "touchforcechange", _preventDefault);
41229        }
41230
41231        if (e.changedTouches) {
41232          e = touch = e.changedTouches[0];
41233          touchID = e.identifier;
41234        } else if (e.pointerId) {
41235          touchID = e.pointerId;
41236        } else {
41237          touch = touchID = null;
41238        }
41239
41240        _dragCount++;
41241
41242        _addToRenderQueue(render);
41243
41244        startPointerY = self.pointerY = e.pageY;
41245        startPointerX = self.pointerX = e.pageX;
41246
41247        _dispatchEvent(self, "pressInit", "onPressInit");
41248
41249        if (allowNativeTouchScrolling || self.autoScroll) {
41250          _recordMaxScrolls(target.parentNode);
41251        }
41252
41253        if (target.parentNode && self.autoScroll && !scrollProxy && !rotationMode && target.parentNode._gsMaxScrollX && !_placeholderDiv.parentNode && !target.getBBox) {
41254          _placeholderDiv.style.width = target.parentNode.scrollWidth + "px";
41255          target.parentNode.appendChild(_placeholderDiv);
41256        }
41257
41258        recordStartPositions();
41259        self.tween && self.tween.kill();
41260        self.isThrowing = false;
41261        gsap.killTweensOf(scrollProxy || target, killProps, true);
41262        scrollProxy && gsap.killTweensOf(target, {
41263          scrollTo: 1
41264        }, true);
41265        self.tween = self.lockedAxis = null;
41266
41267        if (vars.zIndexBoost || !rotationMode && !scrollProxy && vars.zIndexBoost !== false) {
41268          target.style.zIndex = Draggable.zIndex++;
41269        }
41270
41271        self.isPressed = true;
41272        hasDragCallback = !!(vars.onDrag || self._listeners.drag);
41273        hasMoveCallback = !!(vars.onMove || self._listeners.move);
41274
41275        if (vars.cursor !== false || vars.activeCursor) {
41276          i = triggers.length;
41277
41278          while (--i > -1) {
41279            gsap.set(triggers[i], {
41280              cursor: vars.activeCursor || vars.cursor || (_defaultCursor === "grab" ? "grabbing" : _defaultCursor)
41281            });
41282          }
41283        }
41284
41285        _dispatchEvent(self, "press", "onPress");
vendor: 2,447 bytes, lines 41286-41353
41286      },
41287          onMove = function onMove(e) {
41288        var originalEvent = e,
41289            touches,
41290            pointerX,
41291            pointerY,
41292            i,
41293            dx,
41294            dy;
41295
41296        if (!enabled || _isMultiTouching || !self.isPressed || !e) {
41297          isPreventingDefault && e && enabled && _preventDefault(e);
41298          return;
41299        }
41300
41301        self.pointerEvent = e;
41302        touches = e.changedTouches;
41303
41304        if (touches) {
41305          e = touches[0];
41306
41307          if (e !== touch && e.identifier !== touchID) {
41308            i = touches.length;
41309
41310            while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {}
41311
41312            if (i < 0) {
41313              return;
41314            }
41315          }
41316        } else if (e.pointerId && touchID && e.pointerId !== touchID) {
41317          return;
41318        }
41319
41320        if (touchEventTarget && allowNativeTouchScrolling && !touchDragAxis) {
41321          _point1.x = e.pageX - (isFixed ? _getDocScrollLeft$1(ownerDoc) : 0);
41322          _point1.y = e.pageY - (isFixed ? _getDocScrollTop$1(ownerDoc) : 0);
41323          matrix && matrix.apply(_point1, _point1);
41324          pointerX = _point1.x;
41325          pointerY = _point1.y;
41326          dx = Math.abs(pointerX - startPointerX);
41327          dy = Math.abs(pointerY - startPointerY);
41328
41329          if (dx !== dy && (dx > minimumMovement || dy > minimumMovement) || _isAndroid && allowNativeTouchScrolling === touchDragAxis) {
41330            touchDragAxis = dx > dy && allowX ? "x" : "y";
41331
41332            if (allowNativeTouchScrolling && touchDragAxis !== allowNativeTouchScrolling) {
41333              _addListener(_win$1, "touchforcechange", _preventDefault);
41334            }
41335
41336            if (self.vars.lockAxisOnTouchScroll !== false && allowX && allowY) {
41337              self.lockedAxis = touchDragAxis === "x" ? "y" : "x";
41338              _isFunction(self.vars.onLockAxis) && self.vars.onLockAxis.call(self, originalEvent);
41339            }
41340
41341            if (_isAndroid && allowNativeTouchScrolling === touchDragAxis) {
41342              onRelease(originalEvent);
41343              return;
41344            }
41345          }
41346        }
41347
41348        if (!self.allowEventDefault && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling !== touchDragAxis) && originalEvent.cancelable !== false) {
41349          _preventDefault(originalEvent);
41350
41351          isPreventingDefault = true;
41352        } else if (isPreventingDefault) {
41353          isPreventingDefault = false;
vendor: 3,917 bytes, lines 41354-41482
41354        }
41355
41356        if (self.autoScroll) {
41357          checkAutoScrollBounds = true;
41358        }
41359
41360        setPointerPosition(e.pageX, e.pageY, hasMoveCallback);
41361      },
41362          setPointerPosition = function setPointerPosition(pointerX, pointerY, invokeOnMove) {
41363        var dragTolerance = 1 - self.dragResistance,
41364            edgeTolerance = 1 - self.edgeResistance,
41365            prevPointerX = self.pointerX,
41366            prevPointerY = self.pointerY,
41367            prevStartElementY = startElementY,
41368            prevX = self.x,
41369            prevY = self.y,
41370            prevEndX = self.endX,
41371            prevEndY = self.endY,
41372            prevEndRotation = self.endRotation,
41373            prevDirty = dirty,
41374            xChange,
41375            yChange,
41376            x,
41377            y,
41378            dif,
41379            temp;
41380        self.pointerX = pointerX;
41381        self.pointerY = pointerY;
41382
41383        if (isFixed) {
41384          pointerX -= _getDocScrollLeft$1(ownerDoc);
41385          pointerY -= _getDocScrollTop$1(ownerDoc);
41386        }
41387
41388        if (rotationMode) {
41389          y = Math.atan2(rotationOrigin.y - pointerY, pointerX - rotationOrigin.x) * _RAD2DEG;
41390          dif = self.y - y;
41391
41392          if (dif > 180) {
41393            startElementY -= 360;
41394            self.y = y;
41395          } else if (dif < -180) {
41396            startElementY += 360;
41397            self.y = y;
41398          }
41399
41400          if (self.x !== startElementX || Math.abs(startElementY - y) > minimumMovement) {
41401            self.y = y;
41402            x = startElementX + (startElementY - y) * dragTolerance;
41403          } else {
41404            x = startElementX;
41405          }
41406        } else {
41407          if (matrix) {
41408            temp = pointerX * matrix.a + pointerY * matrix.c + matrix.e;
41409            pointerY = pointerX * matrix.b + pointerY * matrix.d + matrix.f;
41410            pointerX = temp;
41411          }
41412
41413          yChange = pointerY - startPointerY;
41414          xChange = pointerX - startPointerX;
41415
41416          if (yChange < minimumMovement && yChange > -minimumMovement) {
41417            yChange = 0;
41418          }
41419
41420          if (xChange < minimumMovement && xChange > -minimumMovement) {
41421            xChange = 0;
41422          }
41423
41424          if ((self.lockAxis || self.lockedAxis) && (xChange || yChange)) {
41425            temp = self.lockedAxis;
41426
41427            if (!temp) {
41428              self.lockedAxis = temp = allowX && Math.abs(xChange) > Math.abs(yChange) ? "y" : allowY ? "x" : null;
41429
41430              if (temp && _isFunction(self.vars.onLockAxis)) {
41431                self.vars.onLockAxis.call(self, self.pointerEvent);
41432              }
41433            }
41434
41435            if (temp === "y") {
41436              yChange = 0;
41437            } else if (temp === "x") {
41438              xChange = 0;
41439            }
41440          }
41441
41442          x = _round(startElementX + xChange * dragTolerance);
41443          y = _round(startElementY + yChange * dragTolerance);
41444        }
41445
41446        if ((snapX || snapY || snapXY) && (self.x !== x || self.y !== y && !rotationMode)) {
41447          if (snapXY) {
41448            _temp1.x = x;
41449            _temp1.y = y;
41450            temp = snapXY(_temp1);
41451            x = _round(temp.x);
41452            y = _round(temp.y);
41453          }
41454
41455          if (snapX) {
41456            x = _round(snapX(x));
41457          }
41458
41459          if (snapY) {
41460            y = _round(snapY(y));
41461          }
41462        }
41463
41464        if (hasBounds) {
41465          if (x > maxX) {
41466            x = maxX + Math.round((x - maxX) * edgeTolerance);
41467          } else if (x < minX) {
41468            x = minX + Math.round((x - minX) * edgeTolerance);
41469          }
41470
41471          if (!rotationMode) {
41472            if (y > maxY) {
41473              y = Math.round(maxY + (y - maxY) * edgeTolerance);
41474            } else if (y < minY) {
41475              y = Math.round(minY + (y - minY) * edgeTolerance);
41476            }
41477          }
41478        }
41479
41480        if (self.x !== x || self.y !== y && !rotationMode) {
41481          if (rotationMode) {
41482            self.endRotation = self.x = self.endX = x
vendor: 13,666 bytes, lines 41482-41889
41482;
41483            dirty = true;
41484          } else {
41485            if (allowY) {
41486              self.y = self.endY = y;
41487              dirty = true;
41488            }
41489
41490            if (allowX) {
41491              self.x = self.endX = x;
41492              dirty = true;
41493            }
41494          }
41495
41496          if (!invokeOnMove || _dispatchEvent(self, "move", "onMove") !== false) {
41497            if (!self.isDragging && self.isPressed) {
41498              self.isDragging = dragged = true;
41499
41500              _dispatchEvent(self, "dragstart", "onDragStart");
41501            }
41502          } else {
41503            self.pointerX = prevPointerX;
41504            self.pointerY = prevPointerY;
41505            startElementY = prevStartElementY;
41506            self.x = prevX;
41507            self.y = prevY;
41508            self.endX = prevEndX;
41509            self.endY = prevEndY;
41510            self.endRotation = prevEndRotation;
41511            dirty = prevDirty;
41512          }
41513        }
41514      },
41515          onRelease = function onRelease(e, force) {
41516        if (!enabled || !self.isPressed || e && touchID != null && !force && (e.pointerId && e.pointerId !== touchID && e.target !== target || e.changedTouches && !_hasTouchID(e.changedTouches, touchID))) {
41517          isPreventingDefault && e && enabled && _preventDefault(e);
41518          return;
41519        }
41520
41521        self.isPressed = false;
41522        var originalEvent = e,
41523            wasDragging = self.isDragging,
41524            isContextMenuRelease = self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2),
41525            placeholderDelayedCall = gsap.delayedCall(0.001, removePlaceholder),
41526            touches,
41527            i,
41528            syntheticEvent,
41529            eventTarget,
41530            syntheticClick;
41531
41532        if (touchEventTarget) {
41533          _removeListener(touchEventTarget, "touchend", onRelease);
41534
41535          _removeListener(touchEventTarget, "touchmove", onMove);
41536
41537          _removeListener(touchEventTarget, "touchcancel", onRelease);
41538
41539          _removeListener(ownerDoc, "touchstart", _onMultiTouchDocument);
41540        } else {
41541          _removeListener(ownerDoc, "mousemove", onMove);
41542        }
41543
41544        _removeListener(_win$1, "touchforcechange", _preventDefault);
41545
41546        if (!_supportsPointer || !touchEventTarget) {
41547          _removeListener(ownerDoc, "mouseup", onRelease);
41548
41549          e && e.target && _removeListener(e.target, "mouseup", onRelease);
41550        }
41551
41552        dirty = false;
41553
41554        if (wasDragging) {
41555          dragEndTime = _lastDragTime = _getTime();
41556          self.isDragging = false;
41557        }
41558
41559        _removeFromRenderQueue(render);
41560
41561        if (isClicking && !isContextMenuRelease) {
41562          if (e) {
41563            _removeListener(e.target, "change", onRelease);
41564
41565            self.pointerEvent = originalEvent;
41566          }
41567
41568          _setSelectable(triggers, false);
41569
41570          _dispatchEvent(self, "release", "onRelease");
41571
41572          _dispatchEvent(self, "click", "onClick");
41573
41574          isClicking = false;
41575          return;
41576        }
41577
41578        i = triggers.length;
41579
41580        while (--i > -1) {
41581          _setStyle(triggers[i], "cursor", vars.cursor || (vars.cursor !== false ? _defaultCursor : null));
41582        }
41583
41584        _dragCount--;
41585
41586        if (e) {
41587          touches = e.changedTouches;
41588
41589          if (touches) {
41590            e = touches[0];
41591
41592            if (e !== touch && e.identifier !== touchID) {
41593              i = touches.length;
41594
41595              while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {}
41596
41597              if (i < 0 && !force) {
41598                return;
41599              }
41600            }
41601          }
41602
41603          self.pointerEvent = originalEvent;
41604          self.pointerX = e.pageX;
41605          self.pointerY = e.pageY;
41606        }
41607
41608        if (isContextMenuRelease && originalEvent) {
41609          _preventDefault(originalEvent);
41610
41611          isPreventingDefault = true;
41612
41613          _dispatchEvent(self, "release", "onRelease");
41614        } else if (originalEvent && !wasDragging) {
41615          isPreventingDefault = false;
41616
41617          if (interrupted && (vars.snap || vars.bounds)) {
41618            animate(vars.inertia || vars.throwProps);
41619          }
41620
41621          _dispatchEvent(self, "release", "onRelease");
41622
41623          if ((!_isAndroid || originalEvent.type !== "touchmove") && originalEvent.type.indexOf("cancel") === -1) {
41624            _dispatchEvent(self, "click", "onClick");
41625
41626            if (_getTime() - clickTime < 300) {
41627              _dispatchEvent(self, "doubleclick", "onDoubleClick");
41628            }
41629
41630            eventTarget = originalEvent.target || target;
41631            clickTime = _getTime();
41632
41633            syntheticClick = function syntheticClick() {
41634              if (clickTime !== clickDispatch && self.enabled() && !self.isPressed && !originalEvent.defaultPrevented) {
41635                if (eventTarget.click) {
41636                  eventTarget.click();
41637                } else if (ownerDoc.createEvent) {
41638                  syntheticEvent = ownerDoc.createEvent("MouseEvents");
41639                  syntheticEvent.initMouseEvent("click", true, true, _win$1, 1, self.pointerEvent.screenX, self.pointerEvent.screenY, self.pointerX, self.pointerY, false, false, false, false, 0, null);
41640                  eventTarget.dispatchEvent(syntheticEvent);
41641                }
41642              }
41643            };
41644
41645            if (!_isAndroid && !originalEvent.defaultPrevented) {
41646              gsap.delayedCall(0.05, syntheticClick);
41647            }
41648          }
41649        } else {
41650          animate(vars.inertia || vars.throwProps);
41651
41652          if (!self.allowEventDefault && originalEvent && (vars.dragClickables !== false || !isClickable.call(self, originalEvent.target)) && wasDragging && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling === touchDragAxis) && originalEvent.cancelable !== false) {
41653            isPreventingDefault = true;
41654
41655            _preventDefault(originalEvent);
41656          } else {
41657            isPreventingDefault = false;
41658          }
41659
41660          _dispatchEvent(self, "release", "onRelease");
41661        }
41662
41663        isTweening() && placeholderDelayedCall.duration(self.tween.duration());
41664        wasDragging && _dispatchEvent(self, "dragend", "onDragEnd");
41665        return true;
41666      },
41667          updateScroll = function updateScroll(e) {
41668        if (e && self.isDragging && !scrollProxy) {
41669          var parent = e.target || target.parentNode,
41670              deltaX = parent.scrollLeft - parent._gsScrollX,
41671              deltaY = parent.scrollTop - parent._gsScrollY;
41672
41673          if (deltaX || deltaY) {
41674            if (matrix) {
41675              startPointerX -= deltaX * matrix.a + deltaY * matrix.c;
41676              startPointerY -= deltaY * matrix.d + deltaX * matrix.b;
41677            } else {
41678              startPointerX -= deltaX;
41679              startPointerY -= deltaY;
41680            }
41681
41682            parent._gsScrollX += deltaX;
41683            parent._gsScrollY += deltaY;
41684            setPointerPosition(self.pointerX, self.pointerY);
41685          }
41686        }
41687      },
41688          onClick = function onClick(e) {
41689        var time = _getTime(),
41690            recentlyClicked = time - clickTime < 100,
41691            recentlyDragged = time - dragEndTime < 50,
41692            alreadyDispatched = recentlyClicked && clickDispatch === clickTime,
41693            defaultPrevented = self.pointerEvent && self.pointerEvent.defaultPrevented,
41694            alreadyDispatchedTrusted = recentlyClicked && trustedClickDispatch === clickTime,
41695            trusted = e.isTrusted || e.isTrusted == null && recentlyClicked && alreadyDispatched;
41696
41697        if ((alreadyDispatched || recentlyDragged && self.vars.suppressClickOnDrag !== false) && e.stopImmediatePropagation) {
41698          e.stopImmediatePropagation();
41699        }
41700
41701        if (recentlyClicked && !(self.pointerEvent && self.pointerEvent.defaultPrevented) && (!alreadyDispatched || trusted && !alreadyDispatchedTrusted)) {
41702          if (trusted && alreadyDispatched) {
41703            trustedClickDispatch = clickTime;
41704          }
41705
41706          clickDispatch = clickTime;
41707          return;
41708        }
41709
41710        if (self.isPressed || recentlyDragged || recentlyClicked) {
41711          if (!trusted || !e.detail || !recentlyClicked || defaultPrevented) {
41712            _preventDefault(e);
41713          }
41714        }
41715
41716        if (!recentlyClicked && !recentlyDragged && !dragged) {
41717          e && e.target && (self.pointerEvent = e);
41718
41719          _dispatchEvent(self, "click", "onClick");
41720        }
41721      },
41722          localizePoint = function localizePoint(p) {
41723        return matrix ? {
41724          x: p.x * matrix.a + p.y * matrix.c + matrix.e,
41725          y: p.x * matrix.b + p.y * matrix.d + matrix.f
41726        } : {
41727          x: p.x,
41728          y: p.y
41729        };
41730      };
41731
41732      old = Draggable.get(target);
41733      old && old.kill();
41734
41735      _this2.startDrag = function (event, align) {
41736        var r1, r2, p1, p2;
41737        onPress(event || self.pointerEvent, true);
41738
41739        if (align && !self.hitTest(event || self.pointerEvent)) {
41740          r1 = _parseRect(event || self.pointerEvent);
41741          r2 = _parseRect(target);
41742          p1 = localizePoint({
41743            x: r1.left + r1.width / 2,
41744            y: r1.top + r1.height / 2
41745          });
41746          p2 = localizePoint({
41747            x: r2.left + r2.width / 2,
41748            y: r2.top + r2.height / 2
41749          });
41750          startPointerX -= p1.x - p2.x;
41751          startPointerY -= p1.y - p2.y;
41752        }
41753
41754        if (!self.isDragging) {
41755          self.isDragging = dragged = true;
41756
41757          _dispatchEvent(self, "dragstart", "onDragStart");
41758        }
41759      };
41760
41761      _this2.drag = onMove;
41762
41763      _this2.endDrag = function (e) {
41764        return onRelease(e || self.pointerEvent, true);
41765      };
41766
41767      _this2.timeSinceDrag = function () {
41768        return self.isDragging ? 0 : (_getTime() - dragEndTime) / 1000;
41769      };
41770
41771      _this2.timeSinceClick = function () {
41772        return (_getTime() - clickTime) / 1000;
41773      };
41774
41775      _this2.hitTest = function (target, threshold) {
41776        return Draggable.hitTest(self.target, target, threshold);
41777      };
41778
41779      _this2.getDirection = function (from, diagonalThreshold) {
41780        var mode = from === "velocity" && InertiaPlugin ? from : _isObject(from) && !rotationMode ? "element" : "start",
41781            xChange,
41782            yChange,
41783            ratio,
41784            direction,
41785            r1,
41786            r2;
41787
41788        if (mode === "element") {
41789          r1 = _parseRect(self.target);
41790          r2 = _parseRect(from);
41791        }
41792
41793        xChange = mode === "start" ? self.x - startElementX : mode === "velocity" ? InertiaPlugin.getVelocity(target, xProp) : r1.left + r1.width / 2 - (r2.left + r2.width / 2);
41794
41795        if (rotationMode) {
41796          return xChange < 0 ? "counter-clockwise" : "clockwise";
41797        } else {
41798          diagonalThreshold = diagonalThreshold || 2;
41799          yChange = mode === "start" ? self.y - startElementY : mode === "velocity" ? InertiaPlugin.getVelocity(target, yProp) : r1.top + r1.height / 2 - (r2.top + r2.height / 2);
41800          ratio = Math.abs(xChange / yChange);
41801          direction = ratio < 1 / diagonalThreshold ? "" : xChange < 0 ? "left" : "right";
41802
41803          if (ratio < diagonalThreshold) {
41804            if (direction !== "") {
41805              direction += "-";
41806            }
41807
41808            direction += yChange < 0 ? "up" : "down";
41809          }
41810        }
41811
41812        return direction;
41813      };
41814
41815      _this2.applyBounds = function (newBounds, sticky) {
41816        var x, y, forceZeroVelocity, e, parent, isRoot;
41817
41818        if (newBounds && vars.bounds !== newBounds) {
41819          vars.bounds = newBounds;
41820          return self.update(true, sticky);
41821        }
41822
41823        syncXY(true);
41824        calculateBounds();
41825
41826        if (hasBounds && !isTweening()) {
41827          x = self.x;
41828          y = self.y;
41829
41830          if (x > maxX) {
41831            x = maxX;
41832          } else if (x < minX) {
41833            x = minX;
41834          }
41835
41836          if (y > maxY) {
41837            y = maxY;
41838          } else if (y < minY) {
41839            y = minY;
41840          }
41841
41842          if (self.x !== x || self.y !== y) {
41843            forceZeroVelocity = true;
41844            self.x = self.endX = x;
41845
41846            if (rotationMode) {
41847              self.endRotation = x;
41848            } else {
41849              self.y = self.endY = y;
41850            }
41851
41852            dirty = true;
41853            render(true);
41854
41855            if (self.autoScroll && !self.isDragging) {
41856              _recordMaxScrolls(target.parentNode);
41857
41858              e = target;
41859              _windowProxy.scrollTop = _win$1.pageYOffset != null ? _win$1.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop;
41860              _windowProxy.scrollLeft = _win$1.pageXOffset != null ? _win$1.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft;
41861
41862              while (e && !isRoot) {
41863                isRoot = _isRoot(e.parentNode);
41864                parent = isRoot ? _windowProxy : e.parentNode;
41865
41866                if (allowY && parent.scrollTop > parent._gsMaxScrollY) {
41867                  parent.scrollTop = parent._gsMaxScrollY;
41868                }
41869
41870                if (allowX && parent.scrollLeft > parent._gsMaxScrollX) {
41871                  parent.scrollLeft = parent._gsMaxScrollX;
41872                }
41873
41874                e = parent;
41875              }
41876            }
41877          }
41878
41879          if (self.isThrowing && (forceZeroVelocity || self.endX > maxX || self.endX < minX || self.endY > maxY || self.endY < minY)) {
41880            animate(vars.inertia || vars.throwProps, forceZeroVelocity);
41881          }
41882        }
41883
41884        return self;
41885      };
41886
41887      _this2.update = function (applyBounds, sticky, ignoreExternalChanges) {
41888        if (sticky && self.isPressed) {
41889          
vendor: 3,070 bytes, lines 41889-41990
41889var m = getGlobalMatrix(target),
41890              p = innerMatrix.apply({
41891            x: self.x - startElementX,
41892            y: self.y - startElementY
41893          }),
41894              m2 = getGlobalMatrix(target.parentNode, true);
41895          m2.apply({
41896            x: m.e - p.x,
41897            y: m.f - p.y
41898          }, p);
41899          self.x -= p.x - m2.e;
41900          self.y -= p.y - m2.f;
41901          render(true);
41902          recordStartPositions();
41903        }
41904
41905        var x = self.x,
41906            y = self.y;
41907        updateMatrix(!sticky);
41908
41909        if (applyBounds) {
41910          self.applyBounds();
41911        } else {
41912          dirty && ignoreExternalChanges && render(true);
41913          syncXY(true);
41914        }
41915
41916        if (sticky) {
41917          setPointerPosition(self.pointerX, self.pointerY);
41918          dirty && render(true);
41919        }
41920
41921        if (self.isPressed && !sticky && (allowX && Math.abs(x - self.x) > 0.01 || allowY && Math.abs(y - self.y) > 0.01 && !rotationMode)) {
41922          recordStartPositions();
41923        }
41924
41925        if (self.autoScroll) {
41926          _recordMaxScrolls(target.parentNode, self.isDragging);
41927
41928          checkAutoScrollBounds = self.isDragging;
41929          render(true);
41930
41931          _removeScrollListener(target, updateScroll);
41932
41933          _addScrollListener(target, updateScroll);
41934        }
41935
41936        return self;
41937      };
41938
41939      _this2.enable = function (type) {
41940        var setVars = {
41941          lazy: true
41942        },
41943            id,
41944            i,
41945            trigger;
41946
41947        if (vars.cursor !== false) {
41948          setVars.cursor = vars.cursor || _defaultCursor;
41949        }
41950
41951        if (gsap.utils.checkPrefix("touchCallout")) {
41952          setVars.touchCallout = "none";
41953        }
41954
41955        if (type !== "soft") {
41956          _setTouchActionForAllDescendants(triggers, allowX === allowY ? "none" : vars.allowNativeTouchScrolling && target.scrollHeight === target.clientHeight === (target.scrollWidth === target.clientHeight) || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x");
41957
41958          i = triggers.length;
41959
41960          while (--i > -1) {
41961            trigger = triggers[i];
41962            _supportsPointer || _addListener(trigger, "mousedown", onPress);
41963
41964            _addListener(trigger, "touchstart", onPress);
41965
41966            _addListener(trigger, "click", onClick, true);
41967
41968            gsap.set(trigger, setVars);
41969
41970            if (trigger.getBBox && trigger.ownerSVGElement && allowX !== allowY) {
41971              gsap.set(trigger.ownerSVGElement, {
41972                touchAction: vars.allowNativeTouchScrolling || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x"
41973              });
41974            }
41975
41976            vars.allowContextMenu || _addListener(trigger, "contextmenu", onContextMenu);
41977          }
41978
41979          _setSelectable(triggers, false);
41980        }
41981
41982        _addScrollListener(target, updateScroll);
41983
41984        enabled = true;
41985
41986        if (InertiaPlugin && type !== "soft") {
41987          InertiaPlugin.track(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left");
41988        }
41989
41990        target._gsDragID = id =
vendor: 5,466 bytes, lines 41990-42196
41990 "d" + _lookupCount++;
41991        _lookup[id] = self;
41992
41993        if (scrollProxy) {
41994          scrollProxy.enable();
41995          scrollProxy.element._gsDragID = id;
41996        }
41997
41998        (vars.bounds || rotationMode) && recordStartPositions();
41999        vars.bounds && self.applyBounds();
42000        return self;
42001      };
42002
42003      _this2.disable = function (type) {
42004        var dragging = self.isDragging,
42005            i = triggers.length,
42006            trigger;
42007
42008        while (--i > -1) {
42009          _setStyle(triggers[i], "cursor", null);
42010        }
42011
42012        if (type !== "soft") {
42013          _setTouchActionForAllDescendants(triggers, null);
42014
42015          i = triggers.length;
42016
42017          while (--i > -1) {
42018            trigger = triggers[i];
42019
42020            _setStyle(trigger, "touchCallout", null);
42021
42022            _removeListener(trigger, "mousedown", onPress);
42023
42024            _removeListener(trigger, "touchstart", onPress);
42025
42026            _removeListener(trigger, "click", onClick, true);
42027
42028            _removeListener(trigger, "contextmenu", onContextMenu);
42029          }
42030
42031          _setSelectable(triggers, true);
42032
42033          if (touchEventTarget) {
42034            _removeListener(touchEventTarget, "touchcancel", onRelease);
42035
42036            _removeListener(touchEventTarget, "touchend", onRelease);
42037
42038            _removeListener(touchEventTarget, "touchmove", onMove);
42039          }
42040
42041          _removeListener(ownerDoc, "mouseup", onRelease);
42042
42043          _removeListener(ownerDoc, "mousemove", onMove);
42044        }
42045
42046        _removeScrollListener(target, updateScroll);
42047
42048        enabled = false;
42049
42050        if (InertiaPlugin && type !== "soft") {
42051          InertiaPlugin.untrack(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left");
42052          self.tween && self.tween.kill();
42053        }
42054
42055        scrollProxy && scrollProxy.disable();
42056
42057        _removeFromRenderQueue(render);
42058
42059        self.isDragging = self.isPressed = isClicking = false;
42060        dragging && _dispatchEvent(self, "dragend", "onDragEnd");
42061        return self;
42062      };
42063
42064      _this2.enabled = function (value, type) {
42065        return arguments.length ? value ? self.enable(type) : self.disable(type) : enabled;
42066      };
42067
42068      _this2.kill = function () {
42069        self.isThrowing = false;
42070        self.tween && self.tween.kill();
42071        self.disable();
42072        gsap.set(triggers, {
42073          clearProps: "userSelect"
42074        });
42075        delete _lookup[target._gsDragID];
42076        return self;
42077      };
42078
42079      _this2.revert = function () {
42080        this.kill();
42081        this.styles && this.styles.revert();
42082      };
42083
42084      if (~type.indexOf("scroll")) {
42085        scrollProxy = _this2.scrollProxy = new ScrollProxy(target, _extend({
42086          onKill: function onKill() {
42087            self.isPressed && onRelease(null);
42088          }
42089        }, vars));
42090        target.style.overflowY = allowY && !_isTouchDevice ? "auto" : "hidden";
42091        target.style.overflowX = allowX && !_isTouchDevice ? "auto" : "hidden";
42092        target = scrollProxy.content;
42093      }
42094
42095      if (rotationMode) {
42096        killProps.rotation = 1;
42097      } else {
42098        if (allowX) {
42099          killProps[xProp] = 1;
42100        }
42101
42102        if (allowY) {
42103          killProps[yProp] = 1;
42104        }
42105      }
42106
42107      gsCache.force3D = "force3D" in vars ? vars.force3D : true;
42108
42109      _context(_assertThisInitialized(_this2));
42110
42111      _this2.enable();
42112
42113      return _this2;
42114    }
42115
42116    Draggable.register = function register(core) {
42117      gsap = core;
42118
42119      _initCore();
42120    };
42121
42122    Draggable.create = function create(targets, vars) {
42123      _coreInitted || _initCore(true);
42124      return _toArray(targets).map(function (target) {
42125        return new Draggable(target, vars);
42126      });
42127    };
42128
42129    Draggable.get = function get(target) {
42130      return _lookup[(_toArray(target)[0] || {})._gsDragID];
42131    };
42132
42133    Draggable.timeSinceDrag = function timeSinceDrag() {
42134      return (_getTime() - _lastDragTime) / 1000;
42135    };
42136
42137    Draggable.hitTest = function hitTest(obj1, obj2, threshold) {
42138      if (obj1 === obj2) {
42139        return false;
42140      }
42141
42142      var r1 = _parseRect(obj1),
42143          r2 = _parseRect(obj2),
42144          top = r1.top,
42145          left = r1.left,
42146          right = r1.right,
42147          bottom = r1.bottom,
42148          width = r1.width,
42149          height = r1.height,
42150          isOutside = r2.left > right || r2.right < left || r2.top > bottom || r2.bottom < top,
42151          overlap,
42152          area,
42153          isRatio;
42154
42155      if (isOutside || !threshold) {
42156        return !isOutside;
42157      }
42158
42159      isRatio = (threshold + "").indexOf("%") !== -1;
42160      threshold = parseFloat(threshold) || 0;
42161      overlap = {
42162        left: Math.max(left, r2.left),
42163        top: Math.max(top, r2.top)
42164      };
42165      overlap.width = Math.min(right, r2.right) - overlap.left;
42166      overlap.height = Math.min(bottom, r2.bottom) - overlap.top;
42167
42168      if (overlap.width < 0 || overlap.height < 0) {
42169        return false;
42170      }
42171
42172      if (isRatio) {
42173        threshold *= 0.01;
42174        area = overlap.width * overlap.height;
42175        return area >= width * height * threshold || area >= r2.width * r2.height * threshold;
42176      }
42177
42178      return overlap.width > threshold && overlap.height > threshold;
42179    };
42180
42181    return Draggable;
42182  }(EventDispatcher);
42183
42184  _setDefaults(Draggable.prototype, {
42185    pointerX: 0,
42186    pointerY: 0,
42187    startX: 0,
42188    startY: 0,
42189    deltaX: 0,
42190    deltaY: 0,
42191    isDragging: false,
42192    isPressed: false
42193  });
42194
42195  Draggable.zIndex = 1000;
42196  Draggable.version = "3.1
421962.5";
42197  _getGSAP() && gsap.registerPlugin(Draggable);
42198
42199  exports.Draggable = Draggable;
42200  exports.default = Draggable;
42201
42202  if (typeof(window) === 'undefined' || window !== exports) {Object.defineProperty(exports, '__esModule', { value: true });} else {delete window.default;}
42203
42204})));
42205/* ========================================================================
42206 * Bootstrap: collapse.js v3.1.1
42207 * http://getbootstrap.com/javascript/#collapse
42208 * ========================================================================
42209 * Copyright 2011-2014 Twitter, Inc.
42210 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42211 * ======================================================================== */
42212
42213
42214+function ($) {
42215	'use strict';
42216
42217	// COLLAPSE PUBLIC CLASS DEFINITION
42218	// ================================
42219
42220	var Collapse = function (element, options) {
42221		this.$element      = $(element)
42222		this.options       = $.extend({}, Collapse.DEFAULTS, options)
42223		this.transitioning = null
42224
42225		if (this.options.parent) this.$parent = $(this.options.parent)
42226		if (this.options.toggle) this.toggle()
42227	}
42228
42229	Collapse.DEFAULTS = {
42230		toggle: true
42231	}
42232
42233	Collapse.prototype.dimension = function () {
42234		var hasWidth = this.$element.hasClass('width')
42235		return hasWidth ? 'width' : 'height'
42236	}
42237
42238	Collapse.prototype.show = function () {
42239		if (this.transitioning || this.$element.hasClass('in')) return
42240
42241		var startEvent = $.Event('show.bs.collapse')
42242		this.$element.trigger(startEvent)
42243		if (startEvent.isDefaultPrevented()) return
42244
42245		var actives = this.$parent && this.$parent.find('> .panel > .in')
42246
42247		if (actives && actives.length) {
42248			var hasData = actives.data('bs.collapse')
42249			if (hasData && hasData.transitioning) return
42250			//START UNCODE EDIT
42251			var parentNoToggle = this.$parent.data('no-toggle')
42252			if (!parentNoToggle) {
42253				actives.collapse('hide')
42254			}
42255			//END UNCODE EDIT
42256			hasData || actives.data('bs.collapse', null)
42257		}
42258
42259		var dimension = this.dimension()
42260
42261		this.$element
42262			.removeClass('collapse')
42263			.addClass('collapsing')[dimension](0)
42264
42265		this.transitioning = 1
42266
42267		var complete = function (e) {
42268			if (e && e.target != this.$element[0]) return
42269			this.$element
42270				.removeClass('collapsing')
42271				.addClass('collapse in')[dimension]('auto')
42272			this.transitioning = 0
42273			this.$element.trigger('shown.bs.collapse')
42274		}
42275
42276		if (!$.support.transition) return complete.call(this)
42277
42278		var scrollSize = $.camelCase(['scroll', dimension].join('-'))
42279
42280		this.$element
42281			.one($.support.transition.end, $.proxy(complete, this))
42282			.emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
42283	}
42284
42285	Collapse.prototype.hide = function () {
42286		if (this.transitioning || !this.$element.hasClass('in')) return
42287
42288		var startEvent = $.Event('hide.bs.collapse')
42289		this.$element.trigger(startEvent)
42290		if (startEvent.isDefaultPrevented()) return
42291
42292		var dimension = this.dimension()
42293
42294		this.$element[dimension](this.$element[dimension]())[0].offsetHeight
42295
42296		this.$element
42297			.addClass('collapsing')
42298			.removeClass('collapse')
42299			.removeClass('in')
42300
42301		this.transitioning = 1
42302
42303		var complete = function (e) {
42304			if (e && e.target != this.$element[0]) return
42305			this.transitioning = 0
42306			this.$element
42307				.trigger('hidden.bs.collapse')
42308				.removeClass('collapsing')
42309				.addClass('collapse')
42310		}
42311
42312		if (!$.support.transition) return complete.call(this)
42313
42314		this.$element
42315			[dimension](0)
42316			.one($.support.transition.end, $.proxy(complete, this))
42317			.emulateTransitionEnd(350)
42318	}
42319
42320	Collapse.prototype.toggle = function () {
42321		this[this.$element.hasClass('in') ? 'hide' : 'show']()
42322	}
42323
42324
42325	// COLLAPSE PLUGIN DEFINITION
42326	// ==========================
42327
42328	var old = $.fn.collapse
42329
42330	$.fn.collapse = function (option) {
42331		return this.each(function () {
42332			var $this   = $(this)
42333			var data    = $this.data('bs.collapse')
42334			var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
42335
42336			if (!data && options.toggle && option == 'show') option = !option
42337			if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
42338			if (typeof option == 'string') data[option]()
42339		})
42340	}
42341
42342	$.fn.collapse.Constructor = Collapse
42343
42344
42345	// COLLAPSE NO CONFLICT
42346	// ====================
42347
42348	$.fn.collapse.noConflict = function () {
42349		$.fn.collapse = old
42350		return this
42351	}
42352
42353
42354	// COLLAPSE DATA-API
42355	// =================
42356
42357	$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
42358		var $this   = $(this), href
42359		var target  = $this.attr('data-target')
42360				|| e.preventDefault()
42361				|| (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
42362		//Edited by Uncode to replace ID in panel [START]
42363		var _target = href.replace(/^#/, "");
42364		if ( $('[data-id="' + _target + '"]').length ) {
42365			var $target = $('[data-id="' + _target + '"]')
42366		} else {
42367			var $target = $(target)
42368		}
42369		//Edited by Uncode to replace ID in panel [END]
42370		var data    = $target.data('bs.collapse')
42371		var option  = data ? 'toggle' : $this.data()
42372		var parent  = $this.attr('data-parent')
42373		var $parent = parent && $(parent)
42374
42375		if (!data || !data.transitioning) {
42376			if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
42377			$this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
42378		}
42379
42380		$target.collapse(option)
42381	})
42382
42383}(jQuery);
42384
42385/* ========================================================================
42386 * Bootstrap: tab.js v3.1.1
42387 * http://getbootstrap.com/javascript/#tabs
42388 * ========================================================================
42389 * Copyright 2011-2014 Twitter, Inc.
42390 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42391 * ======================================================================== */
42392
42393
42394+function ($) {
42395  'use strict';
42396
42397  // TAB CLASS DEFINITION
42398  // ====================
42399
42400  var Tab = function (element) {
42401    this.element = $(element)
42402  }
42403
42404  Tab.prototype.show = function () {
42405    var $this    = this.element
42406    var $ul      = $this.closest('ul:not(.dropdown-menu)')
42407    var selector = $this.data('target')
42408
42409    if (!selector) {
42410      selector = $this.attr('href')
42411      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
42412    }
42413
42414    if ($this.parent('li').hasClass('active')) return
42415
42416    var previous = $ul.find('.active:last a')[0]
42417    var e        = $.Event('show.bs.tab', {
42418      relatedTarget: previous
42419    })
42420
42421    $this.trigger(e)
42422
42423    if (e.isDefaultPrevented()) return
42424
42425    //Edited by Uncode to replace ID in panel [START]
42426    var _target = selector.replace(/^#/, "");
42427    if ( $('[data-id="' + _target + '"]').length )
42428      var $target = $('[data-id="' + _target + '"]')
42429    else
42430      var $target = $(selector)
42431    //Edited by Uncode to replace ID in panel [END]
42432
42433    this.activate($this.parent('li'), $ul)
42434    this.activate($target, $target.parent(), function () {
42435      $this.trigger({
42436        type: 'shown.bs.tab',
42437        relatedTarget: previous
42438      })
42439    })
42440  }
42441
42442  Tab.prototype.activate = function (element, container, callback) {
42443    var $active    = container.find('> .active').add(container.find('> .active > .active'))
42444    var transition = callback
42445      && $.support.transition
42446      && $active.hasClass('fade')
42447
42448    function next() {
42449      $active
42450        .removeClass('active')
42451        .find('> .dropdown-menu > .active')
42452        .removeClass('active')
42453
42454      $active
42455        .find('.tab-excerpt').slideUp();
42456
42457      element.addClass('active')
42458      $('.tab-excerpt', element).slideDown();
42459
42460      //if (transition) {
42461        element[0].offsetWidth // reflow for transition
42462        element.add($active).addClass('in')
42463      /*} else {
42464        element.removeClass('fade')
42465      }*/
42466
42467      if (element.parents('.dropdown-menu').length) {
42468        element.closest('li.dropdown').addClass('active')
42469      }
42470
42471      if ( ! element.is('li') ) {
42472        element.closest('.tab-content').find('> .active').not(element).removeClass('active');
42473      }
42474
42475      callback && callback()
42476    }
42477
42478    transition ? 
42479      $active
42480        .one($.support.transition.end, next)
42481        .emulateTransitionEnd(150) :
42482      next()
42483
42484    $active.removeClass('in')
42485  }
42486
42487
42488  // TAB PLUGIN DEFINITION
42489  // =====================
42490
42491  var old = $.fn.tab
42492
42493  $.fn.tab = function ( option ) {
42494    return this.each(function () {
42495      var $this = $(this)
42496      var data  = $this.data('bs.tab')
42497
42498      if (!data) $this.data('bs.tab', (data = new Tab(this)))
42499      if (typeof option == 'string') data[option]()
42500    })
42501  }
42502
42503  $.fn.tab.Constructor = Tab
42504
42505
42506  // TAB NO CONFLICT
42507  // ===============
42508
42509  $.fn.tab.noConflict = function () {
42510    $.fn.tab = old
42511    return this
42512  }
42513
42514
42515  // TAB DATA-API
42516  // ============
42517
42518  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
42519    e.preventDefault()
42520    $(this).tab('show')
42521  })
42522
42523}(jQuery);
42524
42525/* ========================================================================
42526 * Bootstrap: tooltip.js v3.1.1
42527 * http://getbootstrap.com/javascript/#tooltip
42528 * Inspired by the original jQuery.tipsy by Jason Frame
42529 * ========================================================================
42530 * Copyright 2011-2014 Twitter, Inc.
42531 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42532 * ======================================================================== */
42533
42534
42535+function ($) {
42536  'use strict';
42537
42538  // TOOLTIP PUBLIC CLASS DEFINITION
42539  // ===============================
42540
42541  var Tooltip = function (element, options) {
42542    this.type       =
42543    this.options    =
42544    this.enabled    =
42545    this.timeout    =
42546    this.hoverState =
42547    this.$element   = null
42548
42549    this.init('tooltip', element, options)
42550  }
42551
42552  Tooltip.DEFAULTS = {
42553    animation: true,
42554    placement: 'top',
42555    selector: false,
42556    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
42557    trigger: 'hover focus',
42558    title: '',
42559    delay: 0,
42560    html: false,
42561    container: false,
42562    viewport: {
42563      selector: 'body',
42564      padding: 0
42565    }
42566  }
42567
42568  Tooltip.prototype.init = function (type, element, options) {
42569    this.enabled   = true
42570    this.type      = type
42571    this.$element  = $(element)
42572    this.options   = this.getOptions(options)
42573    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
42574
42575    var triggers = this.options.trigger.split(' ')
42576
42577    for (var i = triggers.length; i--;) {
42578      var trigger = triggers[i]
42579
42580      if (trigger == 'click') {
42581        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
42582      } else if (trigger != 'manual') {
42583        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
42584        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
42585
42586        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
42587        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
42588      }
42589    }
42590
42591    this.options.selector ?
42592      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
42593      this.fixTitle()
42594  }
42595
42596  Tooltip.prototype.getDefaults = function () {
42597    return Tooltip.DEFAULTS
42598  }
42599
42600  Tooltip.prototype.getOptions = function (options) {
42601    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
42602
42603    if (options.delay && typeof options.delay == 'number') {
42604      options.delay = {
42605        show: options.delay,
42606        hide: options.delay
42607      }
42608    }
42609
42610    return options
42611  }
42612
42613  Tooltip.prototype.getDelegateOptions = function () {
42614    var options  = {}
42615    var defaults = this.getDefaults()
42616
42617    this._options && $.each(this._options, function (key, value) {
42618      if (defaults[key] != value) options[key] = value
42619    })
42620
42621    return options
42622  }
42623
42624  Tooltip.prototype.enter = function (obj) {
42625    var self = obj instanceof this.constructor ?
42626      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
42627
42628    clearTimeout(self.timeout)
42629
42630    self.hoverState = 'in'
42631
42632    if (!self.options.delay || !self.options.delay.show) return self.show()
42633
42634    self.timeout = setTimeout(function () {
42635      if (self.hoverState == 'in') self.show()
42636    }, self.options.delay.show)
42637  }
42638
42639  Tooltip.prototype.leave = function (obj) {
42640    var self = obj instanceof this.constructor ?
42641      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
42642
42643    clearTimeout(self.timeout)
42644
42645    self.hoverState = 'out'
42646
42647    if (!self.options.delay || !self.options.delay.hide) return self.hide()
42648
42649    self.timeout = setTimeout(function () {
42650      if (self.hoverState == 'out') self.hide()
42651    }, self.options.delay.hide)
42652  }
42653
42654  Tooltip.prototype.show = function () {
42655    var e = $.Event('show.bs.' + this.type)
42656
42657    if (this.hasContent() && this.enabled) {
42658      this.$element.trigger(e)
42659
42660      if (e.isDefaultPrevented()) return
42661      var that = this;
42662
42663      var $tip = this.tip()
42664
42665      this.setContent()
42666
42667      if (this.options.animation) $tip.addClass('fade')
42668
42669      var placement = typeof this.options.placement == 'function' ?
42670        this.options.placement.call(this, $tip[0], this.$element[0]) :
42671        this.options.placement
42672
42673      var autoToken = /\s?auto?\s?/i
42674      var autoPlace = autoToken.test(placement)
42675      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
42676
42677      $tip
42678        .detach()
42679        .css({ top: 0, left: 0, display: 'block' })
42680        .addClass(placement)
42681
42682      this.options.container ? $tip.appendTo($(document).find(this.options.container)) : $tip.insertAfter(this.$element)
42683
42684      var pos          = this.getPosition()
42685      var actualWidth  = $tip[0].offsetWidth
42686      var actualHeight = $tip[0].offsetHeight
42687
42688      if (autoPlace) {
42689        var orgPlacement = placement
42690        var $parent      = this.$element.parent()
42691        var parentDim    = this.getPosition($parent)
42692
42693        placement = placement == 'bottom' && pos.top   + pos.height       + actualHeight - parentDim.scroll > parentDim.height ? 'top'    :
42694                    placement == 'top'    && pos.top   - parentDim.scroll - actualHeight < 0                                   ? 'bottom' :
42695                    placement == 'right'  && pos.right + actualWidth      > parentDim.width                                    ? 'left'   :
42696                    placement == 'left'   && pos.left  - actualWidth      < parentDim.left                                     ? 'right'  :
42697                    placement
42698
42699        $tip
42700          .removeClass(orgPlacement)
42701          .addClass(placement)
42702      }
42703
42704      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
42705
42706      this.applyPlacement(calculatedOffset, placement)
42707      this.hoverState = null
42708
42709      var complete = function() {
42710        that.$element.trigger('shown.bs.' + that.type)
42711      }
42712
42713      $.support.transition && this.$tip.hasClass('fade') ?
42714        $tip
42715          .one($.support.transition.end, complete)
42716          .emulateTransitionEnd(150) :
42717        complete()
42718    }
42719  }
42720
42721  Tooltip.prototype.applyPlacement = function (offset, placement) {
42722    var $tip   = this.tip()
42723    var width  = $tip[0].offsetWidth
42724    var height = $tip[0].offsetHeight
42725
42726    // manually read margins because getBoundingClientRect includes difference
42727    var marginTop = parseInt($tip.css('margin-top'), 10)
42728    var marginLeft = parseInt($tip.css('margin-left'), 10)
42729
42730    // we must check for NaN for ie 8/9
42731    if (isNaN(marginTop))  marginTop  = 0
42732    if (isNaN(marginLeft)) marginLeft = 0
42733
42734    offset.top  = offset.top  + marginTop
42735    offset.left = offset.left + marginLeft
42736
42737    // $.fn.offset doesn't round pixel values
42738    // so we use setOffset directly with our own function B-0
42739    $.offset.setOffset($tip[0], $.extend({
42740      using: function (props) {
42741        $tip.css({
42742          top: Math.round(props.top),
42743          left: Math.round(props.left)
42744        })
42745      }
42746    }, offset), 0)
42747
42748    $tip.addClass('in')
42749
42750    // check to see if placing tip in new offset caused the tip to resize itself
42751    var actualWidth  = $tip[0].offsetWidth
42752    var actualHeight = $tip[0].offsetHeight
42753
42754    if (placement == 'top' && actualHeight != height) {
42755      offset.top = offset.top + height - actualHeight
42756    }
42757
42758    var delta = this.getViewportAdjustedDelta(placement, offset, actualWid
42758th, actualHeight)
42759
42760    if (delta.left) offset.left += delta.left
42761    else offset.top += delta.top
42762
42763    var arrowDelta          = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
42764    var arrowPosition       = delta.left ? 'left'        : 'top'
42765    var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
42766
42767    $tip.offset(offset)
42768    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
42769  }
42770
42771  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
42772    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
42773  }
42774
42775  Tooltip.prototype.setContent = function () {
42776    var $tip  = this.tip()
42777    var title = this.getTitle()
42778
42779    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
42780    $tip.removeClass('fade in top bottom left right')
42781  }
42782
42783  Tooltip.prototype.hide = function () {
42784    var that = this
42785    var $tip = this.tip()
42786    var e    = $.Event('hide.bs.' + this.type)
42787
42788    function complete() {
42789      if (that.hoverState != 'in') $tip.detach()
42790      that.$element.trigger('hidden.bs.' + that.type)
42791    }
42792
42793    this.$element.trigger(e)
42794
42795    if (e.isDefaultPrevented()) return
42796
42797    $tip.removeClass('in')
42798
42799    $.support.transition && this.$tip.hasClass('fade') ?
42800      $tip
42801        .one($.support.transition.end, complete)
42802        .emulateTransitionEnd(150) :
42803      complete()
42804
42805    this.hoverState = null
42806
42807    return this
42808  }
42809
42810  Tooltip.prototype.fixTitle = function () {
42811    var $e = this.$element
42812    if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
42813      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
42814    }
42815  }
42816
42817  Tooltip.prototype.hasContent = function () {
42818    return this.getTitle()
42819  }
42820
42821  Tooltip.prototype.getPosition = function ($element) {
42822    $element   = $element || this.$element
42823    var el     = $element[0]
42824    var isBody = el.tagName == 'BODY'
42825    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
42826      scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
42827      width:  isBody ? $(window).width()  : $element.outerWidth(),
42828      height: isBody ? $(window).height() : $element.outerHeight()
42829    }, isBody ? {top: 0, left: 0} : $element.offset())
42830  }
42831
42832  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
42833    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
42834           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
42835           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
42836        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
42837
42838  }
42839
42840  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
42841    var delta = { top: 0, left: 0 }
42842    if (!this.$viewport) return delta
42843
42844    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
42845    var viewportDimensions = this.getPosition(this.$viewport)
42846
42847    if (/right|left/.test(placement)) {
42848      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
42849      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
42850      if (topEdgeOffset < viewportDimensions.top) { // top overflow
42851        delta.top = viewportDimensions.top - topEdgeOffset
42852      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
42853        delta.top = viewportDimensions.top + viewportDimensions.height - bottom
42853EdgeOffset
42854      }
42855    } else {
42856      var leftEdgeOffset  = pos.left - viewportPadding
42857      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
42858      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
42859        delta.left = viewportDimensions.left - leftEdgeOffset
42860      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
42861        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
42862      }
42863    }
42864
42865    return delta
42866  }
42867
42868  Tooltip.prototype.getTitle = function () {
42869    var title
42870    var $e = this.$element
42871    var o  = this.options
42872
42873    title = $e.attr('data-original-title')
42874      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
42875
42876    return title
42877  }
42878
42879  Tooltip.prototype.tip = function () {
42880    return this.$tip = this.$tip || $(this.options.template)
42881  }
42882
42883  Tooltip.prototype.arrow = function () {
42884    return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
42885  }
42886
42887  Tooltip.prototype.validate = function () {
42888    if (!this.$element[0].parentNode) {
42889      this.hide()
42890      this.$element = null
42891      this.options  = null
42892    }
42893  }
42894
42895  Tooltip.prototype.enable = function () {
42896    this.enabled = true
42897  }
42898
42899  Tooltip.prototype.disable = function () {
42900    this.enabled = false
42901  }
42902
42903  Tooltip.prototype.toggleEnabled = function () {
42904    this.enabled = !this.enabled
42905  }
42906
42907  Tooltip.prototype.toggle = function (e) {
42908    var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
42909    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
42910  }
42911
42912  Tooltip.prototype.destroy = function () {
42913    clearTimeout(this.timeout)
42914    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
42915  }
42916
42917
42918  // TOOLTIP PLUGIN DEFINITION
42919  // =========================
42920
42921  var old = $.fn.tooltip
42922
42923  $.fn.tooltip = function (option) {
42924    return this.each(function () {
42925      var $this   = $(this)
42926      var data    = $this.data('bs.tooltip')
42927      var options = typeof option == 'object' && option
42928
42929      if (!data && option == 'destroy') return
42930      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
42931      if (typeof option == 'string') data[option]()
42932    })
42933  }
42934
42935  $.fn.tooltip.Constructor = Tooltip
42936
42937
42938  // TOOLTIP NO CONFLICT
42939  // ===================
42940
42941  $.fn.tooltip.noConflict = function () {
42942    $.fn.tooltip = old
42943    return this
42944  }
42945
42946}(jQuery);
42947
42948/* ========================================================================
42949 * Bootstrap: transition.js v3.1.1
42950 * http://getbootstrap.com/javascript/#transitions
42951 * ========================================================================
42952 * Copyright 2011-2014 Twitter, Inc.
42953 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
42954 * ======================================================================== */
42955
42956
42957+function ($) {
42958  'use strict';
42959
42960  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
42961  // ============================================================
42962
42963  function transitionEnd() {
42964    var el = document.createElement('bootstrap')
42965
42966    var transEndEventNames = {
42967      WebkitTransition : 'webkitTransitionEnd',
42968      MozTransition    : 'transitionend',
42969      OTransition      : 'oTransitionEnd otransitionend',
42970      transition       : 'transitionend'
42971    }
42972
42973    for (var name in transEndEventNames) {
42974      if (el.style[name] !== undefined) {
42975        return { end: transEndEventNames[name] }
42976      }
42977    }
42978
42979    return false // explicit for ie8 (  ._.)
42980  }
42981
42982  // http://blog.alexmaccaw.com/css-transitions
42983  $.fn.emulateTransitionEnd = function (duration) {
42984    var called = false, $el = this
42985    $(this).one($.support.transition.end, function () { called = true })
42986    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
42987    setTimeout(callback, duration)
42988    return this
42989  }
42990
42991  $(function () {
42992    $.support.transition = transitionEnd()
42993  })
42994
42995}(jQuery);
42996
42997
42998// ------------------------------------------
42999// Rellax.js
43000// Buttery smooth parallax library
43001// Copyright (c) 2016 Moe Amaya (@moeamaya)
43002// MIT license
43003//
43004// Thanks to Paraxify.js and Jaime Cabllero
43005// for parallax concepts
43006// ------------------------------------------
43007
43008(function (root, factory) {
43009	if (typeof define === 'function' && define.amd) {
43010		// AMD. Register as an anonymous module.
43011		define([], factory);
43012	} else if (typeof module === 'object' && module.exports) {
43013		// Node. Does not work with strict CommonJS, but
43014		// only CommonJS-like environments that support module.exports,
43015		// like Node.
43016		module.exports = factory();
43017	} else {
43018		// Browser globals (root is window)
43019		root.Rellax = factory();
43020	}
43021}(typeof window !== "undefined" ? window : global, function () {
43022	var Rellax = function(el, options){
43023		"use strict";
43024
43025		var self = Object.create(Rellax.prototype);
43026
43027		var posY = 0;
43028		var screenY = 0;
43029		var posX = 0;
43030		var screenX = 0;
43031		var blocks = [];
43032		var pause = true;
43033
43034		// check what requestAnimationFrame to use, and if
43035		// it's not supported, use the onscroll event
43036		var loop = window.requestAnimationFrame ||
43037			window.webkitRequestAnimationFrame ||
43038			window.mozRequestAnimationFrame ||
43039			window.msRequestAnimationFrame ||
43040			window.oRequestAnimationFrame ||
43041			function(callback){ return setTimeout(callback, 1000 / 60); };
43042
43043		// store the id for later use
43044		var loopId = null;
43045
43046		// Test via a getter in the options object to see if the passive property is accessed
43047		var supportsPassive = false;
vendor: 10,724 bytes, lines 43048-43349
43048		try {
43049			var opts = Object.defineProperty({}, 'passive', {
43050				get: function() {
43051					supportsPassive = true;
43052				}
43053			});
43054			window.addEventListener("testPassive", null, opts);
43055			window.removeEventListener("testPassive", null, opts);
43056		} catch (e) {}
43057
43058		// check what cancelAnimation method to use
43059		var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout;
43060
43061		// check which transform property to use
43062		var transformProp = window.transformProp || (function(){
43063				var testEl = document.createElement('div');
43064				if (testEl.style.transform === null) {
43065					var vendors = ['Webkit', 'Moz', 'ms'];
43066					for (var vendor in vendors) {
43067						if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) {
43068							return vendors[vendor] + 'Transform';
43069						}
43070					}
43071				}
43072				return 'transform';
43073			})();
43074
43075		// Default Settings
43076		self.options = {
43077			speed: -2,
43078			verticalSpeed: null,
43079			horizontalSpeed: null,
43080			breakpoints: [576, 768, 1201],
43081			center: false,
43082			wrapper: null,
43083			relativeToWrapper: false,
43084			round: true,
43085			vertical: true,
43086			horizontal: false,
43087			verticalScrollAxis: "y",
43088			horizontalScrollAxis: "x",
43089			callback: function() {},
43090		};
43091
43092		// User defined options (might have more in the future)
43093		if (options){
43094			Object.keys(options).forEach(function(key){
43095				self.options[key] = options[key];
43096			});
43097		}
43098
43099		function validateCustomBreakpoints () {
43100			if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) {
43101				var isAscending = true;
43102				var isNumerical = true;
43103				var lastVal;
43104				self.options.breakpoints.forEach(function (i) {
43105					if (typeof i !== 'number') isNumerical = false;
43106					if (lastVal !== null) {
43107						if (i < lastVal) isAscending = false;
43108					}
43109					lastVal = i;
43110				});
43111				if (isAscending && isNumerical) return;
43112			}
43113			// revert defaults if set incorrectly
43114			self.options.breakpoints = [576, 768, 1201];
43115			console.warn("Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted");
43116		}
43117
43118		if (options && options.breakpoints) {
43119			validateCustomBreakpoints();
43120		}
43121
43122		// By default, rellax class
43123		if (!el) {
43124			el = '.rellax';
43125		}
43126
43127		// check if el is a className or a node
43128		var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el];
43129
43130		// Now query selector
43131		if (elements.length > 0) {
43132			self.elems = elements;
43133		}
43134
43135		// The elements don't exist
43136		else {
43137			console.warn("Rellax: The elements you're trying to select don't exist.");
43138			return;
43139		}
43140
43141		// Has a wrapper and it exists
43142		if (self.options.wrapper) {
43143			if (!self.options.wrapper.nodeType) {
43144				var wrapper = document.querySelector(self.options.wrapper);
43145
43146				if (wrapper) {
43147					self.options.wrapper = wrapper;
43148				} else {
43149					console.warn("Rellax: The wrapper you're trying to use doesn't exist.");
43150					return;
43151				}
43152			}
43153		}
43154
43155		// set a placeholder for the current breakpoint
43156		var currentBreakpoint;
43157
43158		// helper to determine current breakpoint
43159		var getCurrentBreakpoint = function (w) {
43160			var bp = self.options.breakpoints;
43161			if (w < bp[0]) return 'xs';
43162			if (w >= bp[0] && w < bp[1]) return 'sm';
43163			if (w >= bp[1] && w < bp[2]) return 'md';
43164			return 'lg';
43165		};
43166
43167		// Get and cache initial position of all elements
43168		var cacheBlocks = function() {
43169			for (var i = 0; i < self.elems.length; i++){
43170				var block = createBlock(self.elems[i]);
43171				blocks.push(block);
43172			}
43173		};
43174
43175
43176		// Let's kick this script off
43177		// Build array for cached element values
43178		var init = function() {
43179			for (var i = 0; i < blocks.length; i++){
43180				self.elems[i].style.cssText = blocks[i].style;
43181			}
43182
43183			blocks = [];
43184
43185			screenY = window.innerHeight;
43186			screenX = window.innerWidth;
43187			currentBreakpoint = getCurrentBreakpoint(screenX);
43188
43189			setPosition();
43190
43191			cacheBlocks();
43192
43193			animate();
43194
43195			// If paused, unpause and set listener for window resizing events
43196			if (pause) {
43197				window.addEventListener('resize', init);
43198				pause = false;
43199				// Start the loop
43200				update();
43201			}
43202		};
43203
43204		// We want to cache the parallax blocks'
43205		// values: base, top, height, speed
43206		// el: is dom object, return: el cache values
43207		var createBlock = function(el) {
43208			var dataPercentage = el.getAttribute( 'data-rellax-percentage' );
43209			var dataSpeed = el.getAttribute( 'data-rellax-speed' );
43210			var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' );
43211			var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' );
43212			var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' );
43213			var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' );
43214			var dataVerticalSpeed = el.getAttribute('data-rellax-vertical-speed');
43215			var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed');
43216			var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis');
43217			var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis');
43218			var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0;
43219			var dataMin = el.getAttribute( 'data-rellax-min' );
43220			var dataMax = el.getAttribute( 'data-rellax-max' );
43221			var dataMinX = el.getAttribute('data-rellax-min-x');
43222			var dataMaxX = el.getAttribute('data-rellax-max-x');
43223			var dataMinY = el.getAttribute('data-rellax-min-y');
43224			var dataMaxY = el.getAttribute('data-rellax-max-y');
43225			var mapBreakpoints;
43226			var breakpoints = true;
43227
43228			if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) {
43229				breakpoints = false;
43230			} else {
43231				mapBreakpoints = {
43232					'xs': dataXsSpeed,
43233					'sm': dataMobileSpeed,
43234					'md': dataTabletSpeed,
43235					'lg': dataDesktopSpeed
43236				};
43237			}
43238
43239			// initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser)
43240			// ensures elements are positioned based on HTML layout.
43241			//
43242			// If the element has the percentage attribute, the posY and posX needs to be
43243			// the current scroll position's value, so that the elements are still positioned based on HTML layout
43244			var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
43245			// If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll.
43246			if (self.options.relativeToWrapper) {
43247				var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
43248				wrapperPosY = scrollPosY - self.options.wrapper.offsetTop;
43249			}
43250			var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0;
43251			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;
43252
43253			var blockTop = posY + el.getBoundingClientRect().top;
43254			var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight;
43255
43256			var blockLeft = posX + el.getBoundingClientRect().left;
43257			var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth;
43258
43259			// apparently parallax equation everyone uses
43260			var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY);
43261			var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX);
43262			if(self.options.center){ percentageX = 0.5; percentageY = 0.5; }
43263
43264			// Optional individual block speed as data attr, otherwise global speed
43265			var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed);
43266			var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed;
43267			var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed;
43268
43269			// Optional individual block movement axis direction as data attr, otherwise global movement direction
43270			var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis;
43271			var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis;
43272
43273			var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed);
43274
43275			// ~~Store non-translate3d transforms~~
43276			// Store inline styles and extract transforms
43277			var style = el.style.cssText;
43278			var transform = '';
43279
43280			// Check if there's an inline styled transform
43281			var searchResult = /transform\s*:/i.exec(style);
43282			if (searchResult) {
43283				// Get the index of the transform
43284				var index = searchResult.index;
43285
43286				// Trim the style to the transform point and get the following semi-colon index
43287				var trimmedStyle = style.slice(index);
43288				var delimiter = trimmedStyle.indexOf(';');
43289
43290				// Remove "transform" string and save the attribute
43291				if (delimiter) {
43292					transform = " " + trimmedStyle.slice(11, delimiter).replace(/\s/g,'');
43293				} else {
43294					transform = " " + trimmedStyle.slice(11).replace(/\s/g,'');
43295				}
43296			}
43297
43298			return {
43299				baseX: bases.x,
43300				baseY: bases.y,
43301				top: blockTop,
43302				left: blockLeft,
43303				height: blockHeight,
43304				width: blockWidth,
43305				speed: speed,
43306				verticalSpeed: verticalSpeed,
43307				horizontalSpeed: horizontalSpeed,
43308				verticalScrollAxis: verticalScrollAxis,
43309				horizontalScrollAxis: horizontalScrollAxis,
43310				style: style,
43311				transform: transform,
43312				zindex: dataZindex,
43313				min: dataMin,
43314				max: dataMax,
43315				minX: dataMinX,
43316				maxX: dataMaxX,
43317				minY: dataMinY,
43318				maxY: dataMaxY
43319			};
43320		};
43321
43322		// set scroll position (posY, posX)
43323		// side effect method is not ideal, but okay for now
43324		// returns true if the scroll changed, false if nothing happened
43325		var setPosition = function() {
43326			var oldY = posY;
43327			var oldX = posX;
43328
43329			posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset;
43330			posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset;
43331			// If option relativeToWrapper is true, use relative wrapper value instead.
43332			if (self.options.relativeToWrapper) {
43333				var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset;
43334				posY = scrollPosY - self.options.wrapper.offsetTop;
43335			}
43336
43337
43338			if (oldY != posY && self.options.vertical) {
43339				// scroll changed, return true
43340				return true;
43341			}
43342
43343			if (oldX != posX && self.options.horizontal) {
43344				// scroll changed, return true
43345				return true;
43346			}
43347
43348			// scroll did not change
43349			return false;
43350		};
43351
43352		// Ahh a pure function, gets new transform value
43353		// based on scrollPosition and speed
43354		// Allow for decimal pixel values
43355		var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) {
43356			var result = {};
43357			var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX)));
43358			var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY)));
43359
43360			result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100;
43361			result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100;
43362
43363			return result;
43364		};
43365
43366		// Remove event listeners and loop again
43367		var deferredUpdate = function() {
43368			window.removeEventListener('resize', deferredUpdate);
43369			window.removeEventListener('orientationchange', deferredUpdate);
43370			(self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate);
43371			(self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate);
43372
43373			// loop again
43374			loopId = loop(update);
43375		};
43376
43377		// Loop
43378		var update = function() {
43379			if (setPosition() && pause === false) {
43380				animate();
43381
43382				// loop again
43383				loopId = loop(update);
43384			} else {
43385				loopId = null;
43386
43387				// Don't animate until we get a position updating event
43388				window.addEventListener('resize', deferredUpdate);
43389				window.addEventListener('orientationchange', deferredUpdate);
43390				(self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false);
43391				(self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false);
43392			}
43393		};
43394
43395		// Transform3d on parallax element
43396		var animate = function() {
43397			var positions;
43398			for (var i = 0; i < self.elems.length; i++){
43399				// Determine relevant movement directions
43400				var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase();
43401				var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase();
43402				var verticalScrollX = verticalScrollAxis.indexOf("x") != -1 ? posY : 0;
43403				var verticalScrollY = verticalScrollAxis.indexOf("y") != -1 ? posY : 0;
43404				var horizontalScrollX = horizontalScrollAxis.indexOf("x") != -1 ? posX : 0;
43405				var horizontalScrollY = horizontalScrollAxis.indexOf("y") != -1 ? posX : 0;
43406
43407				var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY));
43408				var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX));
43409
43410				// Subtracting initialize value, so element stays in same spot as HTML
43411				positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed);
43412				var positionY = positions.y - blocks[i].baseY;
43413				var positionX = positions.x - blocks[i].baseX;
43414
43415				// The next two "if" blocks go like this:
43416				// Check if a limit is defined (first "min", then "max");
43417				// Check if we need to change the Y or the X
43418				// (Currently working only if just one of the axes is enabled)
43419				// Then, check if the new position is inside the allowed limit
43420				// If so, use new position. If not, set position to limit.
43421
43422				// Check if a min limit is defined
43423				if (blocks[i].min !== null) {
43424					if (self.options.vertical && !self.options.horizontal) {
43425						positionY = positionY <= blocks[i].min ? blocks[i].min : positionY;
43426					}
43427					if (self.options.horizontal && !self.options.vertical) {
43428						positionX = positionX <= blocks[i].min ? blocks[i].min : positionX;
43429					}
43430				}
43431
43432				// Check if directional min limits are defined
43433				if (blocks[i].minY != null) {
43434						positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY;
43435				}
43436				if (blocks[i].minX != null) {
43437						positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX;
43438				}
43439
43440				// Check if a max limit is defined
43441				if (blocks[i].max !== null) {
43442					if (self.options.vertical && !self.options.horizontal) {
43443						positionY = positionY >= blocks[i].max ? blocks[i].max : positionY;
43444					}
43445					if (self.options.horizontal && !self.options.vertical) {
43446						positionX = positionX >= blocks[i].max ? blocks[i].max : positionX;
43447					}
43448				}
43449
43450				// Check if directional max limits are defined
43451				if (blocks[i].maxY != null) {
43452						positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY;
43453				}
43454				if (blocks[i].maxX != null) {
43455						positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX;
43456				}
43457
43458				var zindex = blocks[i].zindex;
43459
43460				// Move that element
43461				// (Set the new translation and append initial inline transforms.)
43462				var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform;
43463				self.elems[i].style[transformProp] = translate;
43464			}
43465			self.options.callback(positions);
43466		};
43467
43468		self.destroy = function() {
43469			for (var i = 0; i < self.elems.length; i++){
43470				self.elems[i].style.cssText = blocks[i].style;
43471			}
43472
43473			// Remove resize event listener if not pause, and pause
43474			if (!pause) {
43475				window.removeEventListener('resize', init);
43476				pause = true;
43477			}
43478
43479			// Clear the animation loop to prevent possible memory leak
43480			clearLoop(loopId);
43481			loopId = null;
43482		};
43483
43484		// Init
43485		init();
43486
43487		// Allow to recalculate the initial values whenever we want
43488		self.refresh = init;
43489
43490		return self;
43491	};
43492	return Rellax;
43493}));
43494
43495/*
43496 * OKVideo by OKFocus v2.3.2
43497 * http://okfoc.us
43498 *
43499 * Copyright 2014, OKFocus
43500 * Licensed under the MIT license.
43501 *
43502 */
43503var player, OKEvents, options, videoWidth, videoHeight, YTplayers, youtubePlayers = new Array();
43504// youtube player ready
43505function onYouTubeIframeAPIReady() {
43506	YTplayers = new Array();
43507	jQuery('.uncode-video-container.video').each(function() {
43508		var playerY;
43509		if (jQuery(this).attr('data-provider') == 'youtube') {
43510			var id = jQuery(this).attr('data-id'),
43511				start = jQuery(this).attr('data-start'),
43512				end = jQuery(this).attr('data-end');
43513			start = typeof start && start !== null ? start : 0;
43514			end = typeof end && end !== null ? end : 0;
43515			options = jQuery(window).data('okoptions-' + id);
43516			if ( typeof options === 'undefined' ) {
43517				return true;
43518			}
43519			options.time = jQuery(this).attr('data-t');
43520			playerY = new YT.Player('okplayer-' + id, {
43521				videoId: options.video ? options.video.id : null,
43522				playerVars: {
43523					'autohide': 1,
43524					'autoplay': jQuery(this).hasClass('is-no-control') ? options.autoplay : 0, //options.autoplay,
43525					'disablekb': 1,
43526					'cc_load_policy': options.captions,
43527					'controls': 0,
43528					'enablejsapi': 1,
43529					'fs': 0,
43530					'modestbranding': 1,
43531					'origin': window.location.origin || (window.location.protocol + '//' + window.location.hostname),
43532					'iv_load_policy': options.annotations,
43533					'loop': options.loop,
43534					'showinfo': 0,
43535					'rel': 0,
43536					'wmode': 'opaque',
43537					'hd': options.hd,
43538					'mute': 1,
43539					'start': start,
43540					'end': end
43541				},
43542				events: {
43543					'onReady': OKEvents.yt.ready,
43544					'onStateChange': OKEvents.yt.onStateChange,
43545					'onError': OKEvents.yt.error
43546				}
43547			});
43548			YTplayers[id] = playerY;
43549			playerY.videoId = id;
43550		}
43551
43552	});
43553}
43554// vimeo player ready
43555function vimeoPlayerReady(id) {
43556	options = jQuery(window).data('okoptions-' + id);
43557	if ( typeof options === 'undefined' ) {
43558		return true;
43559	}
43560	var jIframe = options.jobject,
43561		iframe = jIframe[0];
43562
43563	jIframe.attr('src', jIframe.data('src'));
43564	var playerV = new Vimeo.Player(iframe);
43565	// hide player until Vimeo hides controls...
43566	playerV.on('loaded', function(e) {
43567		OKEvents.v.onReady(iframe);
43568		var carouselContainer = jQuery(iframe).closest('.owl-carousel');
43569		if (carouselContainer.length) {
43570			UNCODE.owlPlayVideo(carouselContainer);
43571		}
43572		// "Do not try to add listeners or call functions before receiving this event."
43573		if (OKEvents.utils.isMobile()) {
43574			// mobile devices cannot listen for play event
43575			OKEvents.v.onPlay(playerV);
43576		} else {
43577			playerV.on('play', function(){
43578				OKEvents.v.onPlay(playerV);
43579				jQuery(window).trigger('okevents.v.play', [playerV]);
43580			});
43581			playerV.on('pause', function(){
43582				OKEvents.v.onPause;
43583				jQuery(window).trigger('okevents.v.pause', [playerV]);
43584			});
43585			playerV.on('ended', function(){
43586				OKEvents.v.onFinish
43587				jQuery(window).trigger('okevents.v.ended', [playerV]);
43588			});
43589		}
43590		if (options.time != null) {
43591			var optsTimeStr = (options.time).replace('t=', ''),
43592				timeV = '';
43593
43594			if ( /[a-zA-Z]/g.test(optsTimeStr) ) {
43595				var timeArr = optsTimeStr.split(/([^\d.-])/);
43596				for ( var i = 0; i < timeArr.length; i++ ) {
43597					if ( timeArr[i] === 'h' ) {
43598						timeV += parseFloat(timeArr[i-1]) * 3600;
43599					} else if ( timeArr[i] === 'm' ) {
43600						timeV += parseFloat(timeArr[i-1]) * 60;
43601					} else if ( timeArr[i] === 's' ) {
43602						timeV += parseFloat(timeArr[i-1]);
43603					}
43604				}
43605			} else {
43606				timeV = optsTimeStr;
43607			}
43608
43609			playerV.setCurrentTime(timeV);
43610		}
43611
43612		playerV.setVolume(0);
43613		playerV.play();
43614		jQuery(iframe).css({
43615			visibility: 'visible',
43616			opacity: 1
43617		});
43618		jQuery(iframe).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43619		jQuery(iframe).closest('#page-header').addClass('video-started');
43620		jQuery(iframe).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43621
43622		jQuery(window).trigger('okevents.v.loaded', [playerV]);
43623	});
43624}
43625OKEvents = {
43626	yt: {
43627		ready: function(event) {
43628			var id = event.target.videoId,
43629				$video = jQuery('#okplayer-' + id),
43630				options = jQuery(window).data('okoptions-' + id);
43631			if ( typeof options === 'undefined' ) {
43632				return true;
43633			}
43634			youtubePlayers[id] = event.target;
43635			event.target.setVolume(options.volume);
43636			if (options.autoplay === 1) {
43637				if (options.playlist.list) {
43638					player.loadPlaylist(options.playlist.list, options.playlist.index, options.playlist.startSeconds, options.playlist.suggestedQuality);
43639				} else {
43640					var inCarousel = $video.closest('.owl-item');
43641					if (!inCarousel.length || (inCarousel.length && inCarousel.hasClass('active'))) {
43642						if (options.time != null) {
43643							event.target.seekTo(parseInt(options.time));
43644						}
43645						event.target.playVideo();
43646					} else {
43647						event.target.pauseVideo();
43648					}
43649				}
43650			}
43651			OKEvents.utils.isFunction(options.onReady) && options.onReady(event.target);
43652
43653			$video.closest('[data-provider]').on('uncode-resume', function(){
43654				if (options.time != null) {
43655					event.target.seekTo(parseInt(options.time)).playVideo();
43656				} else {
43657					event.target.seekTo(0).playVideo();
43658				}
43659			});
43660
43661			$video.closest('[data-provider]').on('uncode-pause', function(){
43662				if (options.time != null) {
43663					event.target.seekTo(parseInt(options.time)).pauseVideo();
43664				} else {
43665					event.target.seekTo(0).pauseVideo();
43666				}
43667			});
43668			jQuery(window).trigger('okevents.y.loaded', [event]);
43669		},
43670		onStateChange: function(event) {
43671			var id = event.target.videoId,
43672				$video = jQuery('#okplayer-' + id),
43673				options = jQuery(window).data('okoptions-' + id);
43674			if ( typeof options === 'undefined' || typeof event.target.setVolume === 'undefined' ) {
43675				return true;
43676			}
43677			youtubePlayers[id] = event.target;
43678			event.target.setVolume(options.volume);
43679			var $fluid = $video.closest('.fluid-object'),
43680				$tmb = $video.closest('.tmb'),
43681				setTime;
43682			switch (event.data) {
43683				case -1:
43684					OKEvents.utils.isFunction(options.unstarted) && options.unstarted();
43685					break;
43686				case 0:
43687					OKEvents.utils.isFunction(options.onFinished) && options.onFinished();
43688					options.loop && event.target.playVideo();
43689					break;
43690				case 1:
43691					OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
43692					setTimeout(function() {
43693						UNCODE.initVideoComponent(document.body, '.uncode-video-container.video:not(.drop-move), .uncode-video-container.self-video:not(.drop-move)');
43694						jQuery('#okplayer-' + id).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43695						jQuery('#okplayer-' + id).closest('#page-header').addClass('video-started');
43696						jQuery('#okplayer-' + id).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43697					}, 300);
43698				break;
43699				case 2:
43700					OKEvents.utils.isFunction(options.onPause) && options.onPause();
43701					break;
43702				case 3:
43703					OKEvents.utils.isFunction(options.buffering) && options.buffering();
43704					break;
43705				case 5:
43706					OKEvents.utils.isFunction(options.cued) && options.cued();
43707					break;
43708				default:
43709					throw "OKVideo: received invalid data from YT player.";
43710			}
43711
43712			jQuery(window).trigger('okevents.y.change', [event]);
43713		},
43714		error: function(event) {
43715			throw event;
43716		}
43717	},
43718	v: {
43719		onReady: function(target) {
43720			if ( typeof options === 'undefined' ) {
43721				return true;
43722			}
43723			OKEvents.utils.isFunction(options.onReady) && options.onReady(target);
43724		},
43725		onPlay: function(player) {
43726			if ( typeof options === 'undefined' ) {
43727				return true;
43728			}
43729			if (!OKEvents.utils.isMobile()) player.setVolume(options.volume);
43730			OKEvents.utils.isFunction(options.onPlay) && options.onPlay();
43731			jQuery(player.element).closest('.uncode-video-container:not(.t-entry-drop)').css('opacity', '1');
43732			jQuery(player.element).closest('#page-header').addClass('video-started');
43733			jQuery(player.element).closest('.background-wrapper').find('.block-bg-blend-mode.not-ie').css('opacity', '1');
43734		},
43735		onPause: function() {
43736			if ( typeof options === 'undefined' ) {
43737				return true;
43738			}
43739			OKEvents.utils.isFunction(options.onPause) && options.onPause();
43740		},
43741		onFinish: function() {
43742			if ( typeof options === 'undefined' ) {
43743				return true;
43744			}
43745			OKEvents.utils.isFunction(options.onFinish) && options.onFinish();
43746		}
43747	},
43748	utils: {
43749		isFunction: function(func) {
43750			if (typeof func === 'function') {
43751				return true;
43752			} else {
43753				return false;
43754			}
43755		},
43756		isMobile: function() {
43757			if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry)/)) {
43758				return true;
43759			} else {
43760				return false;
43761			}
43762		}
43763	}
43764};
43765/**
43766 * vivus - JavaScript library to make drawing animation on SVG
43767 * @version v0.4.4
43768 * @link https://github.com/maxwellito/vivus
43769 * @license MIT
43770 */
43771
43772'use strict';
43773
43774(function () {
43775
43776  'use strict';
43777
43778/**
43779 * Pathformer
43780 * Beta version
43781 *
43782 * Take any SVG version 1.1 and transform
43783 * child elements to 'path' elements
43784 *
43785 * This code is purely forked from
43786 * https://github.com/Waest/SVGPathConverter
43787 */
43788
43789/**
43790 * Class constructor
43791 *
43792 * @param {DOM|String} element Dom element of the SVG or id of it
43793 */
43794function Pathformer(element) {
43795  // Test params
43796  if (typeof element === 'undefined') {
43797	throw new Error('Pathformer [constructor]: "element" parameter is required');
43798  }
43799
43800  // Set the element
43801  if (element.constructor === String) {
43802	element = document.getElementById(element);
43803	if (!element) {
43804	  throw new Error('Pathformer [constructor]: "element" parameter is not related to an existing ID');
43805	}
43806  }
43807  if (element instanceof window.SVGElement ||
43808	  element instanceof window.SVGGElement ||
43809	  /^svg$/i.test(element.nodeName)) {
43810	this.el = element;
43811  } else {
43812	throw new Error('Pathformer [constructor]: "element" parameter must be a string or a SVGelement');
43813  }
43814
43815  // Start
43816  this.scan(element);
43817}
43818
43819/**
43820 * List of tags which can be transformed
43821 * to path elements
43822 *
43823 * @type {Array}
43824 */
43825Pathformer.prototype.TYPES = ['line', 'ellipse', 'circle', 'polygon', 'polyline', 'rect'];
43826
43827/**
43828 * List of attribute names which contain
43829 * data. This array list them to check if
43830 * they contain bad values, like percentage.
43831 *
43832 * @type {Array}
43833 */
43834Pathformer.prototype.ATTR_WATCH = ['cx', 'cy', 'points', 'r', 'rx', 'ry', 'x', 'x1', 'x2', 'y', '
vendor: 24,640 bytes, lines 43834-44632
43834y1', 'y2'];
43835
43836/**
43837 * Finds the elements compatible for transform
43838 * and apply the liked method
43839 *
43840 * @param  {object} options Object from the constructor
43841 */
43842Pathformer.prototype.scan = function (svg) {
43843  var fn, element, pathData, pathDom,
43844	  elements = svg.querySelectorAll(this.TYPES.join(','));
43845
43846  for (var i = 0; i < elements.length; i++) {
43847	element = elements[i];
43848	fn = this[element.tagName.toLowerCase() + 'ToPath'];
43849	pathData = fn(this.parseAttr(element.attributes));
43850	pathDom = this.pathMaker(element, pathData);
43851	element.parentNode.replaceChild(pathDom, element);
43852  }
43853};
43854
43855
43856/**
43857 * Read `line` element to extract and transform
43858 * data, to make it ready for a `path` object.
43859 *
43860 * @param  {DOMelement} element Line element to transform
43861 * @return {object}			 Data for a `path` element
43862 */
43863Pathformer.prototype.lineToPath = function (element) {
43864  var newElement = {},
43865	  x1 = element.x1 || 0,
43866	  y1 = element.y1 || 0,
43867	  x2 = element.x2 || 0,
43868	  y2 = element.y2 || 0;
43869
43870  newElement.d = 'M' + x1 + ',' + y1 + 'L' + x2 + ',' + y2;
43871  return newElement;
43872};
43873
43874/**
43875 * Read `rect` element to extract and transform
43876 * data, to make it ready for a `path` object.
43877 * The radius-border is not taken in charge yet.
43878 * (your help is more than welcomed)
43879 *
43880 * @param  {DOMelement} element Rect element to transform
43881 * @return {object}             Data for a `path` element
43882 */
43883Pathformer.prototype.rectToPath = function (element) {
43884  var newElement = {},
43885      x      = parseFloat(element.x)      || 0,
43886      y      = parseFloat(element.y)      || 0,
43887      width  = parseFloat(element.width)  || 0,
43888      height = parseFloat(element.height) || 0;
43889
43890  if (element.rx || element.ry) {
43891    var rx = parseInt(element.rx, 10) || -1,
43892        ry = parseInt(element.ry, 10) || -1;
43893    rx = Math.min(Math.max(rx < 0 ? ry : rx, 0), width/2);
43894    ry = Math.min(Math.max(ry < 0 ? rx : ry, 0), height/2);
43895
43896    newElement.d = 'M ' + (x + rx) + ',' + y + ' ' +
43897                   'L ' + (x + width - rx) + ',' + y + ' ' +
43898                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + width) + ',' + (y + ry) + ' ' +
43899                   'L ' + (x + width) + ',' + (y + height - ry) + ' ' +
43900                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + width - rx) + ',' + (y + height) + ' ' +
43901                   'L ' + (x + rx) + ',' + (y + height) + ' ' +
43902                   'A ' + rx + ',' + ry + ',0,0,1,' + x + ',' + (y + height - ry) + ' ' +
43903                   'L ' + x + ',' + (y + ry) + ' ' +
43904                   'A ' + rx + ',' + ry + ',0,0,1,' + (x + rx) + ',' + y;
43905  }
43906  else {
43907    newElement.d = 'M' + x + ' ' + y + ' ' +
43908                   'L' + (x + width) + ' ' + y + ' ' +
43909                   'L' + (x + width) + ' ' + (y + height) + ' ' +
43910                   'L' + x + ' ' + (y + height) + ' Z';
43911  }
43912  return newElement;
43913};
43914
43915/**
43916 * Read `polyline` element to extract and transform
43917 * data, to make it ready for a `path` object.
43918 *
43919 * @param  {DOMelement} element Polyline element to transform
43920 * @return {object}             Data for a `path` element
43921 */
43922Pathformer.prototype.polylineToPath = function (element) {
43923  var newElement = {},
43924      points = element.points.trim().split(' '),
43925      i, path;
43926
43927  // Reformatting if points are defined without commas
43928  if (element.points.indexOf(',') === -1) {
43929    var formattedPoints = [];
43930    for (i = 0; i < points.length; i+=2) {
43931      formattedPoints.push(points[i] + ',' + points[i+1]);
43932    }
43933    points = formattedPoints;
43934  }
43935
43936  // Generate the path.d value
43937  path = 'M' + points[0];
43938  for(i = 1; i < points.length; i++) {
43939    if (points[i].indexOf(',') !== -1) {
43940      path += 'L' + points[i];
43941    }
43942  }
43943  newElement.d = path;
43944  return newElement;
43945};
43946
43947/**
43948 * Read `polygon` element to extract and transform
43949 * data, to make it ready for a `path` object.
43950 * This method rely on polylineToPath, because the
43951 * logic is similar. The path created is just closed,
43952 * so it needs an 'Z' at the end.
43953 *
43954 * @param  {DOMelement} element Polygon element to transform
43955 * @return {object}             Data for a `path` element
43956 */
43957Pathformer.prototype.polygonToPath = function (element) {
43958  var newElement = Pathformer.prototype.polylineToPath(element);
43959
43960  newElement.d += 'Z';
43961  return newElement;
43962};
43963
43964/**
43965 * Read `ellipse` element to extract and transform
43966 * data, to make it ready for a `path` object.
43967 *
43968 * @param  {DOMelement} element ellipse element to transform
43969 * @return {object}             Data for a `path` element
43970 */
43971Pathformer.prototype.ellipseToPath = function (element) {
43972  var newElement = {},
43973      rx = parseFloat(element.rx) || 0,
43974      ry = parseFloat(element.ry) || 0,
43975      cx = parseFloat(element.cx) || 0,
43976      cy = parseFloat(element.cy) || 0,
43977      startX = cx - rx,
43978      startY = cy,
43979      endX = parseFloat(cx) + parseFloat(rx),
43980      endY = cy;
43981
43982  newElement.d = 'M' + startX + ',' + startY +
43983                 'A' + rx + ',' + ry + ' 0,1,1 ' + endX + ',' + endY +
43984                 'A' + rx + ',' + ry + ' 0,1,1 ' + startX + ',' + endY;
43985  return newElement;
43986};
43987
43988/**
43989 * Read `circle` element to extract and transform
43990 * data, to make it ready for a `path` object.
43991 *
43992 * @param  {DOMelement} element Circle element to transform
43993 * @return {object}             Data for a `path` element
43994 */
43995Pathformer.prototype.circleToPath = function (element) {
43996  var newElement = {},
43997      r  = parseFloat(element.r)  || 0,
43998      cx = parseFloat(element.cx) || 0,
43999      cy = parseFloat(element.cy) || 0,
44000      startX = cx - r,
44001      startY = cy,
44002      endX = parseFloat(cx) + parseFloat(r),
44003      endY = cy;
44004
44005  newElement.d =  'M' + startX + ',' + startY +
44006                  'A' + r + ',' + r + ' 0,1,1 ' + endX + ',' + endY +
44007                  'A' + r + ',' + r + ' 0,1,1 ' + startX + ',' + endY;
44008  return newElement;
44009};
44010
44011/**
44012 * Create `path` elements form original element
44013 * and prepared objects
44014 *
44015 * @param  {DOMelement} element  Original element to transform
44016 * @param  {object} pathData     Path data (from `toPath` methods)
44017 * @return {DOMelement}          Path element
44018 */
44019Pathformer.prototype.pathMaker = function (element, pathData) {
44020  var i, attr, pathTag = document.createElementNS('http://www.w3.org/2000/svg','path');
44021  for(i = 0; i < element.attributes.length; i++) {
44022    attr = element.attributes[i];
44023    if (this.ATTR_WATCH.indexOf(attr.name) === -1) {
44024      pathTag.setAttribute(attr.name, attr.value);
44025    }
44026  }
44027  for(i in pathData) {
44028    pathTag.setAttribute(i, pathData[i]);
44029  }
44030  return pathTag;
44031};
44032
44033/**
44034 * Parse attributes of a DOM element to
44035 * get an object of attribute => value
44036 *
44037 * @param  {NamedNodeMap} attributes Attributes object from DOM element to parse
44038 * @return {object}                  Object of attributes
44039 */
44040Pathformer.prototype.parseAttr = function (element) {
44041  var attr, output = {};
44042  for (var i = 0; i < element.length; i++) {
44043    attr = element[i];
44044    // Check if no data attribute contains '%', or the transformation is impossible
44045    if (this.ATTR_WATCH.indexOf(attr.name) !== -1 && attr.value.indexOf('%') !== -1) {
44046      throw new Error('Pathformer [parseAttr]: a SVG shape got values in percentage. This cannot be transformed into \'path\' tags. Please use \'viewBox\'.');
44047    }
44048    output[attr.name] = attr.value;
44049  }
44050  return output;
44051};
44052
44053  'use strict';
44054
44055var setupEnv, requestAnimFrame, cancelAnimFrame, parsePositiveInt;
44056
44057/**
44058 * Vivus
44059 * Beta version
44060 *
44061 * Take any SVG and make the animation
44062 * to give give the impression of live drawing
44063 *
44064 * This in more than just inspired from codrops
44065 * At that point, it's a pure fork.
44066 */
44067
44068/**
44069 * Class constructor
44070 * option structure
44071 *   type: 'delayed'|'sync'|'oneByOne'|'script' (to know if the items must be drawn synchronously or not, default: delayed)
44072 *   duration: <int> (in frames)
44073 *   start: 'inViewport'|'manual'|'autostart' (start automatically the animation, default: inViewport)
44074 *   delay: <int> (delay between the drawing of first and last path)
44075 *   dashGap <integer> whitespace extra margin between dashes
44076 *   pathTimingFunction <function> timing animation function for each path element of the SVG
44077 *   animTimingFunction <function> timing animation function for the complete SVG
44078 *   forceRender <boolean> force the browser to re-render all updated path items
44079 *   selfDestroy <boolean> removes all extra styling on the SVG, and leaves it as original
44080 *
44081 * The attribute 'type' is by default on 'delayed'.
44082 *  - 'delayed'
44083 *    all paths are draw at the same time but with a
44084 *    little delay between them before start
44085 *  - 'sync'
44086 *    all path are start and finish at the same time
44087 *  - 'oneByOne'
44088 *    only one path is draw at the time
44089 *    the end of the first one will trigger the draw
44090 *    of the next one
44091 *
44092 * All these values can be overwritten individually
44093 * for each path item in the SVG
44094 * The value of frames will always take the advantage of
44095 * the duration value.
44096 * If you fail somewhere, an error will be thrown.
44097 * Good luck.
44098 *
44099 * @constructor
44100 * @this {Vivus}
44101 * @param {DOM|String}   element  Dom element of the SVG or id of it
44102 * @param {Object}       options  Options about the animation
44103 * @param {Function}     callback Callback for the end of the animation
44104 */
44105function Vivus (element, options, callback) {
44106
44107  setupEnv();
44108
44109  // Setup
44110  this.isReady = false;
44111  this.setElement(element, options);
44112  this.setOptions(options);
44113  this.setCallback(callback);
44114
44115  if (this.isReady) {
44116    this.init();
44117  }
44118}
44119
44120/**
44121 * Timing functions
44122 **************************************
44123 *
44124 * Default functions to help developers.
44125 * It always take a number as parameter (between 0 to 1) then
44126 * return a number (between 0 and 1)
44127 */
44128Vivus.LINEAR          = function (x) {return x;};
44129Vivus.EASE            = function (x) {return -Math.cos(x * Math.PI) / 2 + 0.5;};
44130Vivus.EASE_OUT        = function (x) {return 1 - Math.pow(1-x, 3);};
44131Vivus.EASE_IN         = function (x) {return Math.pow(x, 3);};
44132Vivus.EASE_OUT_BOUNCE = function (x) {
44133  var base = -Math.cos(x * (0.5 * Math.PI)) + 1,
44134    rate = Math.pow(base,1.5),
44135    rateR = Math.pow(1 - x, 2),
44136    progress = -Math.abs(Math.cos(rate * (2.5 * Math.PI) )) + 1;
44137  return (1- rateR) + (progress * rateR);
44138};
44139
44140
44141/**
44142 * Setters
44143 **************************************
44144 */
44145
44146/**
44147 * Check and set the element in the instance
44148 * The method will not return anything, but will throw an
44149 * error if the parameter is invalid
44150 *
44151 * @param {DOM|String}   element  SVG Dom element or id of it
44152 */
44153Vivus.prototype.setElement = function (element, options) {
44154  var onLoad, self;
44155
44156  // Basic check
44157  if (typeof element === 'undefined') {
44158    throw new Error('Vivus [constructor]: "element" parameter is required');
44159  }
44160
44161  // Set the element
44162  if (element.constructor === String) {
44163    element = document.getElementById(element);
44164    if (!element) {
44165      throw new Error('Vivus [constructor]: "element" parameter is not related to an existing ID');
44166    }
44167  }
44168  this.parentEl = element;
44169
44170  // Load the SVG with XMLHttpRequest and extract the SVG
44171  if (options && options.file) {
44172    var self = this;
44173    onLoad = function (e) {
44174      var domSandbox = document.createElement('div');
44175      domSandbox.innerHTML = this.responseText;
44176
44177      var svgTag = domSandbox.querySelector('svg');
44178      if (!svgTag) {
44179        throw new Error('Vivus [load]: Cannot find the SVG in the loaded file : ' + options.file);
44180      }
44181
44182      self.el = svgTag
44183      self.el.setAttribute('width', '100%');
44184      self.el.setAttribute('height', '100%');
44185      self.parentEl.appendChild(self.el)
44186      self.isReady = true;
44187      self.init();
44188      self = null;
44189    }
44190
44191    var oReq = new window.XMLHttpRequest();
44192    oReq.addEventListener('load', onLoad);
44193    oReq.open('GET', options.file);
44194    oReq.send();
44195    return;
44196  }
44197
44198  switch (element.constructor) {
44199  case window.SVGSVGElement:
44200  case window.SVGElement:
44201  case window.SVGGElement:
44202    this.el = element;
44203    this.isReady = true;
44204    break;
44205
44206  case window.HTMLObjectElement:
44207    self = this;
44208    onLoad = function (e) {
44209      if (self.isReady) {
44210        return;
44211      }
44212      self.el = element.contentDocument && element.contentDocument.querySelector('svg');
44213      if (!self.el && e) {
44214        throw new Error('Vivus [constructor]: object loaded does not contain any SVG');
44215      }
44216      else if (self.el) {
44217        if (element.getAttribute('built-by-vivus')) {
44218          self.parentEl.insertBefore(self.el, element);
44219          self.parentEl.removeChild(element);
44220          self.el.setAttribute('width', '100%');
44221          self.el.setAttribute('height', '100%');
44222        }
44223        self.isReady = true;
44224        self.init();
44225        self = null;
44226      }
44227    };
44228
44229    if (!onLoad()) {
44230      element.addEventListener('load', onLoad);
44231    }
44232    break;
44233
44234  default:
44235    throw new Error('Vivus [constructor]: "element" parameter is not valid (or miss the "file" attribute)');
44236  }
44237};
44238
44239/**
44240 * Set up user option to the instance
44241 * The method will not return anything, but will throw an
44242 * error if the parameter is invalid
44243 *
44244 * @param  {object} options Object from the constructor
44245 */
44246Vivus.prototype.setOptions = function (options) {
44247  var allowedTypes = ['delayed', 'sync', 'async', 'nsync', 'oneByOne', 'scenario', 'scenario-sync'];
44248  var allowedStarts =  ['inViewport', 'manual', 'autostart'];
44249
44250  // Basic check
44251  if (options !== undefined && options.constructor !== Object) {
44252    throw new Error('Vivus [constructor]: "options" parameter must be an object');
44253  }
44254  else {
44255    options = options || {};
44256  }
44257
44258  // Set the animation type
44259  if (options.type && allowedTypes.indexOf(options.type) === -1) {
44260    throw new Error('Vivus [constructor]: ' + options.type + ' is not an existing animation `type`');
44261  }
44262  else {
44263    this.type = options.type || allowedTypes[0];
44264  }
44265
44266  // Set the start type
44267  if (options.start && allowedStarts.indexOf(options.start) === -1) {
44268    throw new Error('Vivus [constructor]: ' + options.start + ' is not an existing `start` option');
44269  }
44270  else {
44271    this.start = options.start || allowedStarts[0];
44272  }
44273
44274  this.isIE         = (window.navigator.userAgent.indexOf('MSIE') !== -1 || window.navigator.userAgent.indexOf('Trident/') !== -1 || window.navigator.userAgent.indexOf('Edge/') !== -1 );
44275  this.duration     = parsePositiveInt(options.duration, 120);
44276  this.delay        = parsePositiveInt(options.delay, null);
44277  //Uncode addition
44278  this.delayStart   = parsePositiveInt(options.delayStart, null);
44279  //#END
44280  this.dashGap      = parsePositiveInt(options.dashGap, 1);
44281  this.forceRender  = options.hasOwnProperty('forceRender') ? !!options.forceRender : this.isIE;
44282  this.reverseStack = !!options.reverseStack;
44283  this.selfDestroy  = !!options.selfDestroy;
44284  this.onReady      = options.onReady;
44285  this.map          = [];
44286  this.frameLength  = this.currentFrame = this.delayUnit = this.speed = this.handle = null;
44287
44288  this.ignoreInvisible = options.hasOwnProperty('ignoreInvisible') ? !!options.ignoreInvisible : false;
44289
44290  this.animTimingFunction = options.animTimingFunction || Vivus.LINEAR;
44291  this.pathTimingFunction = options.pathTimingFunction || Vivus.LINEAR;
44292
44293  if (this.delay >= this.duration) {
44294    throw new Error('Vivus [constructor]: delay must be shorter than duration');
44295  }
44296};
44297
44298/**
44299 * Set up callback to the instance
44300 * The method will not return enything, but will throw an
44301 * error if the parameter is invalid
44302 *
44303 * @param  {Function} callback Callback for the animation end
44304 */
44305Vivus.prototype.setCallback = function (callback) {
44306  // Basic check
44307  if (!!callback && callback.constructor !== Function) {
44308    throw new Error('Vivus [constructor]: "callback" parameter must be a function');
44309  }
44310  this.callback = callback || function () {};
44311};
44312
44313
44314/**
44315 * Core
44316 **************************************
44317 */
44318
44319/**
44320 * Map the svg, path by path.
44321 * The method return nothing, it just fill the
44322 * `map` array. Each item in this array represent
44323 * a path element from the SVG, with informations for
44324 * the animation.
44325 *
44326 * ```
44327 * [
44328 *   {
44329 *     el: <DOMobj> the path element
44330 *     length: <number> length of the path line
44331 *     startAt: <number> time start of the path animation (in frames)
44332 *     duration: <number> path animation duration (in frames)
44333 *   },
44334 *   ...
44335 * ]
44336 * ```
44337 *
44338 */
44339Vivus.prototype.mapping = function () {
44340  var i, paths, path, pAttrs, pathObj, totalLength, lengthMeter, timePoint;
44341  timePoint = totalLength = lengthMeter = 0;
44342  paths = this.el.querySelectorAll('path');
44343
44344  for (i = 0; i < paths.length; i++) {
44345    path = paths[i];
44346    if (this.isInvisible(path)) {
44347      continue;
44348    }
44349    pathObj = {
44350      el: path,
44351      length: Math.ceil(path.getTotalLength())
44352    };
44353    // Test if the path length is correct
44354    if (isNaN(pathObj.length)) {
44355      if (window.console && console.warn) {
44356        console.warn('Vivus [mapping]: cannot retrieve a path element length', path);
44357      }
44358      continue;
44359    }
44360    this.map.push(pathObj);
44361    path.style.strokeDasharray  = pathObj.length + ' ' + (pathObj.length + this.dashGap * 2);
44362    path.style.strokeDashoffset = pathObj.length + this.dashGap;
44363    pathObj.length += this.dashGap;
44364    totalLength += pathObj.length;
44365
44366    this.renderPath(i);
44367  }
44368
44369  totalLength = totalLength === 0 ? 1 : totalLength;
44370  this.delay = this.delay === null ? this.duration / 3 : this.delay;
44371  this.delayUnit = this.delay / (paths.length > 1 ? paths.length - 1 : 1);
44372
44373  // Reverse stack if asked
44374  if (this.reverseStack) {
44375    this.map.reverse();
44376  }
44377
44378  for (i = 0; i < this.map.length; i++) {
44379    pathObj = this.map[i];
44380
44381    switch (this.type) {
44382    case 'delayed':
44383      pathObj.startAt = this.delayUnit * i;
44384      pathObj.duration = this.duration - this.delay;
44385      break;
44386
44387    case 'oneByOne':
44388      pathObj.startAt = lengthMeter / totalLength * this.duration;
44389      pathObj.duration = pathObj.length / totalLength * this.duration;
44390      break;
44391
44392    case 'sync':
44393    case 'async':
44394    case 'nsync':
44395      pathObj.startAt = 0;
44396      pathObj.duration = this.duration;
44397      break;
44398
44399    case 'scenario-sync':
44400      path = pathObj.el;
44401      pAttrs = this.parseAttr(path);
44402      pathObj.startAt = timePoint + (parsePositiveInt(pAttrs['data-delay'], this.delayUnit) || 0);
44403      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
44404      timePoint = pAttrs['data-async'] !== undefined ? pathObj.startAt : pathObj.startAt + pathObj.duration;
44405      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
44406      break;
44407
44408    case 'scenario':
44409      path = pathObj.el;
44410      pAttrs = this.parseAttr(path);
44411      pathObj.startAt = parsePositiveInt(pAttrs['data-start'], this.delayUnit) || 0;
44412      pathObj.duration = parsePositiveInt(pAttrs['data-duration'], this.duration);
44413      this.frameLength = Math.max(this.frameLength, (pathObj.startAt + pathObj.duration));
44414      break;
44415    }
44416    lengthMeter += pathObj.length;
44417    this.frameLength = this.frameLength || this.duration;
44418  }
44419};
44420
44421/**
44422 * Interval method to draw the SVG from current
44423 * position of the animation. It update the value of
44424 * `currentFrame` and re-trace the SVG.
44425 *
44426 * It use this.handle to store the requestAnimationFrame
44427 * and clear it one the animation is stopped. So this
44428 * attribute can be used to know if the animation is
44429 * playing.
44430 *
44431 * Once the animation at the end, this method will
44432 * trigger the Vivus callback.
44433 *
44434 */
44435Vivus.prototype.drawer = function () {
44436  var self = this;
44437  this.currentFrame += this.speed;
44438
44439  if (this.currentFrame <= 0) {
44440    this.stop();
44441    this.reset();
44442  } else if (this.currentFrame >= this.frameLength) {
44443    this.stop();
44444    this.currentFrame = this.frameLength;
44445    this.trace();
44446    if (this.selfDestroy) {
44447      this.destroy();
44448    }
44449  } else {
44450    this.trace();
44451    this.handle = requestAnimFrame(function () {
44452      self.drawer();
44453    });
44454    return;
44455  }
44456
44457  this.callback(this);
44458  if (this.instanceCallback) {
44459    this.instanceCallback(this);
44460    this.instanceCallback = null;
44461  }
44462};
44463
44464/**
44465 * Draw the SVG at the current instant from the
44466 * `currentFrame` value. Here is where most of the magic is.
44467 * The trick is to use the `strokeDashoffset` style property.
44468 *
44469 * For optimisation reasons, a new property called `progress`
44470 * is added in each item of `map`. This one contain the current
44471 * progress of the path element. Only if the new value is different
44472 * the new value will be applied to the DOM element. This
44473 * method save a lot of resources to re-render the SVG. And could
44474 * be improved if the animation couldn't be played forward.
44475 *
44476 */
44477Vivus.prototype.trace = function () {
44478  var i, progress, path, currentFrame;
44479  currentFrame = this.animTimingFunction(this.currentFrame / this.frameLength) * this.frameLength;
44480  for (i = 0; i < this.map.length; i++) {
44481    path = this.map[i];
44482    progress = (currentFrame - path.startAt) / path.duration;
44483    progress = this.pathTimingFunction(Math.max(0, Math.min(1, progress)));
44484    if (path.progress !== progress) {
44485      path.progress = progress;
44486      path.el.style.strokeDashoffset = Math.floor(path.length * (1 - progress));
44487      this.renderPath(i);
44488    }
44489  }
44490};
44491
44492/**
44493 * Method forcing the browser to re-render a path element
44494 * from it's index in the map. Depending on the `forceRender`
44495 * value.
44496 * The trick is to replace the path element by it's clone.
44497 * This practice is not recommended because it's asking more
44498 * ressources, too much DOM manupulation..
44499 * but it's the only way to let the magic happen on IE.
44500 * By default, this fallback is only applied on IE.
44501 *
44502 * @param  {Number} index Path index
44503 */
44504Vivus.prototype.renderPath = function (index) {
44505  if (this.forceRender && this.map && this.map[index]) {
44506    var pathObj = this.map[index],
44507        newPath = pathObj.el.cloneNode(true);
44508    pathObj.el.parentNode.replaceChild(newPath, pathObj.el);
44509    pathObj.el = newPath;
44510  }
44511};
44512
44513/**
44514 * When the SVG object is loaded and ready,
44515 * this method will continue the initialisation.
44516 *
44517 * This this mainly due to the case of passing an
44518 * object tag in the constructor. It will wait
44519 * the end of the loading to initialise.
44520 *
44521 */
44522Vivus.prototype.init = function () {
44523  // Set object variables
44524  this.frameLength = 0;
44525  this.currentFrame = 0;
44526  this.map = [];
44527
44528  // Start
44529  new Pathformer(this.el);
44530  this.mapping();
44531  this.starter();
44532
44533  if (this.onReady) {
44534    this.onReady(this);
44535  }
44536};
44537
44538/**
44539 * Trigger to start of the animation.
44540 * Depending on the `start` value, a different script
44541 * will be applied.
44542 *
44543 * If the `start` value is not valid, an error will be thrown.
44544 * Even if technically, this is impossible.
44545 *
44546 */
44547Vivus.prototype.starter = function () {
44548  switch (this.start) {
44549  case 'manual':
44550    return;
44551
44552  case 'autostart':
44553    this.play();
44554    break;
44555
44556  case 'inViewport':
44557    var self = this,
44558    listener = function () {
44559      if (self.isInViewport(self.parentEl, 1)) {
44560        self.play();
44561        window.removeEventListener('scroll', listener);
44562        //Uncode addition
44563        window.removeEventListener('fp-slide-changed', listener);
44564        window.removeEventListener('fp-slide-scroll', listener);
44565        //#END
44566      }
44567    };
44568    window.addEventListener('scroll', listener);
44569    //Uncode addition
44570    window.addEventListener('fp-slide-changed', listener);
44571    window.addEventListener('fp-slide-scroll', listener);
44572    //#END
44573    listener();
44574    break;
44575  }
44576};
44577
44578
44579/**
44580 * Controls
44581 **************************************
44582 */
44583
44584/**
44585 * Get the current status of the animation between
44586 * three different states: 'start', 'progress', 'end'.
44587 * @return {string} Instance status
44588 */
44589Vivus.prototype.getStatus = function () {
44590  return this.currentFrame === 0 ? 'start' : this.currentFrame === this.frameLength ? 'end' : 'progress';
44591};
44592
44593/**
44594 * Reset the instance to the initial state : undraw
44595 * Be careful, it just reset the animation, if you're
44596 * playing the animation, this won't stop it. But just
44597 * make it start from start.
44598 *
44599 */
44600Vivus.prototype.reset = function () {
44601  return this.setFrameProgress(0);
44602};
44603
44604/**
44605 * Set the instance to the final state : drawn
44606 * Be careful, it just set the animation, if you're
44607 * playing the animation on rewind, this won't stop it.
44608 * But just make it start from the end.
44609 *
44610 */
44611Vivus.prototype.finish = function () {
44612  return this.setFrameProgress(1);
44613};
44614
44615/**
44616 * Set the level of progress of the drawing.
44617 *
44618 * @param {number} progress Level of progress to set
44619 */
44620Vivus.prototype.setFrameProgress = function (progress) {
44621  progress = Math.min(1, Math.max(0, progress));
44622  this.currentFrame = Math.round(this.frameLength * progress);
44623  this.trace();
44624  return this;
44625};
44626
44627/**
44628 * Play the animation at the desired speed.
44629 * Speed must be a valid number (no zero).
44630 * By default, the speed value is 1.
44631 * But a negative value is accepted to go forward.
44632 *
44633 * And works with float too.
44634 * But don't forget we are in JavaScript, se be nice
44635 * with him and give him a 1/2^x value.
44636 *
44637 * @param  {number} speed Animation speed [optional]
44638 */
44639Vivus.prototype.play = function (speed, callback) {
44640  this.instanceCallback = null;
44641
44642  if (speed && typeof speed === 'function') {
44643    this.instanceCallback = speed; // first parameter is actually the callback function
44644    speed = null;
44645  }
44646  else if (speed && typeof speed !== 'number') {
44647    throw new Error('Vivus [play]: invalid speed');
44648  }
44649  // if the first parameter wasn't the callback, check if the seconds was
44650  if (callback && typeof(callback) === 'function' && !this.instanceCallback) {
44651    this.instanceCallback = callback;
44652  }
44653
44654
44655  this.speed = speed || 1;
44656  //Uncode addition
44657  if (!this.handle) {
44658    var $this = this,
44659    delay = (this.delayStart != null) ? this.delayStart : 0;
44660    setTimeout(function() {
44661      $this.drawer();
44662    }, delay);
44663  }
44664  //#END
44665  return this;
44666};
44667
44668/**
44669 * Stop the current animation, if on progress.
44670 * Should not trigger any error.
44671 *
44672 */
44673Vivus.prototype.stop = function () {
44674  if (this.handle) {
44675    cancelAnimFrame(this.handle);
44676    this.handle = null;
44677  }
44678  return this;
44679};
44680
44681/**
44682 * Destroy the instance.
44683 * Remove all bad styling attributes on all
44684 * path tags
44685 *
44686 */
44687Vivus.prototype.destroy = function () {
44688  this.stop();
44689  var i, path;
44690  for (i = 0; i < this.map.length; i++) {
44691    path = this.map[i];
44692    path.el.style.strokeDashoffset = null;
44693    path.el.style.strokeDasharray = null;
44694    this.renderPath(i);
44695  }
44696};
44697
44698
44699/**
44700 * Utils methods
44701 * include methods from Codrops
44702 **************************************
44703 */
44704
44705/**
44706 * Method to best guess if a path should added into
44707 * the animation or not.
44708 *
44709 * 1. Use the `data-vivus-ignore` attribute if set
44710 * 2. Check if the instance must ignore invisible paths
44711 * 3. Check if the path is visible
44712 *
44713 * For now the visibility checking is unstable.
44714 * It will be used for a beta phase.
44715 *
44716 * Other improvments are planned. Like detecting
44717 * is the path got a stroke or a valid opacity.
44718 */
44719Vivus.prototype.isInvisible = function (el) {
44720  var rect,
44721    ignoreAttr = el.getAttribute('data-ignore');
44722
44723  if (ignoreAttr !== null) {
44724    return ignoreAttr !== 'false';
44725  }
44726
44727  if (this.ignoreInvisible) {
44728    rect = el.getBoundingClientRect();
44729    return !rect.width && !rect.height;
44730  }
44731  else {
44732    return false;
44733  }
44734};
44735
44736/**
44737 * Parse attributes of a DOM element to
44738 * get an object of {attributeName => attributeValue}
44739 *
44740 * @param  {object} element DOM element to parse
44741 * @return {object}         Object of attributes
44742 */
44743Vivus.prototype.parseAttr = function (element) {
44744  var attr, output = {};
44745  if (element && element.attributes) {
44746    for (var i = 0; i < element.attributes.length; i++) {
44747      attr = element.attributes[i];
44748      output[attr.name] = attr.value;
44749    }
44750  }
44751  return output;
44752};
44753
44754/**
44755 * Reply if an element is in the page viewport
44756 *
44757 * @param  {object} el Element to observe
44758 * @param  {number} h  Percentage of height
44759 * @return {boolean}
44760 */
44761Vivus.prototype.isInViewport = function (el, h) {
44762  var scrolled   = this.scrollY(),
44763    viewed       = scrolled + this.getViewportH(),
44764    elBCR        = el.getBoundingClientRect(),
44765    elHeight     = elBCR.height,
44766    elTop        = scrolled + elBCR.top,
44767    elBottom     = elTop + elHeight;
44768
44769  // if 0, the element is considered in the viewport as soon as it enters.
44770  // if 1, the element is considered in the viewport only when it's fully inside
44771  // value in percentage (1 >= h >= 0)
44772  h = h || 0;
44773
44774  return (elTop + elHeight * h) <= viewed && (elBottom) >= scrolled;
44775};
44776
44777
44778/**
44779 * Get the viewport height in pixels
44780 *
44781 * @return {integer} Viewport height
44782 */
44783Vivus.prototype.getViewportH = function () {
44784  var client = this.docElem.clientHeight,
44785    inner = window.innerHeight;
44786
44787  if (client < inner) {
44788    return inner;
44789  }
44790  else {
44791    return client;
44792  }
44793};
44794
44795/**
44796 * Get the page Y offset
44797 *
44798 * @return {integer} Page Y offset
44799 */
44800Vivus.prototype.scrollY = function () {
44801  return window.pageYOffset || this.docElem.scrollTop;
44802};
44803
44804setupEnv = function () {
44805
44806  if (Vivus.prototype.docElem) {
44807    return;
44808  }
44809
44810  /**
44811   * Alias for document element
44812   *
44813   * @type {DOMelement}
44814   */
44815  Vivus.prototype.docElem = window.document.documentElement;
44816
44817  /**
44818   * Alias for `requestAnimationFrame` or
44819   * `setTimeout` function for deprecated browsers.
44820   *
44821   */
44822  requestAnimFrame = (function () {
44823    return (
44824      window.requestAnimationFrame       ||
44825      window.webkitRequestAnimationFrame ||
44826      window.mozRequestAnimationFrame    ||
44827      window.oRequestAnimationFrame      ||
44828      window.msRequestAnimationFrame     ||
44829      function(/* function */ callback){
44830        return window.setTimeout(callback, 1000 / 60);
44831      }
44832    );
44833  })();
44834
44835  /**
44836   * Alias for `cancelAnimationFrame` or
44837   * `cancelTimeout` function for deprecated browsers.
44838   *
44839   */
44840  cancelAnimFrame = (function () {
44841    return (
44842      window.cancelAnimationFrame       ||
44843      window.webkitCancelAnimationFrame ||
44844      window.mozCancelAnimationFrame    ||
44845      window.oCancelAnimationFrame      ||
44846      window.msCancelAnimationFrame     ||
44847      function(id){
44848        return window.clearTimeout(id);
44849      }
44850    );
44851  })();
44852};
44853
44854/**
44855 * Parse string to integer.
44856 * If the number is not positive or null
44857 * the method will return the default value
44858 * or 0 if undefined
44859 *
44860 * @param {string} value String to parse
44861 * @param {*}
44861 defaultValue Value to return if the result parsed is invalid
44862 * @return {number}
44863 *
44864 */
44865parsePositiveInt = function (value, defaultValue) {
44866  var output = parseInt(value, 10);
44867  return (output >= 0) ? output : defaultValue;
44868};
44869
44870
44871  if (typeof define === 'function' && define.amd) {
44872    // AMD. Register as an anonymous module.
44873    define([], function() {
44874      return Vivus;
44875    });
44876  } else if (typeof exports === 'object') {
44877    // Node. Does not work with strict CommonJS, but
44878    // only CommonJS-like environments that support module.exports,
44879    // like Node.
44880    module.exports = Vivus;
44881  } else {
44882    // Browser globals
44883    window.Vivus = Vivus;
44884  }
44885
44886}());
44887
44888//Noise.js
44889!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)}
44889var 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.